OpenEdv-开源电子网

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

串口中断接收如何判断数组接收完毕呢?

[复制链接]

64

主题

227

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2011-7-23
在线时间
13 小时
发表于 2012-12-10 16:26:28 | 显示全部楼层 |阅读模式
串口中断接收如何判断数组接收完毕呢?开发板上的例程是是判断最后2个字节是0x0A,0x0D, 而我接收到得数据最后2位就是实际的数值。0x00 ,0x23, 或者0x00 ,0x37 这样不确定的数值,怎么判断数组接收结束了?是最后一个接收到的是'\0' 吗?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

64

主题

227

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2011-7-23
在线时间
13 小时
 楼主| 发表于 2012-12-10 16:32:29 | 显示全部楼层
怎样判断串口接收一组数据完毕? 
由于每次接收的数据长度不一样,少的就3个8位数据,多的时候有十多个,这个数据个数是不定的,且没规律的数据,有什么好的方法让它接收完整?第一次弄RS485接收的,弄了半天,烦

两种方法:协议法和超时法。
协议法指通讯双方约定数据包中某一特定位置的数据代表数据包长度,或者利用特殊字符作为结束标志。
超时法指数据停止发送若干时间后即认为当前数据包已完成接收。

我用的是加头加尾的方法,即是所说的协议法,收到最后那个数据就是说明这段数据收完
回复 支持 反对

使用道具 举报

64

主题

227

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2011-7-23
在线时间
13 小时
 楼主| 发表于 2012-12-10 16:33:42 | 显示全部楼层
有没有大侠告诉我,我用串口类接收了一个仪器传输过来的数据。但是数据没有结束标志。我把数据接收过来放在一个LISTBox里显示出来了,当数据传输完成后我想给一个提示框“MessageBox("数据接收完毕");”,但是我不知道怎么在程序里判断接收结束了,然后给提示框。
我发现我真是很白,都有些无地自容了。
回复 支持 反对

使用道具 举报

64

主题

227

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2011-7-23
在线时间
13 小时
 楼主| 发表于 2012-12-10 16:35:25 | 显示全部楼层
串口的收发是建立连接后就可以不停得发送和监听接收的数据的,接收到的数据字段长度为0就表示目前没有数据发送过来,就是上一次数据已经发送完了。

最好的方法还是自己在发送数据的时候在结尾加个结束标致,这样,读的时候就可以判断数据是否接收完整还是丢失了。

你可以判断最后数据接收之后的一个时间长短来判定上一个指令是否发送完成,
不过这样也算不上准确,
最好是双方有协商一致的指令才可能准确判断是不是发送完毕,
比如有结束标志,或者知道某个指令的固定长度等。
回复 支持 反对

使用道具 举报

64

主题

227

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2011-7-23
在线时间
13 小时
 楼主| 发表于 2012-12-10 16:38:55 | 显示全部楼层
通常在定义数据结构的时候在每个数据包前加入当前数据包的字节长度,或者定义一个结束符,两种方式都可以。如果数据包由专有硬件设备返回,那就必须清楚它返回的指令或数据含义,通常有技术资料可查的。
回复 支持 反对

使用道具 举报

25

主题

683

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1351
金钱
1351
注册时间
2012-4-25
在线时间
195 小时
发表于 2012-12-10 17:12:30 | 显示全部楼层
我的方法,开个定时器分 2次 去扫描 判断 当前数据有没变化;
1-1
回复 支持 反对

使用道具 举报

21

主题

125

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
361
金钱
361
注册时间
2012-3-11
在线时间
51 小时
发表于 2012-12-10 20:12:58 | 显示全部楼层
超时法比较简单。设一个变量fg,中断接收到数据,就置位fg=1;开一个一毫秒定时器,若fg>0,则fg++;
应用程序中判断if(fg>3)(3至5毫秒),就认为接收结束
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-12-10 22:12:16 | 显示全部楼层
如果不是频繁数据传送的话,可以采用定时器,判断数据间隔来实现,比如9600的波特率,如果是连续发送,2个字符间的间隔就不会超过2ms,那么你检查到超过2ms没有收到一个字符,就可以认为此次接收完成了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2014-5-30
在线时间
0 小时
发表于 2014-5-31 20:21:30 | 显示全部楼层
回复【7楼】hkys_lxh:
---------------------------------
请问 你有关于超时法这个详细的程序吗?可否借鉴下?
回复 支持 反对

