STM32 idle interrupt - USART? It? Idle (without DMA mode)

Keywords: ascii

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;
}
117 original articles published, 60 praised, 10000 visitors+
Private letter follow

Posted by manwhoeatsrats on Thu, 16 Jan 2020 08:03:20 -0800