数据未存储在接收数据寄存器中,(UART RXNE 标志未设置)
Data Not Being Stored in Receive Data Register, (UART RXNE Flag not setting)
我一直在对stm32l412kb nucleo板进行编程,试图实现基本的UART通信。来自电路板的传输效果很好,但电路板似乎没有接收到任何数据。
对于软件方面,我已经尝试在中断和非中断模式下以几种不同的方式使用标准 HAL 代码。我已经绑定了一个更基本的方法(如下所示)。通过逐行调试,我发现接收数据寄存器 (RDR) 没有填充(因此没有设置有数据时设置的标志)。这就是每种情况下的错误。
此代码的目的是发回输入的字符。
#include "stm32l4xx.h"
int main(void)
{
/* USER CODE BEGIN 1 */
/*The Usart2 peripheral needs its clock to be enabled.*/
RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN;
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
/*The 72 MHz APB1 bus clock with a 9600baud rate gives a baud rate for the register of 0x1D4C*/
USART2->BRR = 0x1D4C;
/*For USART2 we need to enable the overall UART (U) driver, the transmission lines(T) and the reading lines(R). UART Enable is last.*/
USART2->CR1 |= USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;
/*Setting transmission pin*/
GPIOA->MODER |= GPIO_MODE_AF_PP;
GPIOA->OSPEEDR |= GPIO_SPEED_FREQ_HIGH;
/* USER CODE END 1 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (USART2->ISR & USART_ISR_RXNE) //if RX is not empty
{
char temp = USART2->RDR; //fetch the data received
USART2->TDR = temp; //send it back out
while (!(USART2->ISR & USART_ISR_TC)); //wait for TX to be complete
}
}
return 0;
}
为了发送数据,我使用了 RealTerm Serial Capture 并尝试了 stm32cubeIDE 控制台。问题根源的一种可能性是数据表说
"In the USART, the start bit is detected when a specific sequence of samples is recognized. This sequence is: 1 1 1 0 X 0 X 0 X 0 0 0 0."
我没有编写任何方法来引导我的数据,但是,从我从几本书和视频中看到的所有示例来看,他们不需要考虑这个并且它工作得很好。会不会是硬件问题?有什么我没有初始化的吗?我什至尝试过不同的电缆。
非常感谢您的帮助,
哈利
/************************************更新************ *******************************/
首先,非常感谢您的帮助,我现在了解基本知识,例如如何使用数据表配置寄存器。非常感谢。我已经更新了我的代码,但问题仍然存在。
所以我已经更新了我的配置:
/*Configuring GPIO Pins*/
/*Clearing whatever is held in the mode registers for pins 2 and 3 (Inverting with their masks.)*/
GPIOA -> MODER &= ~(GPIO_MODER_MODE2_Msk | GPIO_MODER_MODE3_Msk);
/*The 2 bits 10 are being shifted to the position which configures Mode of pin 2 and also for pin 3 in the mode register.
*(10 is alterntive function mode).*/
GPIOA -> MODER |= (0b10 << GPIO_MODER_MODE2_Pos) | (0b10 << GPIO_MODER_MODE3_Pos);
/*Clearing whatever is held in the output speed registers for pins 2 and 3*/
GPIOA -> OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED2_Msk | GPIO_OSPEEDR_OSPEED3_Msk);
/*Setting the speed of pins 2 and 3 to be very high(11)*/
GPIOA -> OSPEEDR |= (0b11 << GPIO_OSPEEDR_OSPEED2_Pos) | (0b11 << GPIO_OSPEEDR_OSPEED3_Pos);
/*Clearing whatever is held in the alternative function registers for pins 2 and 3.*/
GPIOA -> AFR[0] &= ~(GPIO_AFRL_AFSEL2_Msk | GPIO_AFRL_AFSEL3_Msk);
/*Setting the pins 2 and 3 to their alternative functions(TX and RX)*/
GPIOA -> AFR[0] |= (7 << GPIO_AFRL_AFSEL2_Pos) | (7 << GPIO_AFRL_AFSEL3_Pos);
/*Clock Configuration*/
/*Enabling the USART2 peripheral clock.*/
RCC->APB1ENR1 &= ~(RCC_APB1ENR1_USART2EN_Msk);
RCC->APB1ENR1 |= (0b1 << RCC_APB1ENR1_USART2EN_Pos);
/*Enabling the GPIOA port peripheral clock*/
RCC->AHB2ENR &= ~(RCC_AHB2ENR_GPIOAEN_Msk);
RCC->AHB2ENR |= (0b1 << RCC_AHB2ENR_GPIOAEN_Pos);
/*USART Configuartion*/
/*The 72 MHz APB1 bus clock with a 9600baud rate gives a baud rate for the register of 0x1D4C*/
USART2->BRR = 0x1D4C;
/*For USART2 we need to enable the overall UART (U) driver, the transmission lines(T) and the reading lines(R). UART Enable is last.*/
USART2->CR1 &= ~(USART_CR1_RE_Msk | USART_CR1_TE_Msk | USART_CR1_UE_Msk);
USART2->CR1 |= USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;
这大大加深了我对如何正确配置设备的理解。然而,我仍然对代码反弹一个角色的总体目标有疑问,因为数据仍然没有被 MCU 读取。如果成功,我会继续进行更新。我感谢任何进一步的建议。
- 这不会初始化 GPIO MODER 或 OPEEDR 寄存器。
GPIOA->MODER |= GPIO_MODE_AF_PP;
GPIOA->OSPEEDR |= GPIO_SPEED_FREQ_HIGH;
GPIO_MODE_AF_PP
& GPIO_SPEED_FREQ_HIGH
是 HAL 定义,不能用于寄存器级别。
您需要为您使用的每个引脚设置适当的值:
它永远不会接收或发送任何东西,因为您忘记设置 GPIO -> AF 寄存器并且硬件未在内部连接到引脚。
您可以在数据表中找到备用函数 mappin
以及参考手册中的 AF GPIO 寄存器
这个顺序应该是:
GPIOA -> MODER &= ~(GPIO_MODER_MODE2_Msk | GPIO_MODER_MODE3_Msk);
GPIOA -> MODER |= (0b10 << GPIO_MODER_MODE2_Pos) | (0b10 << GPIO_MODER_MODE3_Pos);
GPIOA -> OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED2_Msk | GPIO_OSPEEDR_OSPEED23Msk);
GPIOA -> OSPEEDR |= (0b11 << GPIO_OSPEEDR_OSPEED2_Pos) | (0b11 << GPIO_OSPEEDR_OSPEED3_Pos);
GPIOA -> AFR[0] &= ~(GPIO_AFRL_AFSEL2_Msk | GPIO_AFRL_AFSEL3_Msk);
GPIOA -> AFR[0] |= (7 << GPIO_AFRL_AFSEL2_Pos) | (7 << GPIO_AFRL_AFSEL3_Pos);
我一直在对stm32l412kb nucleo板进行编程,试图实现基本的UART通信。来自电路板的传输效果很好,但电路板似乎没有接收到任何数据。
对于软件方面,我已经尝试在中断和非中断模式下以几种不同的方式使用标准 HAL 代码。我已经绑定了一个更基本的方法(如下所示)。通过逐行调试,我发现接收数据寄存器 (RDR) 没有填充(因此没有设置有数据时设置的标志)。这就是每种情况下的错误。
此代码的目的是发回输入的字符。
#include "stm32l4xx.h"
int main(void)
{
/* USER CODE BEGIN 1 */
/*The Usart2 peripheral needs its clock to be enabled.*/
RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN;
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
/*The 72 MHz APB1 bus clock with a 9600baud rate gives a baud rate for the register of 0x1D4C*/
USART2->BRR = 0x1D4C;
/*For USART2 we need to enable the overall UART (U) driver, the transmission lines(T) and the reading lines(R). UART Enable is last.*/
USART2->CR1 |= USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;
/*Setting transmission pin*/
GPIOA->MODER |= GPIO_MODE_AF_PP;
GPIOA->OSPEEDR |= GPIO_SPEED_FREQ_HIGH;
/* USER CODE END 1 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (USART2->ISR & USART_ISR_RXNE) //if RX is not empty
{
char temp = USART2->RDR; //fetch the data received
USART2->TDR = temp; //send it back out
while (!(USART2->ISR & USART_ISR_TC)); //wait for TX to be complete
}
}
return 0;
}
为了发送数据,我使用了 RealTerm Serial Capture 并尝试了 stm32cubeIDE 控制台。问题根源的一种可能性是数据表说
"In the USART, the start bit is detected when a specific sequence of samples is recognized. This sequence is: 1 1 1 0 X 0 X 0 X 0 0 0 0."
我没有编写任何方法来引导我的数据,但是,从我从几本书和视频中看到的所有示例来看,他们不需要考虑这个并且它工作得很好。会不会是硬件问题?有什么我没有初始化的吗?我什至尝试过不同的电缆。
非常感谢您的帮助,
哈利
/************************************更新************ *******************************/
首先,非常感谢您的帮助,我现在了解基本知识,例如如何使用数据表配置寄存器。非常感谢。我已经更新了我的代码,但问题仍然存在。
所以我已经更新了我的配置:
/*Configuring GPIO Pins*/
/*Clearing whatever is held in the mode registers for pins 2 and 3 (Inverting with their masks.)*/
GPIOA -> MODER &= ~(GPIO_MODER_MODE2_Msk | GPIO_MODER_MODE3_Msk);
/*The 2 bits 10 are being shifted to the position which configures Mode of pin 2 and also for pin 3 in the mode register.
*(10 is alterntive function mode).*/
GPIOA -> MODER |= (0b10 << GPIO_MODER_MODE2_Pos) | (0b10 << GPIO_MODER_MODE3_Pos);
/*Clearing whatever is held in the output speed registers for pins 2 and 3*/
GPIOA -> OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED2_Msk | GPIO_OSPEEDR_OSPEED3_Msk);
/*Setting the speed of pins 2 and 3 to be very high(11)*/
GPIOA -> OSPEEDR |= (0b11 << GPIO_OSPEEDR_OSPEED2_Pos) | (0b11 << GPIO_OSPEEDR_OSPEED3_Pos);
/*Clearing whatever is held in the alternative function registers for pins 2 and 3.*/
GPIOA -> AFR[0] &= ~(GPIO_AFRL_AFSEL2_Msk | GPIO_AFRL_AFSEL3_Msk);
/*Setting the pins 2 and 3 to their alternative functions(TX and RX)*/
GPIOA -> AFR[0] |= (7 << GPIO_AFRL_AFSEL2_Pos) | (7 << GPIO_AFRL_AFSEL3_Pos);
/*Clock Configuration*/
/*Enabling the USART2 peripheral clock.*/
RCC->APB1ENR1 &= ~(RCC_APB1ENR1_USART2EN_Msk);
RCC->APB1ENR1 |= (0b1 << RCC_APB1ENR1_USART2EN_Pos);
/*Enabling the GPIOA port peripheral clock*/
RCC->AHB2ENR &= ~(RCC_AHB2ENR_GPIOAEN_Msk);
RCC->AHB2ENR |= (0b1 << RCC_AHB2ENR_GPIOAEN_Pos);
/*USART Configuartion*/
/*The 72 MHz APB1 bus clock with a 9600baud rate gives a baud rate for the register of 0x1D4C*/
USART2->BRR = 0x1D4C;
/*For USART2 we need to enable the overall UART (U) driver, the transmission lines(T) and the reading lines(R). UART Enable is last.*/
USART2->CR1 &= ~(USART_CR1_RE_Msk | USART_CR1_TE_Msk | USART_CR1_UE_Msk);
USART2->CR1 |= USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;
这大大加深了我对如何正确配置设备的理解。然而,我仍然对代码反弹一个角色的总体目标有疑问,因为数据仍然没有被 MCU 读取。如果成功,我会继续进行更新。我感谢任何进一步的建议。
- 这不会初始化 GPIO MODER 或 OPEEDR 寄存器。
GPIOA->MODER |= GPIO_MODE_AF_PP;
GPIOA->OSPEEDR |= GPIO_SPEED_FREQ_HIGH;
GPIO_MODE_AF_PP
& GPIO_SPEED_FREQ_HIGH
是 HAL 定义,不能用于寄存器级别。
您需要为您使用的每个引脚设置适当的值:
它永远不会接收或发送任何东西,因为您忘记设置 GPIO -> AF 寄存器并且硬件未在内部连接到引脚。
您可以在数据表中找到备用函数 mappin
以及参考手册中的 AF GPIO 寄存器
这个顺序应该是:
GPIOA -> MODER &= ~(GPIO_MODER_MODE2_Msk | GPIO_MODER_MODE3_Msk);
GPIOA -> MODER |= (0b10 << GPIO_MODER_MODE2_Pos) | (0b10 << GPIO_MODER_MODE3_Pos);
GPIOA -> OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED2_Msk | GPIO_OSPEEDR_OSPEED23Msk);
GPIOA -> OSPEEDR |= (0b11 << GPIO_OSPEEDR_OSPEED2_Pos) | (0b11 << GPIO_OSPEEDR_OSPEED3_Pos);
GPIOA -> AFR[0] &= ~(GPIO_AFRL_AFSEL2_Msk | GPIO_AFRL_AFSEL3_Msk);
GPIOA -> AFR[0] |= (7 << GPIO_AFRL_AFSEL2_Pos) | (7 << GPIO_AFRL_AFSEL3_Pos);