当前位置:网站首页>Serial port data frame

Serial port data frame

2022-07-04 22:39:00 Let everything burn

Mission requirements

 Insert picture description here

Ideas

1 a5 01 b4 It works 01
2 a5 a5/b4 b4 It works a5/b4
3 01 b4 a5 01 Report errors
4 a5 01 02 b4 Report errors
5 Random invalid a5 01 b4 Random invalid It works 01

Valid data is the useful data you need
Frame head The end of the frame is fixed
Invalid data does not conform to the frame header + Valid data + Three byte format at the end of the frame
A byte is decimal 0~255 That's hexadecimal 0x00 To 0xff
A string of data of any length , As long as there are three bytes in it Frame head + One byte of data + Frame tail That is valid data
Data length mismatch , The header or footer of the frame does not match , Are invalid data
Give you some directions , The interrupt service function of the serial port will be called every time the serial port receives a byte , Get one byte per interrupt , But the task requires judging a multi byte data frame , Therefore, it is necessary to save the received data first
Use static variables static Or global variables save data temporarily , Interrupts must be used , If you have spare power to learn, you can use dma
Inquiry serial port reception is meaningless

The main serial port used is usart1 28-33
 Insert picture description here
It uses 30-31
TX Sending port RX Accept port
Query interrupted disable
 Insert picture description here
 Insert picture description here
enable
 Insert picture description here
To accept multiple groups of data, you need to define an array , Then put the data into the array at one time

Now we can only realize the first four situations :

Completion code :

main.c

int main (void){
    // The main program 
delay_ms(500); // Wait for other devices to be ready when powered on 
	RCC_Configuration(); // System clock initialization  
// RELAY_Init();// Relay initialization 

	I2C_Configuration();//I2C initialization 
	OLED0561_Init(); //OLED initialization 
	OLED_DISPLAY_8x16_BUFFER(0," YoungTalk "); // display string 
// OLED_DISPLAY_8x16_BUFFER(3," True "); // display string 

	
	LED_Init();//LED initialization 
	
	USART1_Init(115200); // Serial initialization , Write baud rate in the parameter 
	USART1_RX_STA=0xC000; // The initial value is set to enter , That is, a welcome message is displayed 
	while(1){
    
		if(USART1_RX_STA&0xC000){
     // If the flag bit is 0xC000 Indicates that the received data string is complete , Can handle .
			if((USART1_RX_STA&0x3FFF)==0){
     // A separate enter key displays the welcome message again 
				printf("\033[1;47;33m\r\n"); // Set the color ( Refer to HyperTerminal use )
// printf(" 1y-- open LED1 The lamp  1n-- Turn off LED1 The lamp  \r\n");
// printf(" 2y-- open LED2 The lamp  2n-- Turn off LED2 The lamp  \r\n");
				printf("  Please enter the control command , Press enter to execute ! \033[0m\r\n");
			}else if((USART1_RX_STA&0x3FFF)==6 && USART1_RX_BUF[0]=='5' && USART1_RX_BUF[1]=='a'&&USART1_RX_BUF[4]=='b'&&USART1_RX_BUF[5]=='4'){
     // Judge whether the data is 2 individual , Is the first data “1”, Is the second one “y”
				OLED_DISPLAY_8x16_BUFFER(1," TRUE:");
	
		OLED_DISPLAY_8x16(1,8*8,USART1_RX_BUF[0]);// Display valid data 
		OLED_DISPLAY_8x16(1,9*8,USART1_RX_BUF[1]);//
		OLED_DISPLAY_8x16(1,10*8,USART1_RX_BUF[2]);//
		OLED_DISPLAY_8x16(1,11*8,USART1_RX_BUF[3]);//
		OLED_DISPLAY_8x16(1,12*8,USART1_RX_BUF[4]);//
		OLED_DISPLAY_8x16(1,13*8,USART1_RX_BUF[5]);//
		
				printf(" The order is valid !\r\n");
			

			}else{
     // If none of the above is , That is, the wrong instruction .
			   	OLED_DISPLAY_8x16_BUFFER(1," FALSE: ");
	
				printf(" Command error !\r\n"); 
			}
			USART1_RX_STA=0; // Clear the serial port data flag 0
		}
	}
}

This method only fixes the length of three bytes , Then the first and last frames are processed as the first and last frames , If it does not conform to the data length and the head and tail matching , It's all wrong .
The interrupt function uses the original judgment to enter

In the interrupt, the original judgment returns , Because the super terminal is used in the yangtao video , He doesn't have the send key, so he needs to judge the carriage return , So because other serial port assistants have a send key, they need to send a new line to judge whether there is a carriage return

usart.c

void USART1_IRQHandler(void){
     // A serial port 1 Interrupt service routine ( Fixed function name cannot be modified ) 
	u8 Res;
	// The following is the string received USART_RX_BUF[] The program ,(USART_RX_STA&0x3FFF) It's the length of the data ( Not including return )
	// When (USART_RX_STA&0xC000) When true, it indicates that the data reception is completed , Press enter in the HyperTerminal .
	// Write judgment in the main function if(USART_RX_STA&0xC000), Then read USART_RX_BUF[] Array , Read 0x0d 0x0a That is the end .
	// Note that after the main function processes the serial port data , To put USART_RX_STA clear 0
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){
      // Receive interrupt ( The data received must be 0x0d 0x0a ending ) 
		Res =USART_ReceiveData(USART1);//(USART1->DR); // Read received data 
		printf("%c",Res); // Put the data received in  a Symbolic variables   Send back to the computer  
		if((USART1_RX_STA&0x8000)==0){
    // Reception is not complete  
			if(USART1_RX_STA&0x4000){
    // received 0x0d 
				if(Res!=0x0a)USART1_RX_STA=0;// Receive error , restart 
				else USART1_RX_STA|=0x8000;	// The reception is complete  
			}else{
     // I haven't received 0X0D 
				if(Res==0x0d)USART1_RX_STA|=0x4000;
				else{
    
					USART1_RX_BUF[USART1_RX_STA&0X3FFF]=Res ; // Put the received data into the array 
					USART1_RX_STA++;	// Data length count plus 1
					if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;// Receiving data error , Start receiving again  
				}		 
			}
		}   		 
	} 
} 

Another way :
 Insert picture description here

原网站

版权声明
本文为[Let everything burn]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/185/202207042208243509.html