单片机学习小组
直播中

偶是糕富帅

11年用户 788经验值
私信 关注

STM32串口通信的自定义帧格式是怎样的

STM32串口通信的自定义帧格式是怎样的?

STM32串口通信的超时接收是什么意思?

回帖(1)

云解相

2022-2-18 10:33:15
1 自定义帧格式

1.1 数据帧结构

定义一帧数据的结构

strcut FRAME
{
        u8 head;//帧头
        u8 len;//数据长度
        u8 type;//数据包类型,例如 1代表成绩,2代表身高……
        u8 data[16];//数据包缓冲区
};


1.2 填充数据帧

接下来,假设我要发一个数据包。例如发五个学生的成绩(假设成绩在buf[5]数组里), 那么需要定义一个数据帧变量score,并初始化:

strcut FRAME score;
score.head='#';
score.len=5;
score.type=0x01;
for(i=0;i {
        score.data=buf;
}
1.3 填充数发送缓冲区

然后,把这帧数据放到发送缓冲区:

u8 send_buf[18]={0},index=0,i;
send_buf[index++]=score.head;
send_buf[index++]=score.len;
send_buf[index++]=score.type;
for(i=0;i {
        send_buf[index++]=score.data;
}


1.4 通过串口发送数据

最后,将缓冲区数据发送出去

for(i=0;i {
        while((USART1->SR&0X40)==0);
        USART1->DR = send_buf;
}


2 超时接收

超时接收,就是接收过程可以不对数据进行任何处理。在接收到第一个数据时,就打开定时器开始计时,当定时器溢出后(例如设为10ms, 只要保证数据能传输完即可),认为数据接收结束,才开始处理数据。当然,不用定时器,使用空闲中断也可以,没用过所以这里不写。
2.1 串口中断服务程序

void USART1_IRQHandler(void)                        //´®¿Ú1ÖжϷþÎñ³ÌÐò
{
        u8 Res;       
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
        {
                if(0==over_flag)//未超时或者数据未处理
                {
                        Res =USART_ReceiveData(USART1);       
                    ReceiveBuf[index++]=Res;
                    //当然,还要判断index的值是否过大,这里不做判断
                    if(0==time_flag)
                    {
                                TIM_Cmd(TIM3, ENABLE); //接收到第一个字节,开启定时器
                                time_flag=1;//定时器开启的标志
                        }
                }
        }
}

2.2 定时器中断服务函数:


void TIM3_IRQHandler(void)
{                                                                   
        if(TIM3->SR&0X0001)
        {
                over_flag=1;//超时标志置1                                                                                              
        }                                  
        TIM3->SR&=~(1<<0);   
}


2.3 数据处理

业务程序大致这样:

if(over_flag) //超时,且数据未被处理
{
        {
                //对ReceiveBuf缓冲区的数据进行处理
                //首先要做判断,判断第一个字节是不是‘#’(还有其他检验数据的正确性的方法,
                //本文没涉及),如果数据有误,就丢弃
        }
        TIM_Cmd(TIM3, DISABLE);//关定时器
        time_flag=0;//定时器标志置零
        over_flag=0; //超时标志清零,也表示数据已经被处理
}


大概就是上面写的这样啦,理解不到位还请见谅。临时写的,没有源代码……估计存在不少问题,仅供参考思路。谢谢!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分