STM32串口中斷接收一個完整的數(shù)據(jù)幀
(1)大端發(fā)送;
(2)上位機發(fā)送一幀數(shù)據(jù)的時間間隔不能大于主循環(huán)周期;
(3)數(shù)據(jù)幀滿足下面格式:
幀頭部(Head) | 類型(Type) | 長度(Length) | 值(Value) | CRC校驗 |
2字節(jié) | 1字節(jié) | 1字節(jié) | X字節(jié) | 2字節(jié) |
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{//這里可以根據(jù)類型的范圍進行如上的處理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; //通知主循環(huán)處理}}}}int main(void){int i;//代碼段1while(1)//該循環(huán)不能太慢,否則數(shù)據(jù)緩沖區(qū)會被部分修改{//代碼段2if(COM6_RecvFin == 1){COM6_RecvFin = 0;CMD_Analysis();//分析接收到的這幀數(shù)據(jù)}//代碼段3}return 0;}//在以后再仔細分析數(shù)據(jù)接收較快而處理較慢的問題吧,本課題主要討論的是如何完整的接收一個數(shù)據(jù)幀,在數(shù)據(jù)源正確的情況下不丟幀
評論