• 仿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
  • 相关阅读:
    【嵌入式linux开发】智能家居入门6:最新ONENET,物联网开放平台(QT、微信小程序、MQTT协议、ONENET云平台、旭日x3派)
    Vue插值操作
    [ES6]模块
    【proverif】proverif的语法-解决中间人攻击-代码详解
    Linux进程概念
    2023.11.22使用flask做一个简单的图片浏览器
    VMware vSphere 虚拟交换机绑定和故障切换策略
    【网络】详解HTTPS及探究加密过程
    数据安全前沿技术研究数据安全
    外汇天眼:店大欺客!capital.com能盈利竟全靠封锁账户鲸吞资产?
  • 原文地址:https://blog.csdn.net/analog4535/article/details/125997859