STM32 - 用户自定义通讯协议

一.自定义协议

帧头1:0x5A
帧头1:0xA5
命令类型:
0x01 ADC 读取电压
0x02 外部flash写入
0x03 外部flash 读取
0x04 内部flash 写入
0x05 内部flash 读取
0x06 EEPROM 写入
0x07 EEPROM 读取
数据长度 :三位数据(接收数据不固定的情况下)
帧尾:0x16

在这里插入图片描述
在这里插入图片描述

帧头1帧头2数据类型数据长度地址数据块校验
校验和 or 异或校验 or CRC校验

1.数据包较为复杂,先接收到数据缓存区中,在主程序处理。

uint8_t Rx_buf[MAX_REv_NUM];               //接收缓存区地址

void uart_service (uint_8 *buf)
{
 unsigned char recv_index;
 if(Rx_buf[recv_index+0] == 0x68);                      //判断第一个是不是帧头
 {
  if(Rx_buf[recv_index+1] == 0x68);   
 }
}

2.另一种在串口中断里,边接收边处理。接收一帧,判断是否为帧头,如果不是直接退出。

/*****************************/
//利用switch 做状态机,在中断内实现
unsigned char state = 0;                   //设置状态位
uint8_t Rx_buf[MAX_REv_NUM];               //接收缓存区地址
unsigned int Rw_buf;                       //写入和读取的数据

switch(state)
{
    case 0:
        Rx_buf[0] = SBUF;
        if(Rx_buf[0] == 0x68)
        {
            state = 1;
            cnt = 2;
        }
        else
        {
            state = 0;
        }
        break;
    case 1 :
        Rx_buf[cnt] = SBUF;          //cnt 定时器计次
        cnt++;
        if(cnt > 4)                 //代表三帧数据接收完成
        {
            state = 2;
        }
        else
            {
              state = 1;
            }
            break;
     case 2 :
         Rx_buf[cnt] = SBUF; 
         if(Rx_buf[cnt] == 0x16)                  //已接收到帧尾
         {
             switch(Rx_buf[2])
             {
                 case 1:                             //取buf内容赋值给 函数内容
                     Rw_buf = Rx_buf[3];   
                     break;
                 case 2:
                     break;
                 default:
                     break;
                  }
         }
         break;  
         default:
         break;
}

最后利用串口发送函数将 Rx_buf[ ] 发送出去

例如:
ADC 读取电压 : 68 01
外部flash:帧头1 5A 帧头2 A5 命令 02 长度 地址 数据 帧尾16
外部flash :

/*****************************/

uint8_t recv_data                           //串口接收数据保存
void USART1_IRQHandler(void)
{
static unsigned int flag = 1;      
static unsigned int flag = 0;              //只要求第一次为0,每次竟然不在初始化为0,所以用static 。
unsigned char state = 0;                   //设置状态位
uint8_t Rx_buf[MAX_REv_NUM];               //接收缓存区地址
unsigned char ch;                    
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)
{
    if( ch == 0x68)
    {
        Rx_buf[0] =ch;
        state = 1;
     }
     if(ch != 0x68 && flag ==1)
     {
        Rx_buf[i++] = ch;
        if(i == 5)
        {
        flag = 0;
        i=1;
        if(arr[i] + arr[2]) ==arr[3]) && arr[4] ==0x16);
         switch(arr[1])
         {
         case 0x01if(arr[2] == 0x01)
             //实现0x01 功能
         case 0x02}
        }
  

主机——>下位机正常接收,需要返回一段指令

正确:0x5A A5 80 00 校验值
和校验错误:0x5A A5 81 00 校验值

  • 5
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值