• 仿Modbus消息帧进行通信


    Modbus消息帧格式

    起始符设备地址功能代码数据校验结束符
    一个字符2个字符1个字符n个字符2个字符1个字符
    • 起始符:表示一帧的开始

    • 设备地址:用于指定需要进行信息传递的设备

    • 功能代码: 用于指定需要完成的操作

    • 数据: 表示需要传输的数据

    • 校验: 用于通信中的错误校验

    • 结束符: 表示一帧数据的结束

    自定义的帧格式设定

    帧头设备码功能码帧尾
    0xaa一个字符(8bit)一个字符(8bit)0X55
    • 帧头: 0xaa 表示一帧数据的开始
    • 设备码: 0x01表示指示灯
    • 功能码: 0x00表示关闭指示灯,0x01表示开启指示灯
    • 帧尾:0x55表示一帧数据的结束
    uint8_t RxBuffer[4];   //接受缓冲区
    uint8_t RxFlag = 0;    //接受完成标志: 为0表示接受未完成,为1表示接受完成
    uint8_t ErrFlag = 0;   //指令错误标志: 为0表示指令正确,为1表示指令错误
    
    HAL_UART_Receive_IT(&huart2, (uint8_t*)RxBuffer, 4);   //使能接受中断
    
    
    while(1)   //帧解析代码
    {
      if(RxFlag == 1)       //判断数据是否接受完成
      {
        RxFlag = 0;        // 清除标志位
        
        if(RxBuffer[0] == 0xaa && RxBuffer[3] == 0x55)  //判断帧头帧尾
        {
            if(RxBuffer[1] == 0x01)    //判断设备码
            {
                if(RxBuffer[2] == 0x00)   //判断功能码
                {
                    //用户操作
                    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
                    printf("LD2 is close!\r\n");
                }
                else if(RxBuffer[2] == 0x01)    //判断功能码
                {
                    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
                    printf("LED2 is open!\r\n");
                }
                else                      //功能码错误
                {
                    ErrFlag = 1;           //置位错误标志
                }
            }
            else
            { 
                ErrFlag = 1;        //置位错误标志
            }   
        }
        else
        {
            ErrFlag = 1;        //置位错误标志
        }
        if(ErrFlag == 1)
        {
            printf("Communication Error! Please send again!\r\n");
        }
        // 清除接受缓冲区和错误标志,准备下一次接受  
        ErrFlag     = 0;
        RxBuffer[0] = 0;
        RxBuffer[1] = 0;
        RxBuffer[2] = 0;
        RxBuffer[3] = 0;
      }
    }
    
    //接受中断回调函数
    
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
        if(huart ->Instance == USART2)  //判断发生接受中断的串口
        {
             RxFlag = 1;     //置位接受完成标志
            HAL_UART_Receive_IT(&huart2, (uint8_t*)RxBuffer, LENGTH); //使能串口中断
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
  • 相关阅读:
    市政管理学试题及答案
    Redis从入门到放弃(9):集群模式
    面向对象编程三⼤特性 --封装、继承、多态
    pnpm快速创建 Vue.js 项目(npm类似)
    Spring框架注解大全
    【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固
    C++ struct结构体内存对齐
    计算机网络(自顶向下方法)-应用层
    【前端】js下载url文件
    软件测试/测试开发丨跨平台 api 对接 学习笔记
  • 原文地址:https://blog.csdn.net/analog4535/article/details/125997859