新手入门
- 积分
- 10
- 金钱
- 10
- 注册时间
- 2016-7-9
- 在线时间
- 0 小时
|
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]
|
-
-
最佳答案
查看完整内容[请看2#楼]
我开始学的时候也在中断里用了printf,我当时是容易出现协议解析失败,因为printf在中断里占用时间比较长,直接导致接收不到下一个字节
|