代码运行条件:
(1) 大端发送;
(2) 上位机发送一帧数据的时间间隔不能大于主循环周期;spa
(3)数据帧知足下面格式: code
帧头部(Head)ip |
类型(Type)ci |
长度(Length)it |
值(Value)io |
CRC校验table |
2字节class |
1字节循环 |
1字节im |
X字节 |
2字节 |
0xaa 0x55 |
|
X |
|
|
void USART6_Init (void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); //修改 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;//修改 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC,&GPIO_InitStructure);//修改 GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_USART6);//修改 GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_USART6); //修改 NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_Init(USART6,&USART_InitStructure); USART_ITConfig(USART6,USART_IT_RXNE,ENABLE);//打开接收中断 USART_Cmd(USART6,ENABLE); } void USART6_IRQHandler() { unsigned char rCh; static char rCnt = 0; if(USART_GetITStatus(USART6,USART_IT_RXNE) != RESET) { rCh = USART_ReceiveData(USART6); COM6_RecvBuf[rCnt] = rCh; if(rCnt == 0) //帧头0xAA { rCnt = (0xAA != rCh)?0:rCnt+1; } else if(rCnt == 1) //帧头0x55 { rCnt = (0x55 != rCh)?0:rCnt+1; } else if(rCnt == 2) //类型type { //这里能够根据类型的范围进行如上的处理 rCnt++; } else if(rCnt == 3) //长度len { rCnt++; } else if(rCnt > 3) //值value { rCnt++; if(rCnt == 6+COM6_RecvBuf[3]) { rCnt = 0; memcpy(COM6_RecvBufBck,COM6_RecvBuf,RECV_BUF_SZ);//缓冲 COM6_RecvFin = 1; //通知主循环处理 } } } } int main(void) { int i; //代码段1 while(1)//该循环不能太慢,不然数据缓冲区会被部分修改 { //代码段2 if(COM6_RecvFin == 1) { COM6_RecvFin = 0; CMD_Analysis();//分析接收到的这帧数据 } //代码段3 } return 0; } //在之后再仔细分析数据接收较快而处理较慢的问题吧,本课题主要讨论的是如何完整的接收一个数据帧,在数据源正确的状况下不丢帧