Article directory
Introduction to serial port interruption
Introduction of serial port
UART (Universal Asynchronous Receiver/Transmitter) is a universal asynchronous transceiver and transmitter. As one of the asynchronous serial communication protocols, UART works by transmitting each character of data one by one. It is the most frequently used data bus in the process of application development.
UART serial port is characterized by the sequential transmission of data one by one. As long as two transmission lines can achieve two-way communication, one line can send data while another line receives data. UART serial communication has several important parameters, which are baud rate, start bit, data bit, stop bit and parity check bit. For two ports using UART serial communication, these parameters must match, otherwise the communication will not be completed normally. The data format transmitted by UART serial port is as follows:
-
Start bit: indicates the start of data transmission, and the level logic is "0".
-
Data bit: the possible values are 5, 6, 7, 8 and 9, indicating the transmission of these bit data. The general value is 8, because an ASCII character value is 8 bits.
-
Parity bit: used by the receiver to check the received data, and check "1"
The bits of are even (even check) or odd (odd check), so as to verify the correctness of data transmission. This bit is not needed when using. -
Stop bit: indicates the end of a frame of data. The level logic is "1".
-
Baud rate: the rate of serial communication. It is expressed by the number of significant bits of binary code transmitted in unit time. Its unit is bits per second
-
bit/s(bps). The common baud rate values are 4800, 9600, 14400, 38400, 115200, etc. the larger the value is, the faster the data is transmitted, and the baud rate is
-
115200 means 115200 bits per second.
Serial communication process
Introduction to idle interrupt
When there is no data receiving at the serial port, the interrupt of STM32 IDLE will not be generated all the time. The generated condition is as follows: when the IDLE flag bit is cleared, the first data must be received before triggering. When the received data is disconnected and no data is received, the IDLE interrupt will be generated. The IDLE bit is not set high again until the RXNE bit is set (i.e. an IDLE bus is detected again). RXNE can receive interrupt without opening, reducing the number of incoming interrupts.
Code case list
Serial port configuration
/* Config IDLE Interrupt To LPUART1 */ if(uart->UartHandle.Instance == LPUART1) { __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_IDLE); }
Interrupt reception
void LPUART1_IRQHandler(void) { struct stm32_uart *uart; int ch; uart = &lpuart1; /* enter interrupt */ // rt_interrupt_enter(); if((l_serial.parent.open_flag & RT_DEVICE_FLAG_INT_RX)) { HAL_UART_IRQHandler(&uart->UartHandle); ch = -1; ch = uart->UartHandle.Instance->RDR & 0xff; lpuart_recv_buff[recv_len++] = ch; /* When idle interrupt comes */ if(__HAL_UART_GET_FLAG(&uart->UartHandle,UART_FLAG_IDLE)!=RESET) { recv_len--; __HAL_UART_CLEAR_IDLEFLAG(&uart->UartHandle); uart_rx_idle_callback(lpuart_recv_buff,recv_len); // rt_memset(lpuart_recv_buff,0,sizeof(lpuart_recv_buff)); recv_len = 0; } } if(recv_len >= 300) { recv_len = 0; } /* leave interrupt */ //rt_interrupt_leave(); }
Callback function
void uart_rx_idle_callback(uint8_t *pData,int size) { /* If recvive byte > 5, judge valid */ if(size > 5) { debug_uart_recv_data_parse(pData,size); } }
data processing
/* * lpuart Serial interrupt receive callback function * Format: HEAD(1B)+ CMD(1B)+ LEN(2B)+ DATA + CS(1B) */ bool debug_uart_recv_data_parse( uint8_t *pData, uint16_t Size) { debug_uart_package_t debug_frame = {0}; rz_reset_info_t *pobj = rz_reset_info_get(); // printf_debug_log("recv_data_parse",pData,Size); /* Step1: Judge the length of received data*/ debug_frame.recv_buf = pData; if(debug_frame.recv_buf == NULL) { rt_kprintf("recv_buff NULL error \r\n"); return false; } debug_frame.recv_len = Size; if(debug_frame.recv_len > MAX_EFR_LENGTH ) { rt_kprintf("Receive data length error \r\n"); return false; } #if 1 debug_frame.head = debug_frame.recv_buf[0]; debug_frame.check_sum = rz_cs_check_sum_data(debug_frame.recv_buf,debug_frame.recv_len-1); /* Step2: Judge the content of received data */ if(debug_frame.head != EFR_HEAD && debug_frame.check_sum != debug_frame.recv_buf[debug_frame.recv_len] ) { rt_kprintf("recv head error || check sum error\r\n"); return false; } /* Step3:Check Mudule */ if(pobj->init == NULL ){ rt_kprintf(" Module Init failed\r\n"); return false; } #endif recvive_complete_flag = true; g_lpuart_obj.lpuart_recv_len = debug_frame.recv_len; rt_memcpy (g_lpuart_obj.lpuart_recv_buf, debug_frame.recv_buf , debug_frame.recv_len); return true; }