OpenEdv-开源电子网

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

STM32串口中断接收数据多一字节

[复制链接]

1

主题

2

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2016-5-24
在线时间
5 小时
发表于 2016-5-24 17:31:20 | 显示全部楼层 |阅读模式
3金钱
使用了STM32F1和F4的串口中断,遇到一个问题,请大家帮忙找一下原因。
我的外设给我STM32发一组数据,例如是0xAA,0x01,0x02,0x03,0x04,0x05,0xFF,0xFC,0xFF,0xFF;其中0xAA是帧头,0xFF,0xFC,0xFF,0xFF是帧尾。单片机串口中断读到了0xAA时会开始存放后面的数据。但是一组数据发送完成后,STM32还会进入一次串口中断,并且收到的数据是0xAA。
void USART3_IRQHandler(void)        
{
    uint8_t c;
    if(USART_GetFlagStatus(USART3,USART_FLAG_RXNE)==SET)
    {
        c = USART_ReceiveData(USART3);
        if((GPS_cmd_st == 0) && (GPS_bufIdx == 0) && (c == 0xAA))//判断帧头
        {
            GPS_cmd_st = 1;
        }
        if(GPS_cmd_st)
        {
            GPS_buf[GPS_bufIdx++] = c;
        }
            if( (GPS_buf[GPS_bufIdx-1] == 0xFF) && (GPS_buf[GPS_bufIdx-2] == 0xFF) && (GPS_buf[GPS_bufIdx-3] == 0xFC) )//判断帧尾
            {
                  GPS_cmd_st = 0;
                  GPS_REV_FLAG = 1;//本组数据接收完成
                  GPS_bufIdx = 0;
            }
    }
}

上面中断函数接收数据的处理。
外设发来的数据是:0xAA,0x01,0x02,0x03,0x04,0x05,0xFF,0xFC,0xFF,0xFF
USB转串口模块读到的数据是:0xAA,0x01,0x02,0x03,0x04,0x05,0xFF,0xFC,0xFF,0xFF
单片机接收到的数据是:0xAA,0x01,0x02,0x03,0x04,0x05,0xFF,0xFC,0xFF,0xFF,0xAA
单片机调试模式下在读到0xFF,0xFC,0xFF,0xFF后在中断加入断点,能够发现单片机会进入中断函数,并且读到的数据是0xAA。
请问有没有高手遇到这个问题的,有没有解决方法(除了软件屏蔽最后的0xAA)?


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

使用道具 举报

4

主题

290

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1130
金钱
1130
注册时间
2015-8-4
在线时间
107 小时
发表于 2016-5-24 17:33:41 | 显示全部楼层
你进了串口中断后第一件事居然不是清除中断标志?
活到老,学到老。
回复

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1605
金钱
1605
注册时间
2015-6-10
在线时间
222 小时
发表于 2016-5-25 08:38:18 | 显示全部楼层
kingnike 发表于 2016-5-24 17:33
你进了串口中断后第一件事居然不是清除中断标志?

读取数据硬件自动清除标志位
回复

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1605
金钱
1605
注册时间
2015-6-10
在线时间
222 小时
发表于 2016-5-25 08:48:31 | 显示全部楼层
你说的问题我不知道怎么回事儿,但是我很好奇你的GPS_bufIdx-2  和-3 竟然没有溢出
回复

使用道具 举报

4

主题

290

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1130
金钱
1130
注册时间
2015-8-4
在线时间
107 小时
发表于 2016-5-25 09:23:16 | 显示全部楼层
止天 发表于 2016-5-25 08:38
读取数据硬件自动清除标志位

抱歉之前没注意这个细节。我想了下你这个有两个地方可以修改试下:
1、判断帧头的if语句增加对GPS_REV_FLAG的判断,在该标志为0的情况下再判断是否是帧头,这样可以软件滤掉尾部的0XAA。
2、你的帧尾有点长,而且数据包含多个0XFF,能修改的话尽量修改一下。在判断帧尾的地方需要加入数据长度的判断,不然每次中断都要判断帧尾,明显在接收前2个数据时该判断都会溢出。
3、收完后再次进入中断是没道理的,可以用示波器抓一下数据。然后个人建议把帧头修改为0XAA0X55两个字节联合判断,当然不改也没问题。
活到老,学到老。
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2016-5-24
在线时间
5 小时
 楼主| 发表于 2016-5-25 19:29:53 | 显示全部楼层
GPS_REV_FLAG置一后,处理函数在主程序的死循环里,因此GPS_REV_FLAG会被置0,所以不会用GPS_REV_FLAG在帧头处判断,至于GPS_bufIdx-2  和-3 溢出的问题是我粘贴了程序,删除没用的注释误删了,前面还有个判断if(GPS_bufIdx >= 5)。使用USB转串口模块读取到的数据是正常的,但是单片机中断读取到的数据在最后会多一个0xAA。并且GPS_buf数据每次用了之后会清0。因为多出一个0xAA,所以我程序认为又开始读数据,因此在判断时数据被移了一位,导致程序错误。例如原本判断0xE1为某个功能,从外设发给我的存储的数据在GPS_buf[1]里面,但实际存放位置在GPS_buf[2]里面。由于我判断的是GPS_buf[1],所以单片机没有执行相应功能
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-5-25 20:21:49 | 显示全部楼层
我觉得不应该出这个问题,你用串口助手模拟发送一次数据看看。
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
3
金钱
3
注册时间
2018-9-13
在线时间
0 小时
发表于 2018-9-13 19:40:54 | 显示全部楼层
你看,我最近也遇到了这个问题,不管单片机接收什么收据,即使把中断标志清除了,也还是两次进入接收中断函数。怀疑与接收移位寄存器和接收数据寄存器有关。能给解释下吗
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
3
金钱
3
注册时间
2018-9-13
在线时间
0 小时
发表于 2018-9-13 19:44:27 | 显示全部楼层
正点原子 发表于 2016-5-25 20:21
我觉得不应该出这个问题,你用串口助手模拟发送一次数据看看。

不应该?如果所有程序不应用于实践,的确是,但是,呵呵!!!
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-9-13 20:01:38 | 显示全部楼层
查一下ORE标志位, 应该是OverRun了
回复

使用道具 举报

26

主题

355

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1770
金钱
1770
注册时间
2017-4-1
在线时间
432 小时
发表于 2018-9-14 09:31:41 | 显示全部楼层
这么久的贴了,楼主解决了吗?mark一下期待结果
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-19 17:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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