STM8避坑—串口中断
STM8库函数开发方式中,串口中断的类型有很多,头文件中的定义入下:
typedef enum { UART1_IT_TXE = (uint16_t)0x0277, /*!< Transmit interrupt */ UART1_IT_TC = (uint16_t)0x0266, /*!< Transmission Complete interrupt */ UART1_IT_RXNE = (uint16_t)0x0255, /*!< Receive interrupt */ UART1_IT_IDLE = (uint16_t)0x0244, /*!< IDLE line interrupt */ UART1_IT_OR = (uint16_t)0x0235, /*!< Overrun Error interrupt */ UART1_IT_PE = (uint16_t)0x0100, /*!< Parity Error interrupt */ UART1_IT_LBDF = (uint16_t)0x0346, /**< LIN break detection interrupt */ UART1_IT_RXNE_OR = (uint16_t)0x0205 /*!< Receive/Overrun interrupt */ } UART1_IT_TypeDef;
我们经常使用的串口中断是,接收中断和发送中断,但是从头文件中来看比较模糊。
发送中断到底是用UART1_IT_TXE(TXE的意思是发送寄存器为空),还是用UART1_IT_TC(TC的意思是发送完成),接收中断到底是用UART1_IT_RXNE(RXNE的意思是接收寄存器非空),还是用UART1_IT_RXNE_OR(OR的意思是接收寄存器超载溢出),又要怎么使用呢?
经过实践,总结如下:
发送中断只能使用UART1_IT_TXE,并且与51单片机的方式有很大不同,51单片机中发送中断的工作流程是:1)给SBUF赋值,2)硬件自动发送,3)发送完成进入串口中断,4)在中断中判断中断是发送还是接受,清楚对应标志位;
STM8中对串口进行了初始化之后,
UART1_Init((uint32_t)115200, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE); UART1_Cmd(ENABLE);
在需要发送数据时再对发送中断进行使能,比如在主函数中,
UART1_ITConfig(UART1_IT_TXE,ENABLE);
然后在发送中断服务函数中执行发送函数,最后关闭发送中断,一定要关闭发送中断,不然就会一直反复进入发送中断,退不出来;
/** * @brief UART1 TX Interrupt routine. * @param None * @retval None */ INTERRUPT_HANDLER(UART1_TX_IRQHandler, 17) { /* In order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction. */ UART1_SendData8('A'); UART1_ITConfig(UART1_IT_TXE,DISABLE); }
接收中断只能使用UART1_IT_RXNE_OR,可以在串口初始化之后直接使能,因为只有在接收到数据才会进入中断,这里和51单片机基本一致,
UART1_ITConfig(UART1_IT_RXNE_OR,ENABLE);
接收中断服务中,如果接收数据量比较大的,需要查询超载溢出的对应标志,因为超载溢出也会触发此中断,一旦是溢出,就要软件清除对应的标志位,取出接收到的数据使用UART1_ReceiveData8()函数。