英文:
Modify the example named UART_HyperTerminal_IT to enable UART reception interrupts on STM32F4?
问题
我正在开发一个使用STM32F4的项目,需要启用UART6接收中断。我已经使用STM32CubeMX启用了UART6,并在STM32CubeMX中启用了NVIC USART6全局中断。
示例 UART_HyperTerminal_IT
我已经按照STM32Cube_FW_F4_V1.27.0
包中安装的示例UART_HyperTerminal_IT
进行操作。这段代码更新一些,但与此示例代码并没有太大不同。
我想要修改示例以将接收到的UART6的每个字符发送回同一个UART6(回显)。因此,我已经删除了示例中发送数据并等待UART数据的所有代码。
我通过以下代码初始化了UART6:
UartHandle.Instance = USART6;
UartHandle.Init.BaudRate = 115200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if(HAL_UART_Init(&UartHandle) != HAL_OK) {
/* 初始化错误 */
Error_Handler();
}
上述代码与示例代码非常相似(我只更改了波特率和奇偶校验)。
我的中断例程
我在文件stm32f4xx_it.c
中定义了USART6_IRQHandler
函数,如下所示:
void USART6_IRQHandler(void) {
unsigned char ch;
uint32_t isrflags = READ_REG(huart6.Instance->SR);
uint32_t cr1its = READ_REG(huart6.Instance->CR1);
if (((isrflags & USART_CR1_RXNEIE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)){
huart6.Instance->SR;
ch = huart6.Instance->DR;
HAL_UART_Transmit(&huart6, &ch, 1, 1000);
}
HAL_UART_IRQHandler(&huart6);
}
在示例的readme文件中,我找到了以下句子:
此示例展示了如何通过中断确保UART数据缓冲区的传输和接收。
这句话说示例中已启用中断,但如果我尝试向UART6发送数据,中断例程USART6_IRQHandler()
并不会被调用。
我认为UART6接收中断没有被启用,但如何启用它呢?是否有某个寄存器中的特定位必须设置?
谢谢。
英文:
I'm developing a project with STM32F4 and I need to enable the UART6 receive interrupt. I have used STM32CubeMX to enable the UART6 and in the STM32CubeMX I have enabled the NVIC USART6 global interrupt.
The example UART_HyperTerminal_IT
I have followed the example UART_HyperTerminal_IT
which is installed by the package STM32Cube_FW_F4_V1.27.0
.
The code is more recent but not so different from this example code.
I would like to modify the example to send back every character received from UART6 on the same UART6 (echo). So I have removed all the code of the example that sends data by the UART and wait data from the UART.
I have initialized the UART6 by the following code:
UartHandle.Instance = USART6;
UartHandle.Init.BaudRate = 115200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if(HAL_UART_Init(&UartHandle) != HAL_OK) {
/* Initialization Error */
Error_Handler();
}
The previous code is very similar to the example code (I have changed only baud rate and the parity).
My interrupt routine
I have defined the function USART6_IRQHandler
in the file stm32f4xx_it.c
as in the code below:
void USART6_IRQHandler(void) {
unsigned char ch;
uint32_t isrflags = READ_REG(huart6.Instance->SR);
uint32_t cr1its = READ_REG(huart6.Instance->CR1);
if (((isrflags & USART_CR1_RXNEIE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)){
huart6.Instance->SR;
ch = huart6.Instance->DR;
HAL_UART_Transmit(&huart6, &ch, 1, 1000);
}
HAL_UART_IRQHandler(&huart6);
}
In the readme file of the example I have found this sentence:
>This example shows how to ensure UART Data buffer transmission and reception with
Interrupt.
The sentence says that in the example the Interrupt is enabled, but if I try to send data to the UART6 the interrupt routine USART6_IRQHandler()
is not called.
I think that the UART6 Receive Interrupt is not enabled, but how can I enable it? Is there a specific bit in some register that must be set?
Thanks
This post on SO speak about this topic but I think is too old for my STM32F4.
This other post is old too.
答案1
得分: 0
感谢 @pmacfarlane 的评论,我解决了在示例 UART_HyperTerminal_IT
中缺少接收中断的问题。
所以我确认,要获得从UART6接收的字符的回显所需的唯一修改是添加指令 huart6.Instance->CR1 |= USART_CR1_RXNEIE;
。
启用接收中断的UART6初始化
因此,UART6的初始化代码如下:
huart6.Instance = USART6;
huart6.Init.BaudRate = 115200;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.Mode = UART_MODE_TX_RX;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
if(HAL_UART_Init(&huart6) != HAL_OK) {
/* 初始化错误 */
Error_Handler();
}
// 启用接收中断
huart6.Instance->CR1 |= USART_CR1_RXNEIE;
注意。 在前面的代码中,我用变量 UART_HandleTypeDef huart6
替代了在 UART_HyperTerminal_IT 示例中使用的变量 UART_HandleTypeDef UartHandle
。
中断例程实现回显
在问题中提到的中断例程的代码保持不变:
void USART6_IRQHandler(void) {
unsigned char ch;
uint32_t isrflags = READ_REG(huart6.Instance->SR);
uint32_t cr1its = READ_REG(huart6.Instance->CR1);
if (((isrflags & USART_CR1_RXNEIE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)){
huart6.Instance->SR;
ch = huart6.Instance->DR;
HAL_UART_Transmit(&huart6, &ch, 1, 1000);
}
HAL_UART_IRQHandler(&huart6);
}
USART6_IRQHandler()
函数检索接收到的字符并立即将其发送回去,实现了每个接收到的字符的回显。
空的 while 循环
这就是全部,while(1)
循环完全为空:
while(1) {
// 空循环
}
英文:
Thanks to @pmacfarlane's comment I solved the problem of the lack of reception interrupts in the example UART_HyperTerminal_IT
.
So I confirm that the only modification needed to obtain the echo of the characters receives from UART6 is the addition of the instruction huart6.Instance->CR1 |= USART_CR1_RXNEIE;
.
Initialization of UART6 with reception interrupts enabled
So the initialization code for the UART6 becomes:
huart6.Instance = USART6;
huart6.Init.BaudRate = 115200;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.Mode = UART_MODE_TX_RX;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
if(HAL_UART_Init(&huart6) != HAL_OK) {
/* Initialization Error */
Error_Handler();
}
// ---> enable reception interruptions
huart6.Instance->CR1 |= USART_CR1_RXNEIE;
Note. In the previous code I have substituted the variable UART_HandleTypeDef UartHandle
used in the UART_HyperTerminal_IT example with the variable:
UART_HandleTypeDef huart6;
Interrupt routine implements echo
The code of the interrupt routine presented in the question remains exactly the same:
void USART6_IRQHandler(void) {
unsigned char ch;
uint32_t isrflags = READ_REG(huart6.Instance->SR);
uint32_t cr1its = READ_REG(huart6.Instance->CR1);
if (((isrflags & USART_CR1_RXNEIE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)){
huart6.Instance->SR;
ch = huart6.Instance->DR;
HAL_UART_Transmit(&huart6, &ch, 1, 1000);
}
HAL_UART_IRQHandler(&huart6);
}
The USART6_IRQHandler()
function retrieves the received char and sends it immediately back implementing the echo of every char received.
While loop empty
That's all, the while(1) loop is completly empty:
while(1) {
// empty loop
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论