精华内容
下载资源
问答
  • vc串口数据解析

    2018-01-22 16:05:26
    串口数据解析,vc读取串口数据,获取完整数据包并解析出其中数据 抱歉,上传时默认了下载所需积分,之后不能编辑,下载了的可以联系我返还部分积分
  • 本程序vs2013平台用c#开发,包含北斗部分通信应用协议的串口数据解析,其中协议为北斗协议为4.0通用版,大家可放心下载使用。
  • QT串口数据解析

    2021-02-26 10:50:47
    数据解析 /******************************************************************* * 函数功能:接收遥控器传来的数据并进行解析 * 调用:放在定时器中断服务函数中定时接收 * 时间:2020.12.5 *****************...

    数据解析

    /*******************************************************************
     * 函数功能:接收遥控器传来的数据并进行解析
     * 调用:放在定时器中断服务函数中定时接收
     * 时间:2020.12.5
    ********************************************************************/
    void MainWindow::rec_buffer()//接收操纵杆
    {
        buffer = serial->readAll();
        buffer = buffer.toHex();
    
        QString rDate;
        QByteArray fPLatLeverPercent,fPFanLeverPercent,fPMainLeverPercent,fPLonLeverPercent,
                   fPoil1LeverPercent,fPoil2LeverPercent,byteFlyingMode;
        rDate = QString(buffer);
        if(buffer != NULL)
        {
            if(rDate[0] == '0'&&rDate[1] == 'f'&&rDate.length() >= 70)
            {
                //qDebug("%s",qPrintable(rDate));
                rDate.remove(0, 2);
                fPLatLeverPercent = rDate.left(4).toLocal8Bit();
                rDate.remove(0, 4);
                fPFanLeverPercent = rDate.left(4).toLocal8Bit();
                rDate.remove(0, 4);
                fPMainLeverPercent = rDate.left(4).toLocal8Bit();
                rDate.remove(0, 4);
                fPLonLeverPercent = rDate.left(4).toLocal8Bit();
                rDate.remove(0, 4);
                byteFlyingMode = rDate.left(4).toLocal8Bit();
                rDate.remove(0, 4);
                fPoil1LeverPercent = rDate.left(4).toLocal8Bit();
                rDate.remove(0, 4);
                fPoil2LeverPercent = rDate.left(4).toLocal8Bit();
                rDate.remove(0, 4);
    
                gl_intPLatLeverPercent = (int16_t)fPLatLeverPercent.toInt(nullptr, 16);
                gl_intPFanLeverPercent = (int16_t)fPFanLeverPercent.toInt(nullptr, 16);
                gl_intPMainLeverPercent = (uint16_t)fPMainLeverPercent.toInt(nullptr, 16);
                gl_intPLonLeverPercent = (int16_t)fPLonLeverPercent.toInt(nullptr, 16);
                gl_intPOil1LeverPercent = (uint16_t)fPoil1LeverPercent.toInt(nullptr, 16);
                gl_intPOil2LeverPercent = (uint16_t)fPoil2LeverPercent.toInt(nullptr, 16);
    
            }
        }
        buffer.clear();
    }
    
    展开全文
  • linux C串口数据解析

    2020-08-31 17:06:01
    @解析串口数据 串口初始化及配置 下面展示一些 串口相关初始化。 /相关初始化/ pthread_t pSerial; static const char *device = "/dev/ttyS1"; static int uartFd = 0; int speed_arr[] = { B921600, B460800, B...

    @解析串口数据

    串口初始化及配置

    下面展示一些 串口相关初始化
    /相关初始化/

    pthread_t pSerial;
    static const char *device = "/dev/ttyS1";
    static int uartFd = 0;
    int speed_arr[] = {
        B921600, B460800, B230400, B115200, B57600, B38400, B19200,
        B9600, B4800, B2400, B1200, B300,
    };
    int name_arr[] = {
        921600, 460800, 230400, 115200, 57600, 38400,  19200,
        9600,  4800,  2400,  1200,  300,
    };
    

    /设置串口速度/

    void set_speed(int fd, int speed)
    {
        int   i;
        int   status;
        struct termios   Opt;
        tcgetattr(fd, &Opt);
    
        for ( i= 0;  i < (int)(sizeof(speed_arr) / sizeof(int));  i++) {
            if  (speed == name_arr[i])	{
                tcflush(fd, TCIOFLUSH);
                cfsetispeed(&Opt, speed_arr[i]);
                cfsetospeed(&Opt, speed_arr[i]);
                status = tcsetattr(fd, TCSANOW, &Opt);
                if  (status != 0)
                    perror("tcsetattr fd1");
                return;
            }
            tcflush(fd,TCIOFLUSH);
        }
    
        if (i == 12){
            printf("\tSorry, please set the correct baud rate!\n\n");
        }
    }
    

    /串口相关设置,停止位,校验位…/

    int set_Parity(int fd,int databits,int stopbits,int parity)
    {
        struct termios options;
        if  ( tcgetattr( fd,&options)  !=  0) {
            perror("SetupSerial 1");
            return(FALSE);
        }
        options.c_cflag &= ~CSIZE ;
        switch (databits) /*脡猫脰脙脢媒戮脻脦禄脢媒*/ {
        case 7:
            options.c_cflag |= CS7;
            break;
        case 8:
            options.c_cflag |= CS8;
            break;
        default:
            fprintf(stderr,"Unsupported data size\n");
            return (FALSE);
        }
    
        switch (parity) {
        case 'n':
        case 'N':
            options.c_cflag &= ~PARENB;   /* Clear parity enable */
            options.c_iflag &= ~INPCK;     /* Enable parity checking */
            break;
        case 'o':
        case 'O':
            options.c_cflag |= (PARODD | PARENB);  /* 脡猫脰脙脦陋脝忙脨搂脩茅*/
            options.c_iflag |= INPCK;             /* Disnable parity checking */
            break;
        case 'e':
        case 'E':
            options.c_cflag |= PARENB;     /* Enable parity */
            options.c_cflag &= ~PARODD;   /* 脳陋禄禄脦陋脜录脨搂脩茅*/
            options.c_iflag |= INPCK;       /* Disnable parity checking */
            break;
        case 'S':
        case 's':  /*as no parity*/
            options.c_cflag &= ~PARENB;
            options.c_cflag &= ~CSTOPB;
            break;
        default:
            fprintf(stderr,"Unsupported parity\n");
            return (FALSE);
        }
        /* 脡猫脰脙脥拢脰鹿脦禄*/
        switch (stopbits) {
        case 1:
            options.c_cflag &= ~CSTOPB;
            break;
        case 2:
            options.c_cflag |= CSTOPB;
            break;
        default:
            fprintf(stderr,"Unsupported stop bits\n");
            return (FALSE);
        }
        /* Set input parity option */
        if (parity != 'n')
            options.c_iflag |= INPCK;
        options.c_cc[VTIME] = 1; // 15 seconds
        options.c_cc[VMIN] = 128;
        options.c_lflag &= ~(ECHO | ICANON);
        options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
        options.c_oflag &= ~OPOST;
        options.c_cflag |= CLOCAL | CREAD;
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    
        tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
        if (tcsetattr(fd,TCSANOW,&options) != 0) {
            perror("SetupSerial 3");
            return (FALSE);
        }
        return (TRUE);
    }
    

    /打开串口/linux下查看串口 /dev/ttyS*

    int OpenDev(const char *Dev)
    {
        int fd = open( Dev, O_RDWR | O_NOCTTY | O_NDELAY);
        if (-1 == fd)
        {
            perror("Can't Open Serial Port");
            return -1;
        } else
            return fd;
    }
    
    *这里就是初始化串口一些信息调用以上的函数* __
    void InitCom(const char *SeriName)
    {
        //    pthread_t pSerial;
        uartFd = OpenDev(SeriName);
        if (uartFd > 0)
        {
            set_speed(uartFd, 19200);
            if (set_Parity(uartFd,8,1,'N')== FALSE)
            {
                fprintf(stderr, "Set Parity Error\n");
                close(uartFd);
                return;
            }
            pthread_create(&pSerial,NULL,ReadComData,NULL);
        }
        else
        {        printf("Open %s Falied!\r\n",device);
            return;
        }
    }
    

    串口数据的解析

    *启动线程接收* __
    void InitCom(const char *SeriName)
    {
        //    pthread_t pSerial;
        uartFd = OpenDev(SeriName);
        if (uartFd > 0)
        {
            set_speed(uartFd, 19200);
            if (set_Parity(uartFd,8,1,'N')== FALSE)
            {
                fprintf(stderr, "Set Parity Error\n");
                close(uartFd);
                return;
            }
            pthread_create(&pSerial,NULL,ReadComData,NULL);/*线程函数在下面*/
        }
        else
        {        printf("Open %s Falied!\r\n",device);
            return;
        }
    }
    

    下面展示一些 接收串口数据解析

    void * ReadComData(void *arg)
    {
        printf("%s is running\r\n",__FUNCTION__);
        (void)arg;
        char buf[128];
        int rtn;
        int index = 0;
        char c;
        while(1)
        {
            rtn = read(uartFd,&c,1);
            if(rtn > 0)
            {
            /*接收到的数据开头为A*/
                if('A' == c)
                {
                    index = 1;
                    buf[0] = c;
                }
                /*以换行结束,也就是在输入如:A123456\r,\r是在串口界面上输入发送信息的时候键盘上的回车*/
                else if('\r' == c)
                {
                    buf[index] = '\0';
                    if('>' == buf[0])
                    {
                        printf("Recv data is:%s\r\n",buf);
                        /**/
                    }
                    index = 0;
                }
                /*没找到继续找*/
                else
                {
                    buf[index] = c;
                    index++;
                    if(index >= 128)
                        index = 0;
                }
            }
        }
        return NULL;
    }
    
    展开全文
  • 通过C语言实现链表功能,可自定义链表的长度,通过NODE_DATA_TYPE_IS_POINTER宏可设置链表节点类型,实现接收缓存表。在串口数据处理中,可将接收和处理异步进行
  • ❝说明:此文章提供了一种基于TencentOS-tiny的串口数据解析思路及实现,「感谢戴大神」最初写的源码,这种思路同样可以实现AT框架、基于串口的GPS数据解析等等。❞1. PM2.5传感器本文使用的是攀藤PMSA003 PM2.5...

    说明:此文章提供了一种基于TencentOS-tiny的串口数据解析思路及实现,「感谢戴大神」最初写的源码,这种思路同样可以实现AT框架、基于串口的GPS数据解析等等。

    1. PM2.5传感器

    本文使用的是攀藤PMSA003 PM2.5传感器。

    f4df33e7d5aa9261b8b262ddfdc0a8c9.pngPMSA003 是一款「基于激光散射原理的数字式通用颗粒物传感器」, 可连续采集并计算单位体积内空气中不同粒径的悬浮颗粒物个数,即颗粒物浓度分布,进而换算成为质量浓度,并以通用数字接口形式输出。本传感器可嵌入各种与空气中悬浮颗粒物浓度相关的仪器仪表或环境改善设备,为其提供及时准确的浓度数据。

    1.1. 测量原理

    本传感器采用激光散射原理。即:

    令激光照射在空气中的悬浮颗粒物上产生散射,同时在某一特定角度收集散射光,得到散射光强度随时间变化的曲线。

    进而微处理器基于米氏(MIE)理论的算法,得出颗粒物的等效粒径及单位体积内不同粒径的颗粒物数量。

    75cbae62b4e1ec420c6609b5aaa8226b.png

    1.2. 技术指标

    75a24ec0fa1b776954d449d67b1a8b7d.png80286bb6d42c88278bc6847b0fca0985.png

    1.3. 引脚定义

    9199cb66d648446c436917e35f22b099.png

    4eef63f46c4fe61ca07063eec42ef952.png75617b8afec2d31e00b868c324416aa6.png

    1. 「PMSA003 需要 5V 供电,这是因为风机需要 5V 驱动。但其他数据通讯和控制管脚均需要 3.3V 作为高电平」。因此与之连接通讯的主板 MCU 应为 3.3V供电。如果主板 MCU 为 5V 供电,则在通讯线(TXD、 RXD)和控制线(SET、 RESET)上应当加入电平转换芯片或电路。
    2. SET 和 RESET 内部有上拉电阻,「如果不使用,则应悬空」
    3. PIN6 和 PIN8 为程序内部调试用,「应用电路中应使其悬空」

    1.4. 输出数据

    主要输出结果为「单位体积内各浓度颗粒物质量以及个数」, 其中颗粒物个数的单位体积为 0.1L,质量浓度单位为:微克/立方米。

    传感器上电后默认状态为主动输出,即「传感器主动向主机发送串行数据,时间间隔为 200~800ms」,空气中颗粒物浓度越高,时间间隔越短。

    传感器还具备被动输出模式,如下:2e90086e96fa0647295ff3cdd0817507.png

    其中指令字节和状态字节如下:56421318bed24417770a412cb6be27d6.png校验字为从特征字节开始所有字节累加和。

    指令得到的应答为32个字节,和主动接收相同。

    2. 使用USB转串口查看输出数据

    2.1. 传感器为主动模式

    直接使用UBS转串口连接传感器的VCC、GND、TXD、RXD,打开串口助手,波特率9600bps/s,即可看到传感器周期性收到的数据:

    2df85cd958c6d6cf3b755ecf91cb370a.png

    每次接收到的数据总长度为「32字节」,每个数据意义如下:c234e227581be23025aed38dd1002800.pngdfdce2eca3699908134ae9845175758d.png

    2.2. 传感器为被动模式

    「进入待机模式的指令」如下:

    42 4D E4 00 00 01 73

    执行之后传感器进入待机模式,风扇停止转动。

    ② 恢复正常模式的指令如下:

    42 4D E4 00 01 01 74

    执行之后传感器恢复正常工作。

    ③ 切换被动读数模式:

    42 4D E1 00 00 01 70

    收到的返回数据为:

    42 400 04 E1 00 01 74

    执行之后传感器依然在正常工作,风扇正常转动,但是不会主动上报数据,需要手动读取。

    ④ 读取一次数据:

    42 4D E2 00 00 01 71

    收到传感器返回的32字节数据:

    42 400 100 02 00 03 00 03 00 02 00 03 00 03 02 10 00 A1 00 17 00 00 00 00 00 00 97 00 02 1

    ⑤ 切换回主动上报模式:

    42 4D E1 00 01 01 71

    3. 使用TencentOS-tiny操作系统解析

    3.1. 解析思路

    串口逐个字节接收,缓存到chr fifo中 --> 解析任务读取缓存的数据进行解析校验 --> 取出其中26字节载荷发到邮箱 --> 邮箱接收有效数据并通过MQTT发送。

    da079927da40648761e8b0a95d71e5e3.png

    3.2. 数据结构抽象

    在上图所示的数据流中,整块的数据有3个:① 整个解析器所需要的任务控制块、信号量控制块、chr_fifo控制块可以封装为1个:

    /* PM2.5 数据解析器控制块 */
    typedef struct pm2d5_parser_control_st {
        k_task_t     parser_task;       //解析器任务控制块
        
        k_sem_t      parser_rx_sem;     //表示解析器从串口接收到数据
        k_chr_fifo_t parser_rx_fifo;    //存放解析器接收到的数
    pm2d5_parser_ctrl_t;

    其中任务相关的大小配置、chr_fifo缓冲区的大小配置,可以用宏定义表示,方便修改:

    /* pm2d5 parser config */
    #define PM2D5_PARSER_TASK_STACK_SIZE    512
    #define PM2D5_PARSER_TASK_PRIO          5
    #define PM2D5_PARSER_BUFFER_SIZE        64

    ② 解析器从缓冲区读取出的传感器原始数据,可以封装为一个结构体,union是为了后续实现结构体无差异遍历:

    /**
     * @brief   解析出的PM2D5数据值
     * @note    可以作为邮件发送给其他任务进行进一步处理
     */

    typedef struct pm2d5_data_st {
        uint16_t    data1;
        uint16_t    data2;
        uint16_t    data3;
        uint16_t    data4;
        uint16_t    data5;
        uint16_t    data6;
        uint16_t    data7;
        uint16_t    data8;
        uint16_t    data9;
        uint16_t    data10;
        uint16_t    data11;
        uint16_t    data12;
        uint16_t    data13;
    }pm2d5_data_t;

    typedef union pm2d5_data_un {
        uint16_t data[13];
        pm2d5_data_t pm2d5_data;
    } pm2d5_data_u;

    ③ 解析器从原始数据中解析出的数据,需要使用邮箱发送,也可以封装为一个结构体:

    /**
     * @brief   解析出的PM2D5数据值
     * @note    可以作为邮件发送给其他任务进行进一步处理
     */

    typedef struct pm2d5_data_st {
        uint16_t    data1;
        uint16_t    data2;
        uint16_t    data3;
        uint16_t    data4;
        uint16_t    data5;
        uint16_t    data6;
        uint16_t    data7;
        uint16_t    data8;
        uint16_t    data9;
        uint16_t    data10;
        uint16_t    data11;
        uint16_t    data12;
        uint16_t    data13;
    }pm2d5_data_t;

    typedef union pm2d5_data_un {
        uint16_t data[13];
        pm2d5_data_t pm2d5_data;
    } pm2d5_data_u;

    3.3. 逐个字节送入缓冲区

    /**
     * @brief   向PM2D5解析器中送入一个字节数据
     * @param   data  送入的数据
     * @retval  none
     * @note    需要用户在串口中断函数中手动调用
    */

    void pm2d5_parser_input_byte(uint8_t data){
        if (tos_chr_fifo_push(&pm2d5_parser_ctrl.parser_rx_fifo, data) == K_ERR_NONE) {
            /* 送入数据成功,释放信号量,计数 */
            tos_sem_post(&pm2d5_parser_ctrl.parser_rx_sem);
        }
    }

    只需要在串口中断处理函数中每次接收一个字节,然后调用此函数送入缓冲区即可。

    3.4. 解析任务实现

    解析任务负责等待信号量,从缓冲区中不停的读取数据进行校验、解析。

    首先是从缓冲区中等待读取一个字节的函数:

    /**
     * @brief   PM2D5解析器从chr fifo中取出一个字节数据
     * @param   none
     * @retval  正常返回读取数据,错误返回-1
    */

    static int pm2d5_parser_getchar(void){
        uint8_t chr;
        k_err_t err;
        
        /* 永久等待信号量,信号量为空表示chr fifo中无数据 */
        if (tos_sem_pend(&pm2d5_parser_ctrl.parser_rx_sem, TOS_TIME_FOREVER) != K_ERR_NONE) {
            return -1;
        }
        
        /* 从chr fifo中取出数据 */
        err = tos_chr_fifo_pop(&pm2d5_parser_ctrl.parser_rx_fifo, &chr);

        return err == K_ERR_NONE ? chr : -1;
    }

    基于此函数可以编写出在解析到包头和帧数据长度后,从缓冲区中提取整个数据的函数:

    /**
     * @brief   PM2D5读取传感器原始数据并解析
     * @param   void
     * @retval  解析成功返回0,解析失败返回-1
    */

    static int pm2d5_parser_read_raw_data(pm2d5_raw_data_u *pm2d5_raw_data, pm2d5_data_u *pm2d5_data){
        int i;
        uint8_t  len_h,len_l;
        uint16_t len;
        uint16_t check_sum;
        uint16_t check_sum_cal = 0x42 + 0x4d;
       
        /* 读取并计算帧长度 */
        len_h = pm2d5_parser_getchar();
        len_l = pm2d5_parser_getchar();
        len = (len_h <8) | len_l;
        
        if ( len != 0x001C) {
            //非传感器值数据,清空缓存
            for (i = 0; i             pm2d5_parser_getchar();
            }
            return -1;
        }
        
        /* 读取传感器原始数据 */
        for (i = 0; i         pm2d5_raw_data->data[i] = pm2d5_parser_getchar();
        }
        
        /* 和校验 */
        //通过数据计算和校验
        check_sum_cal = check_sum_cal + len_h + len_l;
        for (i = 0; i -2; i++) {
            check_sum_cal += pm2d5_raw_data->data[i];
        }
        //协议中给出的和校验值
        check_sum = (pm2d5_raw_data->pm2d5_raw_data.chk_sum_h <8) + pm2d5_raw_data->pm2d5_raw_data.chk_sum_l;
        if (check_sum_cal != check_sum) {
            return -1;
        }
        
        /* 存储传感器值 */
        for (i = 0; i sizeof(pm2d5_data_t); i++) {
            pm2d5_data->data[i] = pm2d5_raw_data->data[i];
        }
        
        return 0;
    }

    接着创建一个任务task,循环读取缓冲区中数据,如果读到包头,则调用整个原始数据读取函数,一次性全部读出,并进行校验得到有效值,得到有效值之后通过邮箱队列发送:

    /**
     * @brief   PM2D5解析器任务
    */

    static void pm2d5_parser_task_entry(void *arg){
        int chr, last_chr = 0;
        
        while (1) {
           
            chr = pm2d5_parser_getchar();
            if (chr 0) {
                printf("parser task get char fail!\r\n");
                continue;
            }
            
            if (chr == 0x4d && last_chr == 0x42) {
                /* 解析到包头 */
                if (0 ==  pm2d5_parser_read_raw_data(&pm2d5_raw_data, &pm2d5_data)) {
                    /* 正常解析之后通过邮箱发送 */
                    tos_mail_q_post(&mail_q, &pm2d5_data, sizeof(pm2d5_data_t));
                }
            }
            
            last_chr = chr;
        }
    }

    最后编写创建解析器所需要的任务、信号量、chr_fifo的函数,「此函数由外部用户调用」

    /**
     * @brief   初始化PM2D5解析器
     * @param   none
     * @retval  全部创建成功返回0,任何一个创建失败则返回-1
    */

    int pm2d5_parser_init(void){
        k_err_t ret;
        
        memset((pm2d5_parser_ctrl_t*)&pm2d5_parser_ctrl, 0sizeof(pm2d5_parser_ctrl));
        
        /* 创建 chr fifo */
        ret = tos_chr_fifo_create(&pm2d5_parser_ctrl.parser_rx_fifo, pm2d5_parser_buffer, sizeof(pm2d5_parser_buffer));
        if (ret != K_ERR_NONE) {
            printf("pm2d5 parser chr fifo create fail, ret = %d\r\n", ret);
            return -1;
        }
        
        /* 创建信号量 */
        ret = tos_sem_create(&pm2d5_parser_ctrl.parser_rx_sem, 0);
        if (ret != K_ERR_NONE) {
            printf("pm2d5 parser_rx_sem create fail, ret = %d\r\n", ret);
            return -1;
        }
        
        /* 创建线程 */
        ret = tos_task_create(&pm2d5_parser_ctrl.parser_task, "pm2d5_parser_task"
                              pm2d5_parser_task_entry, NULL, PM2D5_PARSER_TASK_PRIO,
                              pm2d5_parser_task_stack,PM2D5_PARSER_TASK_STACK_SIZE,0);
        if (ret != K_ERR_NONE) {
            printf("pm2d5 parser task create fail, ret = %d\r\n", ret);
            return -1;
        }

        return 0;
    }

    3.5. MQTT使用邮件接收并发布到云服务器

    mqtt task之前的一堆初始化代码省略,只要while(1)中的业务逻辑就够了:

     while (1)
        {
            //通过接收邮件来读取数据
            HAL_NVIC_EnableIRQ(USART3_4_IRQn);
            tos_mail_q_pend(&mail_q, (uint8_t*)&pm2d5_value, &mail_size, TOS_TIME_FOREVER);
            HAL_NVIC_DisableIRQ(USART3_4_IRQn);
            
            //收到之后打印信息
            printf("\r\n\r\n\r\n");
            for (i = 0; i 13; i++) {
                printf("data[%d]:%d ug/m3\r\n", i+1, pm2d5_value.data[i]);
            }
            
            //数据上云
            memset(payload, 0256);
            snprintf(payload,  sizeof(payload), "{\\\"method\\\":\\\"report\\\"\\,\\\"clientToken\\\":\\\"clientToken-145023f5-bc9b-4174-ba3b-430ba5956e5c\\\"\\,\\\"params\\\":{\\\"Pm2d5Value\\\":%d}}", pm2d5_value.pm2d5_data.data2);
            printf("message publish: %s\n", payload);
            
      if (tos_tf_module_mqtt_pub(pub_topic_name, QOS0, payload) != 0) {
       printf("module mqtt pub fail\n");
       //break;
      } else {
       printf("module mqtt pub success\n");
      }
            
            //每隔5s收取一次邮件并向云端发布
            tos_sleep_ms(5000);
     }

    ① 因为PM2.5传感器的数据每隔800ms就主动向串口发送一次,所以在串口初始化完毕之后关闭该串口的中断,不然单片机一直跑去解析数据了。

    ② 在需要数据的时候,先将该串口中断打开,然后阻塞等待邮件;

    ③ 串口中断使能之后,解析器完成解析后会发送邮件,唤醒之前等待该邮件的任务;

    ④ 数据上报之后,继续将串口中断关闭,避免浪费CPU。

    「接收更多精彩文章及资源推送,欢迎订阅我的微信公众号:『mculover666』。」09012cbd57b0cf37703cfd3b4fa2f038.png

    展开全文
  • 1.串口数据解析函数 unsigned char DataAnalysis(char *buf) { unsigned char i,Result; char *NEXT=NULL; for(i=0;i;i++) { NEXT=StrCmp(buf,(char*)InstructionList[i].CMD); if(NEXT!=NULL) { usart


    1.串口数据解析函数
    unsigned char DataAnalysis(char *buf)
    {
    unsigned char i,Result;
    char *NEXT=NULL;
    for(i=0;i<CMDMax;i++)
    {
    NEXT=StrCmp(buf,(char*)InstructionList[i].CMD);
    if(NEXT!=NULL)
    {
    usartfuncp=InstructionList[i].cmd_operate;
    Result=(*usartfuncp)(NEXT);
    }
    }
    return Result;
    }

    2.定义数据结构
    typedef struct 
    {
    char CMD[CMDLen];
    unsigned char (*cmd_operate)(char *data);

    }Usart_Tab;


    3.指令、函数映射表
    static const Usart_Tab InstructionList[CMDMax]=
    {
    {"PWON",PowOn},
    {"PWOFF",PowOff},
    {"HDCP",HdcpOnOff},
    {"/V",QueryKaVersion},
    {"EDIDUpgrade",UpdataEDID},
    {"Psave",Psave},
    {"Precall",Precall},
    {"Pclear",Pclear},
    };

    展开全文
  • 串口数据解析总结

    2018-03-27 19:21:00
    在linux下编写串口通讯程序,采用select监听串口的可读事件,一旦可读,调用read。但是我们会发现,read一次得到的数据通常不是完整的一个数据帧。 比如完整数据帧为 但是实际上需要read多次才能完全读到。 ...
  • 串口数据解析

    千次阅读 2018-11-28 11:06:32
    串口数据 展示, Availability: Caption:Prolific USB-to-Serial Comm Port (COM8) ClassGuid:{4d36e978-e325-11ce-bfc1-08002be10318} CompatibleID:System.String[] ConfigManagerErrorCode:0 ...
  • 使用Modbus协议,解析串口接收数据并显示,整个项目使用C#开发
  • 人体红外感应,UCOSSIII+STm32F0.程序可用
  • 串口数据解析问题

    2018-08-20 16:05:47
    我要怎么解析数据呢 找了点网上的代码 我要怎么根据协议来改合适呢,没有包尾 public class ByteQueue { private List<byte> m_buffer = new List<byte>(); public bool Find() { if (m...
  • 串口数据解析出错问题分析

    千次阅读 2010-03-10 10:03:00
    1. 目的 项目开发过程中遇到的串口数据解析出错问题分析并提出解决方案2. 问题现象描述主控下发的开关波形数据下面驱动板有时候能解析正确,有时候解析不正确,而且主控下发某些数据时候就都能解析正确,下发其它...
  • 吉林空管空管监视数据解析软件 随着民用航空事业快速发展,雷达和ADS-B设备大量建设。监视数据源数量大量增加,数据源到管制中心的传输线路又多采用冗余的方式,每一个传输节点都可能造成通信质量下降和数据信息丢失...
  • 串口数据解析通用方法

    千次阅读 2017-09-18 08:23:53
    #region 解析方法2  // Listening = true;////设置标记,说明我已经开始处理数据,一会儿要使用系统UI的。  isReceive = true;  //将数据添加到缓存区  buffer.AddRange(receiveByte);  
  • 点击上方蓝字关注我哦~最近笔者要要实现win10下的一个串口工具,要想多少年前开发的串口工具还是vc++6.0下开发的,把之前vc++6.0的工程转换到VS2015下,报出各种问题,这些问题就不呈现给大家看了,总之都是心酸泪...
  • C# 串口数据解析问题

    2015-05-14 17:42:48
    [img=https://img-bbs.csdn.net/upload/201505/14/1431596474_424423.png][/img]接收到的数据[img=https://img-bbs.csdn.net/upload/201505/14/1431596523_456420.png][/img] 结果[img=...[/img] 如何解析出来
  • 海南现代myDAQ数据采集卡基础 ejsnb5p海南现代myDAQ数据采集卡基础 它还提供各种卓越性能及调试功能,且价格实惠。但二者的区别在于:编程语言是用文本语言编程,而用图形语言(即各种图标、图形符、连线等)编程。...
  • 数据可用USB或串口监听工具监听到数据。 现需要将监听到的数据解析,以便自己定义一份通讯协议。 目前已解析数据头、数据大小字节等相关数据。 之后毫无头绪。 无法向硬件设备中写入数据,硬件设备存储了...
  • 串口收到 16进制的字符串 [b]0A 01 02 03 04 05 06 [/b] 我需要一个uint temp的类型来存放,看了些资料是用移位的方式。 temp = 00001010(0A); temp << 8; temp += 00000001(01); ... 请问这种方式对吗...
  • 本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的 USART 外设,接收 GPS 模块的数据解析。1. 准备工作硬件准备开发板首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi):GPS模块(L80-R)...
  • 物联网产品框架:传统设备使用通信模组连接云服务器(即上云)做数据收发。本文将使用EC20 封装好的AT指令通过 MQTT 协议连接阿里云,简单的介绍下移远4G通信模块 EC20 是如何连接服务器进行数据收发1 关于EC20模块 1.1...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,483
精华内容 593
关键字:

串口数据解析