使用道具 举报

21

主题

125

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
361
金钱
361
注册时间
2012-3-11
在线时间
51 小时
发表于 2014-6-4 20:57:23 | 显示全部楼层
把思路搞清楚再下手,学着自己练练回复【9楼】skyboy_23:
---------------------------------
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2015-4-29
在线时间
3 小时
发表于 2017-1-4 09:21:04 | 显示全部楼层
我现在也遇到你这个问题,不知是否可以指点一下
回复 支持 反对

使用道具 举报

15

主题

406

帖子

0

精华

高级会员

Rank: 4

积分
795
金钱
795
注册时间
2015-3-26
在线时间
151 小时
发表于 2017-1-4 09:23:20 | 显示全部楼层
超时结束
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2015-4-29
在线时间
3 小时
发表于 2017-1-4 09:28:33 | 显示全部楼层
你手里有代码吗?我学习一下,,,再次感谢;不方便的话,也没关系
回复 支持 反对

使用道具 举报

21

主题

387

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1043
金钱
1043
注册时间
2016-9-8
在线时间
213 小时
发表于 2017-1-4 09:47:35 | 显示全部楼层
用判断吗??.........
shop60994719.taobao.com
回复 支持 反对

使用道具 举报

8yte 该用户已被删除
发表于 2017-1-4 09:52:45 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

21

主题

387

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1043
金钱
1043
注册时间
2016-9-8
在线时间
213 小时
发表于 2017-1-4 09:58:26 | 显示全部楼层
定义两个变量,如RXF,TXF;接收时RXF++,数据处理时TXF++;当RXF==TXF,就没数据要处理了......这就是环形队列处理的精髓。
再不会写,就看它,https://item.taobao.com/item.htm ... amp;id=537439006677
shop60994719.taobao.com
回复 支持 反对

使用道具 举报

29

主题

492

帖子

0

精华

高级会员

Rank: 4

积分
811
金钱
811
注册时间
2016-4-7
在线时间
123 小时
发表于 2017-1-4 11:47:26 | 显示全部楼层
好像原子的蓝牙模块程序里用到了超时法吧,记不清了
回复 支持 反对

使用道具 举报

2

主题

15

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2016-12-23
在线时间
7 小时
发表于 2017-1-12 16:29:48 | 显示全部楼层
超时法有程序可以共享一下吗?原子哥
回复 支持 反对

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2016-5-20
在线时间
12 小时
发表于 2017-1-12 22:35:21 | 显示全部楼层
可以参考下mosbus协议,判断一帧数据完成就是超时3.5个字符,
需要使用的资源 :定时器1个,串口接收中断,一个接收数组unsigned char【】,1个数组索引unsigned char
步骤
1,初始化定时器,计算溢出时间,modbus是3.5个字符间隔9600大概3.5ms,可以根据自己的需求,
2,初始化USART,打开接收中断
3,在USART接收中断中 接收数据保存在接收缓冲区中, ReadBuffer[Index]=USART_ReceiveData(USART1);
然后Inedx++,启动定时器,TIM的Count置0(TIM重新开始)
4,在定时器中断函数中处理信息,当定时器中断时,表示已经3.5个字符的时间没收到数据了,可以认为接收完成了,最后Index索引置0,准备接收下一帧数据。
参考代码
void USART1_IRQHandler()
{
        if(USART_GetITStatus(USART1,USART_IT_RXNE))
        {
                USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                ReadBuffer[Index]=USART_ReceiveData(USART1);
                Index++;
                TIM_SetCounter(TIM2,0);
                TIM_Cmd(TIM2,ENABLE);       
        }

}

void TIM2_IRQHandler()
{
        if(TIM_GetITStatus(TIM2,TIM_IT_Update))
        {
               
                TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
                TIM_Cmd(TIM2,DISABLE);       
                Index=0;       
               处理ReadBuffer接收到的数据
        }
}
回复 支持 反对

使用道具 举报

21

主题

299

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1857
金钱
1857
注册时间
2013-7-29
在线时间
282 小时
发表于 2017-1-13 08:23:42 | 显示全部楼层
,很详细!
回复 支持 反对

使用道具 举报

20

主题

108

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
375
金钱
375
注册时间
2016-9-26
在线时间
59 小时
发表于 2017-5-17 10:47:31 | 显示全部楼层
顶一个
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-8-21 04:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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