OpenEdv-开源电子网

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

STM32F407如何串口接收分包后的蓝牙数据

[复制链接]

2

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2017-12-20
在线时间
60 小时
发表于 2018-7-3 14:49:24 | 显示全部楼层 |阅读模式
10金钱
[mw_shl_code=c,true]//串口接收缓存区        
u8 USART2_RX_BUF[USART2_MAX_RECV_LEN];                                 //接收缓冲,最大USART2_MAX_RECV_LEN个字节.
u16 USART2_RX_STA=0;            
void USART2_IRQHandler(void)
{       
        u8 res;            
        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//接收到数据   接收到以0x0d,0x0a作为结尾的数据
        {         
                USART_ClearITPendingBit(USART2,USART_IT_RXNE);
                res =USART_ReceiveData(USART2);                  //读取一字节的数据
                if((USART2_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据    (1<<15)即0x8000
                {
                        if(USART2_RX_STA<USART2_MAX_RECV_LEN)                //还可以接收数据
                        {
                                TIM_SetCounter(TIM2,0);//计数器清空                                         
                                if(USART2_RX_STA==0)
                                {                                       
                                        TIM_Cmd(TIM2, ENABLE);  //使能定时器2
                                }
                                USART2_RX_BUF[USART2_RX_STA++]=res;                //记录接收到的值        。转存数据
                                if(USART2_RX_BUF[0]==0x71)//UFM通讯协议指令
                                {
                                        if(USART2_RX_BUF[USART2_RX_STA]==0x17||USART2_RX_BUF[USART2_RX_STA]==0x03)
                                        {
                                                USART2_RX_STA|=1<<15;                                        //强制标记接收完成
                                        }
                                }
                                else if(USART2_RX_BUF[0]==0x41)//蓝牙指令
                                {
                                        if(USART2_RX_BUF[USART2_RX_STA-3]==0x30&&USART2_RX_BUF[USART2_RX_STA-2]==0x31&&USART2_RX_BUF[USART2_RX_STA-1]==0x0d&&USART2_RX_BUF[USART2_RX_STA]==0x0a)
                                        {
                                                USART2_RX_STA|=1<<15;                                        //强制标记接收完成
                                        }
                                        else if(USART2_RX_BUF[USART2_RX_STA-3]==0x30&&USART2_RX_BUF[USART2_RX_STA-2]==0x30&&USART2_RX_BUF[USART2_RX_STA-1]==0x0d&&USART2_RX_BUF[USART2_RX_STA]==0x0a)
                                        {
                                                USART2_RX_STA|=1<<15;                                        //强制标记接收完成
                                        }
                                }
                                else
                                {
                                        USART2_RX_STA=0;//丢弃之前的数据,重新开始接收
                                }
                        }
                        else
                        {
                                USART2_RX_STA|=1<<15;                                        //强制标记接收完成
                        }
                }       
        }                                                                                 
} [/mw_shl_code]

现在安卓通过蓝牙给我发数据,数据长度是50个字节,安卓是分包后发送给我的,每包20个字节,我如何把这50个字节接收完整啊?
现在的情况是,能收到50个字节,但是这50个字节的数据,前20个字节的正确,最后10个字节也正确,中间的20个字节数据是把正常数据的最后20个字节填进来了。

最佳答案

查看完整内容[请看2#楼]

我觉得最好不要再接收中断里面做数据处理,对于分包的数据.可以做一个类似循环队列的处理.采用DMA+空闲中断的方式更节省CPU资源,每次进入空闲中断后将接收到的数据全部丢到队列里面,主函数里面只需要不停的解析队列里面的数据就可以了!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2018-7-14
在线时间
3 小时
发表于 2018-7-3 14:49:25 | 显示全部楼层
淡然若梦 发表于 2018-7-14 15:40
低于20个字节的接收都是正常的,所以基本可以排除编码问题。
可能是安卓分包发送有问题或者我这边接收组 ...

我觉得最好不要再接收中断里面做数据处理,对于分包的数据.可以做一个类似循环队列的处理.采用DMA+空闲中断的方式更节省CPU资源,每次进入空闲中断后将接收到的数据全部丢到队列里面,主函数里面只需要不停的解析队列里面的数据就可以了!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2018-7-4 02:15:09 | 显示全部楼层
这个自己多想想吧,很简单的。
回复

使用道具 举报

2

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2017-12-20
在线时间
60 小时
 楼主| 发表于 2018-7-5 11:47:23 | 显示全部楼层
正点原子 发表于 2018-7-4 02:15
这个自己多想想吧,很简单的。

原子哥,我还是没想明白,我每接收一个字节,数组角标就+1,不应该会存在到接收完成后,把我最后10个字节的数据填充到第20-30个字节的位置上啊。
我可能钻进死角了,还望原子哥指点一下。
回复

使用道具 举报

2

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2017-12-20
在线时间
60 小时
 楼主| 发表于 2018-7-9 13:15:14 | 显示全部楼层
大神们都不屑这个问题么?还是木有回答
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2018-7-10 01:59:49 | 显示全部楼层
淡然若梦 发表于 2018-7-5 11:47
原子哥,我还是没想明白,我每接收一个字节,数组角标就+1,不应该会存在到接收完成后,把我最后10个字节 ...

精简代码,测试。
比如你把你安卓发过来的,直接printf输出到电脑,或者直接用你的电脑串口接你的蓝牙模块。
测试下,看看原始数据对不对先
然后剩下的解析数据,实在没什么好说的。
C语言基础问题,不懂就学。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

8

主题

168

帖子

0

精华

高级会员

Rank: 4

积分
557
金钱
557
注册时间
2015-7-4
在线时间
104 小时
发表于 2018-7-10 08:56:06 | 显示全部楼层
需要分包发送吧
回复

使用道具 举报

2

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2017-12-20
在线时间
60 小时
 楼主| 发表于 2018-7-12 09:07:08 | 显示全部楼层
正点原子 发表于 2018-7-10 01:59
精简代码,测试。
比如你把你安卓发过来的,直接printf输出到电脑,或者直接用你的电脑串口接你的蓝牙模 ...

就是使用printf打印出来的,是错的;这么说的话有可能是安卓那边分包发送有问题了?
回复

使用道具 举报

2

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2017-12-20
在线时间
60 小时
 楼主| 发表于 2018-7-12 09:07:52 | 显示全部楼层

安卓端蓝牙自动分包发送的,我这边接收
回复

使用道具 举报

5

主题

38

帖子

0

精华

初级会员

Rank: 2

积分
90
金钱
90
注册时间
2018-4-18
在线时间
24 小时
发表于 2018-7-12 13:53:46 | 显示全部楼层
不是吧, 你看一下安卓后台的数据应该全部发出来了,蓝牙通信最大字节20个,接收时分段接收组包就行
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2018-7-13 01:47:36 | 显示全部楼层
淡然若梦 发表于 2018-7-12 09:07
就是使用printf打印出来的,是错的;这么说的话有可能是安卓那边分包发送有问题了?

如果printf就出问题,那单片机解析,肯定也是不能用的。

注意收手机一般是用UTF-8编码,你估计得找找是不是编码问题。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2017-12-20
在线时间
60 小时
 楼主| 发表于 2018-7-14 15:40:43 | 显示全部楼层
正点原子 发表于 2018-7-13 01:47
如果printf就出问题,那单片机解析,肯定也是不能用的。

注意收手机一般是用UTF-8编码,你估计得找找 ...

低于20个字节的接收都是正常的,所以基本可以排除编码问题。
可能是安卓分包发送有问题或者我这边接收组包有问题吧。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2018-7-15 00:47:30 | 显示全部楼层
淡然若梦 发表于 2018-7-5 11:47
原子哥,我还是没想明白,我每接收一个字节,数组角标就+1,不应该会存在到接收完成后,把我最后10个字节 ...

你得确定你是从第一个开始存起的。如果你一开始就是20了,有什么奇怪?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2017-12-20
在线时间
60 小时
 楼主| 发表于 2018-7-16 11:37:43 | 显示全部楼层
sharn夏 发表于 2018-7-14 18:51
我觉得最好不要再接收中断里面做数据处理,对于分包的数据.可以做一个类似循环队列的处理.采用DMA+空闲中 ...

你说的这种方式我试过。DMA那种效果一样,此外接收中断不做数据处理,只是单纯的将数据存储到数组中,结果仍然一样。
回复

使用道具 举报

2

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2017-12-20
在线时间
60 小时
 楼主| 发表于 2018-7-16 11:40:32 | 显示全部楼层
正点原子 发表于 2018-7-15 00:47
你得确定你是从第一个开始存起的。如果你一开始就是20了,有什么奇怪?

确定,前20和后20都正确,就中间10个错误。因为我每次接收前都是角标清0,然后等到接收完成,将数据转移走后,又清0,为下一次接收作准备。
回复

使用道具 举报

2

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2017-12-20
在线时间
60 小时
 楼主| 发表于 2018-7-16 11:43:00 | 显示全部楼层
正点原子 发表于 2018-7-15 00:47
你得确定你是从第一个开始存起的。如果你一开始就是20了,有什么奇怪?

原子哥,谢了,这个问题暂时先搁置,我修改协议来避开这个问题,等后期有空再来研究这么问题。
回复

使用道具 举报

2

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2017-12-20
在线时间
60 小时
 楼主| 发表于 2018-7-16 11:45:40 | 显示全部楼层
sharn夏 发表于 2018-7-14 18:51
我觉得最好不要再接收中断里面做数据处理,对于分包的数据.可以做一个类似循环队列的处理.采用DMA+空闲中 ...

谢谢啊。DMA+空闲中断是一个可以很好处理多条命令的方式,可以一直缓存命令,然后再一条条的从队列里解析。不过,我这边暂时是接收一个处理一个就行了。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-22 22:15

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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