OpenEdv-开源电子网

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

USART串口中断只能接收两字节

[复制链接]

1

主题

2

帖子

0

精华

新手入门

积分
10
金钱
10
注册时间
2016-7-9
在线时间
0 小时
发表于 2016-7-9 13:24:13 | 显示全部楼层 |阅读模式
1金钱
新人请教一个问题,因为要加协议,改了USART1串口中断,发送一串hex,每次只接收前两字节[mw_shl_code=c,true]void USART1_IRQHandler(void)                        //串口1中断服务程序
{               
        u8 Res;        
        static u8 fsm = 0, idx = 0, len = 0;
        static u8 rcv[20];//接受协议

        #if SYSTEM_SUPPORT_OS                 //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
                OSIntEnter();   
        #endif
               
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾即\r\n)
        {
                Res = USART_ReceiveData(USART1);//读取接收到的数据
                switch(fsm)
                {
                        default:
                        case 0://初始空闲状态
                                printf("空闲\r\n");
                                printf("Res:%02x\r\n", Res);
                                if(Res==0x37)        fsm = 1;
                                break;
                        case 1:
                                if(Res==0x4D)        fsm = 2;
                                else                                        fsm = 0;
                                printf("Res:%02x\r\n", Res);
                                break;                        
                        case 2://接受到帧头
                                printf("收到7M\r\n");
                                memset(rcv,0,20);//清零
                                len = 2;                                 //前两帧写帧头了
                                rcv[0]=0x37;                  //"7"
                                rcv[1]=0x4D;                 //"M"
                                if(Res==0x2B)                                
                                {
                                        fsm = 10;//"+"亮灯
                                        printf("收到2B\r\n");
                                }
                                else if(Res==0x2D)        fsm = 20;//"-"灭灯
                                else                                                               
                                {
                                        fsm = 0;
                                        rcv[len++]=Res;         //不是灯控,继续接受数据
                                        printf("没收到2B %02x\r\n", Res);
                                }
                                break;
                        case 10:
                        case 20:
                                if(Res>='1'&&Res<='8')
                                {
                                        idx=fsm+Res-'0';
                                        fsm = 50;
                                }
                                else fsm = 0;
                                rcv[len++]=Res;  //接受灯号
                                break;
                        case 50://校验字节1
                                rcv[len]=Res;
                                fsm = 51;
                                break;
                        case 51://校验字节2
                                rcv[len+1]=Res;
                                fsm = 52;
                                break;
                        case 52://尾帧
                                if(Res==0x0D)
                                {
                                        printf("成功\r\n");
                                }
                                fsm = 0;
                                break;
                }
//                if((USART_RX_STA&0x8000)==0)//接收未完成
//                {
//                        if(USART_RX_STA&0x4000)//接收到了0x0d
//                        {
//                                if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
//                                else USART_RX_STA|=0x8000;        //接收完成了
//                        }
//                        else //还没收到0X0D
//                        {        
//                                if(Res==0x0d)USART_RX_STA|=0x4000;
//                                else
//                                {
//                                        USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
//                                        USART_RX_STA++;
//                                        if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收         
//                                }                 
//                        }
//                }                    
}
#if SYSTEM_SUPPORT_OS         //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
        OSIntExit();                                                                                          
#endif
}
#endif        

[/mw_shl_code]


搜狗截图16年07月09日1319_1.png
搜狗截图16年07月09日1319_2.png

最佳答案

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

我开始学的时候也在中断里用了printf,我当时是容易出现协议解析失败,因为printf在中断里占用时间比较长,直接导致接收不到下一个字节
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

94

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1581
金钱
1581
注册时间
2016-7-2
在线时间
277 小时
发表于 2016-7-9 13:24:14 | 显示全部楼层
我开始学的时候也在中断里用了printf,我当时是容易出现协议解析失败,因为printf在中断里占用时间比较长,直接导致接收不到下一个字节
回复

使用道具 举报

6

主题

94

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1581
金钱
1581
注册时间
2016-7-2
在线时间
277 小时
发表于 2016-7-9 13:40:31 | 显示全部楼层
中断服务函数里面最好别用printf函数
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
10
金钱
10
注册时间
2016-7-9
在线时间
0 小时
 楼主| 发表于 2016-7-9 13:50:36 | 显示全部楼层
迪拜大呲花 发表于 2016-7-9 13:44
我开始学的时候也在中断里用了printf,我当时是容易出现协议解析失败,因为printf在中断里占用时间比较长, ...

之前是没用printf,但还是不行,是不是中断还是太复杂,请问有什么办法吗?还是都读出来再判断
回复

使用道具 举报

6

主题

94

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1581
金钱
1581
注册时间
2016-7-2
在线时间
277 小时
发表于 2016-7-9 14:06:47 | 显示全部楼层
小妖貂 发表于 2016-7-9 13:50
之前是没用printf,但还是不行,是不是中断还是太复杂,请问有什么办法吗?还是都读出来再判断

除了printf的问题别的我也没看出来,再等大神解答吧
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-10 16:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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