完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一.UART中断概述
如figure 302所示,在stm32中UART有多个中断,下面来逐一说明这些中断及其应用。 一.发送中断 1.1TXE:发送数据寄存器为空状态标志位 当TDR寄存器的内容已转移到移位寄存器中时,此位由硬件置1。 如果USART_CR1寄存器中的TXEIE位= 1,则会产生一个中断。 通过写USART_DR寄存器将其清除。 0:数据未传输到移位寄存器 1:数据传输到移位寄存器) 注:在单缓冲区传输期间使用此位。TXE位总是通过写数据寄存器来清除。TXE位由硬件置1,它指示: •数据已从TDR移至移位寄存器,并且数据传输已开始。 •TDR寄存器为空。 •可以将下一个数据写入USART_DR寄存器,而不会覆盖前一个数据。 如果TXEIE位置1,此标志将产生中断。 1.2.TC 传输完成状态标志位 传输完成中断,如果包含数据的帧的传输完成并且TXE被置位,则该位置1。 如果USART_CR1寄存器中的TCIE = 1,则产生一个中断。 通过软件序列(从USART_SR寄存器读取,然后写入USART_DR寄存器)将其清除。 TC位也可以通过向其写入“ 0”来清除。 建议仅对多缓冲区通信使用此清除序列。 0:传输未完成。 1:传输完成。 1.3.CTS <待整理> 1.4.中断发送 通过STM32CubeIDE创建工程后,设置好UART及其它相关的配置后,在UART的中断发送过程中,HAL库的相互调用关系如下:HAL_UART_Transmit_IT ---》 HAL_UART_IRQHandler ---》 UART_Transmit_IT ---》 UART_EndTransmit_IT。 HAL_UART_Transmit_IT : 此函数会将要发送的数据赋值给UART结构体。然后使能UART_IT_TXE中断,进入中断处理函数。 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) { /* *此函数会将要发送的数据赋值给UART结构体。然后使能UART_IT_TXE中断,进入中断处理函数;从发送时序图Fig 282可以看到 *在使能UART_IT_TXE中断后会马上触发一次UART_IT_TXE中断中断。TXE flag在初始状态就是保持在高电平。 * **/ /* Check that a Tx process is not already ongoing */ if (huart->gState == HAL_UART_STATE_READY) { if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(huart); huart->pTxBuffPtr = pData; huart->TxXferSize = Size; huart->TxXferCount = Size; huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_BUSY_TX; /* Process Unlocked */ __HAL_UNLOCK(huart); /* Enable the UART Transmit data register empty Interrupt */ __HAL_UART_ENABLE_IT(huart, UART_IT_TXE); return HAL_OK; } else { return HAL_BUSY; } } HAL_UART_IRQHandler : 进入UART中断入口函数后,会调用中断处理函数HAL_UART_IRQHandler,在中断处理函数HAL_UART_IRQHandler中会根据中断标志位(TC TXE)不同调用不同的函数UART_Transmit_IT 和UART_EndTransmit_IT。其中UART_Transmit_IT在huart->gState == HAL_UART_STATE_BUSY_TX控制下循环将要发送的数据一帧一帧的写入串口的发送数据寄存器,并关闭TXE中断,使能TC中断。UART_EndTransmit_IT会关闭TC中断并调用用户自己的中断处理函数HAL_UART_TxCpltCallback。 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) { uint32_t isrflags = READ_REG(huart->Instance->SR); uint32_t cr1its = READ_REG(huart->Instance->CR1); uint32_t cr3its = READ_REG(huart->Instance->CR3); uint32_t errorflags = 0x00U; uint32_t dmarequest = 0x00U; /* If no error occurs */ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE)); if (errorflags == RESET) { /* UART in mode Receiver -------------------------------------------------*/ if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) { UART_Receive_IT(huart); return; } } /* If some errors occur */ if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET))) { //error flag //此处代码暂时不关注已删除 } /* End if some error occurs */ /* UART in mode Transmitter ------------------------------------------------*/ if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) { //中断发送,每次发生TXE中断,就调用一次UART_Transmit_IT。 UART_Transmit_IT(huart); return; } /* UART in mode Transmitter end --------------------------------------------*/ if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) { //如果是发送TC中断,则调用UART_EndTransmit_IT。 UART_EndTransmit_IT(huart); return; } UART_Transmit_IT : huart->gState == HAL_UART_STATE_BUSY_TX软件定义的传输完成标志变量,如果特定的帧数据发送完成,会触发TC中断再次调用HAL_UART_IRQHandler,并在HAL_UART_IRQHandler中调用TC中断处理函数UART_EndTransmit_IT中复位HAL_UART_STATE_BUSY_TX。 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart) { uint16_t *tmp; /* Check that a Tx process is ongoing */ if (huart->gState == HAL_UART_STATE_BUSY_TX) { if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) { //如果数据位是9位,则需要发送一个16位数 tmp = (uint16_t *) huart->pTxBuffPtr; huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); huart->pTxBuffPtr += 2U; } else { //如果数据位是8位,则只需要发送一个8位数 huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF); } if (--huart->TxXferCount == 0U) { /* Disable the UART Transmit Complete Interrupt */ __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); /* Enable the UART Transmit Complete Interrupt */ __HAL_UART_ENABLE_IT(huart, UART_IT_TC); } return HAL_OK; } else { return HAL_BUSY; } } UART_EndTransmit_IT : 执行到这里标志串口发送完成,在UART_EndTransmit_IT中关闭TC中断,复位HAL_UART_STATE_BUSY_TX,然后调用发送完成的用户中断处理程序HAL_UART_TxCpltCallback。 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart) { /* Disable the UART Transmit Complete Interrupt */ __HAL_UART_DISABLE_IT(huart, UART_IT_TC); /* Tx process is ended, restore huart->gState to Ready */ huart->gState = HAL_UART_STATE_READY; #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) /*Call registered Tx complete callback*/ huart->TxCpltCallback(huart); #else /*Call legacy weak Tx complete callback*/ HAL_UART_TxCpltCallback(huart); #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ return HAL_OK; } 二.接收中断 https://blog.csdn.net/Hola_ya/article/details/81560204?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=5e1deb95-ae63-46d4-8bf3-744ae8dc909d&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control https://blog.csdn.net/qq_29413829/article/details/63262321?utm_medium=distribute.pc_relevant_download.none-task-blog-baidujs-1.nonecase&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-baidujs-1.nonecase 2.1 IDLE:IDLE line detected 当检测到空闲线时,该位置1。 如果USART_CR1寄存器中的IDLEIE = 1,则产生一个中断。 它由软件序列清除(先读取USART_SR寄存器,再读取USART_DR寄存器)。 0:未检测到空闲线 1:检测到空闲线 注意:在RXNE位本身被置位之前(即出现新的空闲线),IDLE位将不会再次置位。 2.2 ORE:Overrun error(溢出错误) 当RXNE = 1时,当移位寄存器中当前接收的字准备好被传送到RDR寄存器中时,该位由硬件置1。 如果USART_CR1寄存器中的RXNEIE = 1,则产生一个中断。 它由软件序列清除(先读取USART_SR寄存器,再读取USART_DR寄存器)。 0:无溢出错误 1:检测到超限错误 注:置位时,RDR寄存器的内容不会丢失,但移位寄存器将被覆盖。 如果EIE位置1,则在进行多缓冲区通信时,在ORE标志上会产生一个中断。 2.3 RXNE : Read data register not empty 当RDR移位寄存器的内容已传输到USART_DR寄存器时,此位由硬件置1。 如果USART_CR1寄存器中的RXNEIE = 1,则产生一个中断。通过读取USART_DR寄存器将其清除。 也可以通过向其写入零来清除RXNE标志。 建议仅对多缓冲区通信使用此清除序列。 0:未收到数据 1:已准备好读取已接收的数据。 2.4 PE :Parity error 当在接收器模式下发生奇偶校验错误时,此位由硬件设置。 它由软件序列清除(先读取状态寄存器,然后读取USART_DR数据寄存器)。 在清除PE位之前,软件必须等待RXNE标志置1。 如果USART_CR1寄存器中的PEIE = 1,则会产生一个中断。 0:无奇偶校验错误 1:奇偶校验错误 2.5 LBD : LIN break detection flag 当检测到LIN中断时,由硬件将该位置1。 通过软件清除(将其写入0)。 如果USART_CR2寄存器中的LBDIE = 1,则会产生一个中断。 0:未检测到LIN Break 1:检测到LIN中断 注意:如果LBDIE = 1,则当LBD = 1时会产生一个中断。 2.6 NE/ORE/FE : NE: Noise error flag 当在接收到的帧上检测到噪声时,该位由硬件设置。 它由软件序列清除(先读取USART_SR寄存器,再读取USART_DR寄存器)。 0:未检测到噪音 1:检测到噪音 注意:如果EIE位置1,则在多缓冲区通信的情况下,NE标志上会生成与本身产生中断中断的RXNE位同时出现的该位,不会产生中断。 ORE: Overrun error 当RXNE = 1时,当移位寄存器中当前接收的字准备好被传送到RDR寄存器中时,该位由硬件置1。 如果USART_CR1寄存器中的RXNEIE = 1,则产生一个中断。 它由软件序列清除(先读取USART_SR寄存器,再读取USART_DR寄存器)。 0:无溢出错误 1:检测到超限错误 注:置位时,RDR寄存器的内容不会丢失,但移位寄存器将被覆盖。 如果EIE位置1,则在进行多缓冲区通信时,在ORE标志上会产生一个中断。 FE: Framing error 当检测到去同步,过多的噪声或中断字符时,该位将由硬件置位。 它由软件序列清除(先读取USART_SR寄存器,再读取USART_DR寄存器)。 0:未检测到构图错误 1:检测到帧错误或中断字符 注:该位不会产生中断,因为它与本身会产生中断的RXNE位同时出现。 如果当前正在传输的字同时引起帧错误和溢出错误,则将传输该字,并且仅将ORE位置1。 如果EIE位置1,则在多缓冲区通信的情况下,FE标志上会产生一个中断。 EIE: Error interrupt enable 如果发生多缓冲器通信(DMAR = 1时),则在发生帧错误,溢出错误或噪声错误(USART_SR寄存器中的FE = 1或ORE = 1或NE = 1)时,需要错误中断允许位来使能中断生成。 USART_CR3寄存器)。 0:禁止中断 1:每当USART_CR3寄存器中的DMAR = 1和USART_SR寄存器中的FE = 1或ORE = 1或NE = 1时,都会产生一个中断。 DMAR :DMA enable receiver 该位由软件置位/复位 1:启用DMA模式进行接收 0:禁用DMA模式进行接收 该位不适用于UART5。 HAL_UART_Receive_IT : Enable the UART Parity Error ,Frame error, noise error, overrun error,UART Data Register not empty Interrupt. HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) { /* Check that a Rx process is not already ongoing */ if (huart->RxState == HAL_UART_STATE_READY) { if ((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(huart); huart->pRxBuffPtr = pData; huart->RxXferSize = Size; huart->RxXferCount = Size; huart->ErrorCode = HAL_UART_ERROR_NONE; huart->RxState = HAL_UART_STATE_BUSY_RX; /* Process Unlocked */ __HAL_UNLOCK(huart); /* Enable the UART Parity Error Interrupt */ __HAL_UART_ENABLE_IT(huart, UART_IT_PE); /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_UART_ENABLE_IT(huart, UART_IT_ERR); /* Enable the UART Data Register not empty Interrupt */ __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE); return HAL_OK; } else { return HAL_BUSY; } } HAL_UART_IRQHandler : void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) { uint32_t isrflags = READ_REG(huart->Instance->SR); uint32_t cr1its = READ_REG(huart->Instance->CR1); uint32_t cr3its = READ_REG(huart->Instance->CR3); uint32_t errorflags = 0x00U; uint32_t dmarequest = 0x00U; /* If no error occurs */ errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE)); if (errorflags == RESET) { /* UART in mode Receiver -------------------------------------------------*/ if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) { UART_Receive_IT(huart); return; } } /* If some errors occur */ /* UART in mode Transmitter ------------------------------------------------*/ /* UART in mode Transmitter end --------------------------------------------*/ } UART_Receive_IT : static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) { uint8_t *pdata8bits; uint16_t *pdata16bits; /* Check that a Rx process is ongoing */ if (huart->RxState == HAL_UART_STATE_BUSY_RX) { if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) { pdata8bits = NULL; pdata16bits = (uint16_t *) huart->pRxBuffPtr; *pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF); huart->pRxBuffPtr += 2U; } else { pdata8bits = (uint8_t *) huart->pRxBuffPtr; pdata16bits = NULL; if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE))) { *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); } else { *pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F); } huart->pRxBuffPtr += 1U; } if (--huart->RxXferCount == 0U) { /* Disable the UART Data Register not empty Interrupt */ __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); /* Disable the UART Parity Error Interrupt */ __HAL_UART_DISABLE_IT(huart, UART_IT_PE); /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); /* Rx process is completed, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) /*Call registered Rx complete callback*/ huart->RxCpltCallback(huart); #else /*Call legacy weak Rx complete callback*/ HAL_UART_RxCpltCallback(huart); #endif /* USE_HAL_UART_REGISTER_CALLBACKS */ return HAL_OK; } return HAL_OK; } else { return HAL_BUSY; } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1097 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1111 浏览 1 评论
549 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
415 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
996 浏览 2 评论
1593浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
262浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
275浏览 3评论
245浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
238浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-16 17:30 , Processed in 0.751825 second(s), Total 47, Slave 41 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191