OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5606|回复: 6

stm32F030 定时器+串口中断 接收异常问题

[复制链接]

0

主题

6

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2017-7-24
在线时间
3 小时
发表于 2021-8-5 01:34:42 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 qweasdzxc 于 2021-8-5 01:36 编辑

芯片:STM32F030C8t6 Keil5 库函数版本
测试环境:串口助手 发送指令如5A 01 00 00 A5,第一次没有反应,读到的接收数据长度异常,第二次发送指令,才会有动作,接收指令数据长度正常为5;
              修改指令如5A 01 00 00 00 A5,发送指令长度为5,下一次发送指令,长度才是正常6。
感觉总是在执行上一次的内存中的东西。

代码如下:
串口中断函数:
void USART2_IRQHandler(void)
{
  if(USART_GetITStatus(USART2, USART_IT_RXNE)!=RESET)  //表示接收到数据
  {
                //USART2_SendNByte(TxBuffer,11);
                //先判断是否超时
                if(RXTimout==0) //没有超时,将数据存储到接收数组,并将RXNE清零中断清零
                {
                        Rec_Len=i;
                        USART2_Printf(&i);
                        i=0;
                        Rec_Over_Flag=1;
                }
                else  //如果超时,将数组的数据长度i进行赋值,在清空,接收完成中断标志位置1;
                {
                        USART_RX_BUF[i++]=USART_ReceiveData(USART2);
                }
                RXTimout=10;//定时器重新赋值
        }               
}
定时器中断函数:
void TIM3_IRQHandler(void) //TIME3中断服务函数  需要设定中断优先级  即NVIC配置
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update))//判断是否发生了更新(溢出)中断 表示已经中断进入
    {
                        if(RXTimout>0)//判断是否到指定的延时时间,1ms中断一次,需要进来3次
                        {
                                RXTimout--;
                        }

                }
                TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除溢出中断标志位
}

主函数命令解析:
  while(1)
  {        
                if(Rec_Over_Flag==1)//表示接收完成一组数据
                {
                        Len=Rec_Len;//将接收到的数据长度赋值给新的变量

                        if(Len<USART_REC_LEN)//判断接收的数据长度是否超过了指定的数组大小
                        {
                                if((USART_RX_BUF[0]==0XA5)&&(USART_RX_BUF[Len-1])==0X5A)
                                {
                                        if(USART_RX_BUF[1]==0X01)
                                        {
                                                LED1_ONOFF(Bit_SET);
                                                USART2_SendNByte(Tx3,10);                        
                                        }
                                        else if(USART_RX_BUF[1]==0X02)
                                        {
                                                LED1_ONOFF(Bit_SET);
                                                USART2_SendNByte(Tx4,10);                        
                                        }                                       
                                }
                        }
                        else return 0;
                        Rec_Over_Flag=0;
                }                                       
  }               
麻烦帮忙找找问题,谢谢,附件可编译  



USART2通讯非DMA.zip

12.05 MB, 下载次数: 206

源程序

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

11

主题

2147

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4894
金钱
4894
注册时间
2015-1-10
在线时间
612 小时
发表于 2021-8-5 10:40:14 | 显示全部楼层
正常,你用串口助手看一下接收的HEX就会发现每次上电后MCU就会发一个byte出来
回复

使用道具 举报

0

主题

6

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2017-7-24
在线时间
3 小时
 楼主| 发表于 2021-8-5 13:57:23 | 显示全部楼层
阿侑kevin 发表于 2021-8-5 10:40
正常,你用串口助手看一下接收的HEX就会发现每次上电后MCU就会发一个byte出来

但是,我要去做控制,这肯定是不行的吧,是不是程序哪里有问题
回复

使用道具 举报

11

主题

2147

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4894
金钱
4894
注册时间
2015-1-10
在线时间
612 小时
发表于 2021-8-5 14:12:56 | 显示全部楼层
qweasdzxc 发表于 2021-8-5 13:57
但是,我要去做控制,这肯定是不行的吧,是不是程序哪里有问题

一般串口接收这块会加个接收超时就可以解决这种问题
回复

使用道具 举报

0

主题

6

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2017-7-24
在线时间
3 小时
 楼主| 发表于 2021-8-5 16:58:59 | 显示全部楼层
阿侑kevin 发表于 2021-8-5 14:12
一般串口接收这块会加个接收超时就可以解决这种问题

我现在就是用定时器做了接收超时啊
回复

使用道具 举报

0

主题

6

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2017-7-24
在线时间
3 小时
 楼主| 发表于 2021-8-6 06:24:00 | 显示全部楼层
通过调试,找到问题的原因了,如果使用这种方式,只有等下一帧数据送到串口时,才会再去判断定时器是否超时引起标志位的变化,但已经为时过晚了
if(RXTimout==0) //没有超时,将数据存储到接收数组,并将RXNE清零中断清零
                {
                        Rec_Len=i;
                        USART2_Printf(&i);
                        i=0;
                        Rec_Over_Flag=1;
                }
所以函数还是有BUG的,需要再调整下
回复

使用道具 举报

11

主题

2147

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4894
金钱
4894
注册时间
2015-1-10
在线时间
612 小时
发表于 2021-8-6 09:40:06 | 显示全部楼层
本帖最后由 阿侑kevin 于 2021-8-6 09:43 编辑
qweasdzxc 发表于 2021-8-5 16:58
我现在就是用定时器做了接收超时啊

每次处理数据以后清一下接收缓存,提个建议:程序里面也用了很多功能重复的变量,读起来有点费劲,串口那边用个全局变量就可以了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-26 00:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表