硬汉嵌入式论坛

 找回密码
 立即注册
查看: 592|回复: 5
收起左侧

[技术讨论] STM32F407串口数据连续Ascii码解析实现方法请教(20221204)

[复制链接]

12

主题

22

回帖

58

积分

初级会员

积分
58
发表于 2022-12-4 23:13:12 | 显示全部楼层 |阅读模式
本帖最后由 951319804 于 2022-12-4 23:30 编辑

上位机:STM32F407VET6 下位机:DC电源
目的:上位机读取DC电源的各项参数以及控制。
通讯Log如下:
上位机发送:MON?[CR](4D 4F 4E 3F 0D)
下位机数据转换成字符:00000,00000,50,50,000000,00000,0
下位机返回:30 30 30 30 30 2C 35 30 2C 35 30 2C 30 30 30 30 30 30 2C 30 30 30 30 30 2C 31 0D
问题:返回的是Ascii码,返回数据有负数,整数,小数点,字符N,而且数位置不定,需要将数据转换成MCU可以识别的数据,进行控制。
以下是我写的解析代码,首先是先将每个字符进行对比判断,通过switch 进行分类储存在一个结构体变量(比如:指针里面)再返回调用函数进行控制。
遇到逗号,就认为是一个数完成,记住逗号位置,再进行逗号分隔出,每一个数据。
接下来我就不知道怎么控制了。
代码如下:// UART2 接收数据处理
#if (UART2_EN > 0)
void Uart2_UserProcess(INT8U *p, INT16U len)
{
    INT16U i,j;
          
//        INT16U *TEMP7;
//          INT16U TEMP1,TEMP2,TEMP3,TEMP4,TEMP5,TEMP6;
          
    #if (APP_UART_DEBUG_EN > 0) // 条件编译使能接收数据打印输出
    // 打印数据输出到调试串口(注意: 按16进制数据打印)
    #if (AT_EN > 0)
    if (LibAppVars.Para.ATFlag&AT_UART_FLAG) // 判断AT配置参数是否允许打印输出
    #endif        
    {
        printf("AT+UART2=RX[%d]:", len);
        for(i=0; i<MIN(len-1, DEBUG_MAX_DATA_LEN); i++)
        {
             printf("%02x ", p);               
        }
        printf("%02x\r\n", p);
                        Uart2_Receive_Data_Analysis(p,len);       
    }
    #endif  
                                            
    // 用户在这里处理UART2接收到的数据: 数据指针p, 数据长度len   
    //
    // 记录数据指针及长度
    UserVars.Uart2.p = p;
    UserVars.Uart2.len = len;
    UserVars.WKFlag |= USER_UART2_UPDATE_FLAG;  // 设置UART2收到新数据标志

    #if (APP_UART2_TEST_EN > 0)
    // 测试功能: 将数据在原样发送回去
    // Uart_Write(UART2_ID, p, len);
//    Uart_UserSendData(UART2_ID, p, len, 1, 0);
    #endif
}
#endif
-----------------------------------------------------------------------------------------------
以下是解析函数
void Uart2_Receive_Data_Analysis(INT8U *Uart2_RXD_Buf,INT8U Rx_Length)
{
    INT8U i;
        USER_UART2_AsciiCode_VARS UART2_AsciiCode_Analysis;
        for(i=0;i<Rx_Length;i++)
         {
            UART2_AsciiCode_Analysis=Uart2_AsciiCode__Analysis(Uart2_RXD_Buf,i);
         }  
}

-----------------------------------------------------------------------------------------------------------

USER_UART2_AsciiCode_VARS Uart2_AsciiCode__Analysis(INT8U AsciiCode,INT8U Index)
{
        USER_UART2_AsciiCode_VARS UART2_AsciiCode_Return;
        switch (AsciiCode)
        {
                case '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9':
                                UART2_AsciiCode_Return.Number[Index]=ASCII_to_Hex(AsciiCode);
            break;
                case ',':
                                UART2_AsciiCode_Return.CommaPostion[Index]=ASCII_to_Hex(AsciiCode);
            break;
                case '.':
                                UART2_AsciiCode_Return.Decimal_PointPosition[Index]=ASCII_to_Hex(AsciiCode);
            break;
                case 'N':
                                UART2_AsciiCode_Return.LetterPosition=ASCII_to_Hex(AsciiCode);
            break;
                case '-':
                                UART2_AsciiCode_Return.SymbolPostion[Index]=ASCII_to_Hex(AsciiCode);
            break;
                        case 0x0D:
                                UART2_AsciiCode_Return.EndCodeCheck=ASCII_to_Hex(AsciiCode);
            break;
           default:                                                                                  
                 break;       
        }       
        return UART2_AsciiCode_Return;

-----------------------------------------------------------------------------------------------------------------
INT8U ASCII_to_Hex(INT8U ASCII_Data)
{
  if((ASCII_Data>=0x30)&&(ASCII_Data<=0x39))
    ASCII_Data=ASCII_Data-0x30;
  if((ASCII_Data>=0x41)&&(ASCII_Data<=0x46))
    ASCII_Data=ASCII_Data-0x37;
  return (ASCII_Data);
}

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2022-12-5 01:42:54 | 显示全部楼层
使用atoi和atof转换整数和浮点数不是更方便些
回复

使用道具 举报

12

主题

22

回帖

58

积分

初级会员

积分
58
 楼主| 发表于 2022-12-5 07:42:34 | 显示全部楼层
eric2013 发表于 2022-12-5 01:42
使用atoi和atof转换整数和浮点数不是更方便些

好的,硬汉哥。谢谢。我先测试一下。后面有问题再追问。
回复

使用道具 举报

19

主题

235

回帖

292

积分

高级会员

积分
292
发表于 2022-12-5 08:37:58 | 显示全部楼层
C 库函数 char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。
我看那些写AT指令解析的用的就是这个,不过最好用可重入的版本 strtok_r,不然在多线程环境下多个地方调用会出问题
回复

使用道具 举报

3

主题

338

回帖

347

积分

高级会员

积分
347
发表于 2022-12-5 09:21:33 | 显示全部楼层
这是什么语言的用法?case '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9':
回复

使用道具 举报

19

主题

235

回帖

292

积分

高级会员

积分
292
发表于 2022-12-5 09:33:02 | 显示全部楼层
glory 发表于 2022-12-5 09:21
这是什么语言的用法?case '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9':

很像何不扩散条约里的代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-16 06:49 , Processed in 0.268001 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表