串口中断接收数据处理

[复制链接]
5314|16
 楼主| xvezhe 发表于 2014-2-26 08:48 | 显示全部楼层 |阅读模式
本帖最后由 xvezhe 于 2014-2-26 09:29 编辑

//串口中断
void timer1(void) interrupt 4
{        
         uchar ch;
         if(RI)
         {                 
                         ch = SBUF;                                            //接收串口数据
                        ES = 0;
                        if(State_machine==0)
                        {                                                
                                        if(ch==0x55)           State_machine=1;          //数据帧头
                                        else                 State_machine=0;
                        }
                        else if(State_machine==1)
                        {               
                                        if(ch==0xaa)           State_machine=2;  //数据帧头
                                        else                 State_machine=0;
                        }                                                               
                        else if(State_machine==2)
                        {                        
                                dat_bug [ i ] = ch;                                   //存储串口数据
                                num=dat_bug[0];         
                                i++;                                
                                if(i>=2*num+2)                 
                                {
                                        i=0;State_machine=0;
                                        read_flag=1;      //取数标志位
                                }                                       
                                                                                                                        
                    }
                    RI = 0;
                    ES = 1;
         }
}


以上的代码。若一次接收失败,则后面的接收时, read_flag就不会置1;
也就是说,接收的数据 i  不满足i>=2*num+2,  i 就不会 清0.。。。
串口接收不定长数据,怎样在其收到的数据错误的情况下,恢复接收缓冲区
相对以上代码,若接收失败,不会影响到下一次接收。。。。应如何更改,请各位指点



















原野之狼 发表于 2014-2-26 09:00 | 显示全部楼层
中断中收数据放入缓冲,在中断外再判断处理。
ayb_ice 发表于 2014-2-26 09:08 | 显示全部楼层
LS的方法是正道
 楼主| xvezhe 发表于 2014-2-26 09:14 | 显示全部楼层
本帖最后由 xvezhe 于 2014-2-26 09:18 编辑
ayb_ice 发表于 2014-2-26 09:08
LS的方法是正道

因程序中,有几种运行模式,比如说:A中运行中断数据处理,B运行其他的模式处理;程序现在正在B模式,只有当串口接收数据成功,才切回A模式运行
所以,在串口中断中判断,若本次接收不成功,应不影响下次接收
ayb_ice 发表于 2014-2-26 09:31 | 显示全部楼层
xvezhe 发表于 2014-2-26 09:14
因程序中,有几种运行模式,比如说:A中运行中断数据处理,B运行其他的模式处理;程序现在正在B模式,只有 ...

啥这模式,那模式的,主循环应该就是不停的循环,A-B-C...>A...
 楼主| xvezhe 发表于 2014-2-26 09:36 | 显示全部楼层
ayb_ice 发表于 2014-2-26 09:31
啥这模式,那模式的,主循环应该就是不停的循环,A-B-C...>A...

有标志位才能进的、、、
ayb_ice 发表于 2014-2-26 09:52 | 显示全部楼层
xvezhe 发表于 2014-2-26 09:36
有标志位才能进的、、、

不都说了吗,改变算法吗

只要接收的数据不丢失,其它的都好办
原野之狼 发表于 2014-2-26 10:29 | 显示全部楼层
单核下,虽说只能同时做一件事,但是做完一件事还可以做另外一件事嘛,表现在:
A、简单点的,协作式任务调度。
B、复杂点的,抢占式OS机制。
52414133 发表于 2014-2-26 10:55 | 显示全部楼层
设置个标志位判断
很忙 发表于 2014-2-26 12:02 | 显示全部楼层
本帖最后由 很忙 于 2014-2-26 13:29 编辑

这样做没有什么大的问题,一般处理简单的协议是可以这样做的,我就经常这样玩。但是你写的这个判断头出问题了。
真的会出现你遇到的情况。建议这样写。
//串口中断
uchar buff=0,buff1=0;
void timer1(void) interrupt 4
{        
         uchar ch;
         if(RI)
         {               
                        RI = 0;
                        ch = SBUF;                                            //接收串口数据
                        ES = 0;
                        buff1=buff;
                        buff=ch;
                        if((buff1==0x55)&&(buff==0xaa))
                        {
                         State_machine=1;
                        }
                        if(State_machine==1)
                       {
                       dat_bug [0] =ch;
                       num=dat_bug[0];   
                       i=1;
                      State_machine=2;
                       }
                        else if(State_machine==2)
                           {                        
                           dat_bug [ i ] = ch;                                   //存储串口数据                 
                           i++;                                
                           if(i>=2*num+2)                 
                           {
                            i=0;
                            State_machine=0;
                            read_flag=1;      //取数标志位
                           }                                                                                                                                                               
                       }
                                
         }
}
这样比你的要稳健很多。
当然在你的主函数中,要判断数据的合理性。
科技猎人 发表于 2014-2-26 12:49 | 显示全部楼层
可以采用“超时断句”接收数据包,其天生就有出错后能自动恢复的功能,不会影响后面数据包得接收。具体方法看我的另一篇帖子吧(包括各楼的回复中有许多高手们的深入见解)
https://bbs.21ic.com/icview-674102-1-1.html
飞辉会i 发表于 2014-2-26 15:59 | 显示全部楼层
对,在中断外判断 处理
aouwen 发表于 2017-4-22 11:12 | 显示全部楼层
很忙 发表于 2014-2-26 12:02
这样做没有什么大的问题,一般处理简单的协议是可以这样做的,我就经常这样玩。但是你写的这个判断头出问题 ...

你好,我的usart数据接收,有时候会出问题,就是当主控发送数据过来的时候,一次发送两条,我是接收不了的,因为接收缓冲区是全局变量,第一条接收就没处理完第二条中断又来了
ningling_21 发表于 2017-4-22 12:37 | 显示全部楼层
aouwen 发表于 2017-4-22 11:12
你好,我的usart数据接收,有时候会出问题,就是当主控发送数据过来的时候,一次发送两条,我是接收不了 ...

缓冲区怎么能用全局变量,太乱来了
aouwen 发表于 2017-4-26 17:29 | 显示全部楼层
ningling_21 发表于 2017-4-22 12:37
缓冲区怎么能用全局变量,太乱来了

那用临时变量如何传到main函数中处理?
lnulibin 发表于 2017-4-26 21:58 | 显示全部楼层
原野之狼 发表于 2014-2-26 09:00
中断中收数据放入缓冲,在中断外再判断处理。

原野之狼说的是j正道.
lnulibin 发表于 2017-4-26 22:05 | 显示全部楼层
原野之狼 发表于 2014-2-26 10:29
单核下,虽说只能同时做一件事,但是做完一件事还可以做另外一件事嘛,表现在:
A、简单点的,协作式任务调 ...

嗯.就是.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

225

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部