如何启用UART4 STM32F215?

问题描述

我正在运行ST发行的标准CMSIS,其中包括libc和所有爵士乐。这是无效的代码

void __attribute__ ((constructor)) uart4_init() {
  // Enable the clock for uart4
  RCC->APB1ENR |= 1 << 19;
  // Enable the clock for GPIO_C,which needs to be configured to pass-through UART4
  RCC->AHB1ENR |= 1 << 2;

  // Set up the GPIOC 11 and 10 pins for UART use
  // Set to alternate function mode
  GPIOC->MODER &= ~(0b1111 << 20);
  GPIOC->MODER |= 0b1010 << 20;
  // Finally set Alternate Function to UART4,to pass through the UART
  GPIOC->AFR[1] &= ~(0b11111111 << 8);
  GPIOC->AFR[1] |= 0b10001000 << 8;

  // Set up the UART port for reasonable sending settings
  // Here follows explanations on all bits set to 1:
    // Enable the serial port
    // Set to nine bits,so we have one to spare for parity
    // (Leave default wakeup method,since unused?)
    // Enable parity
    // Enable odd parity (better at detecting speed mismatch)
    // (Do not set parity error interrupt on)
    // (Do not set transfer buffer empty interrupt on)
    // (Do not set transmission complete,since that is DMA specific)
    // (Do not set recieve buffer not empty interrupt on)
    // (Do not set idle interrupt since we don't use it)
    // (Do not enable transmitter until setup is fully done)
    // (Do not enable reciever until setup is fully done)
    // (Do not enable mute-mode,we don't use it)
    // (Do not send a break character)
  UART4->CR1 = 0b11011000000000; // Set everything up
  // The confusing part,setting the baud rate,is in separate function
  uart4_set_baud(b9600);
  // Enable sending and receiving
  UART4->CR1 |= 0b1100;
}

我已经验证了RCC_APB1ENR位19的设置,但是UART4的控制寄存器似乎没有任何时钟,因此不接受分配。

(gdb) print/x *0x40023840
$23 = 0x80000

在阅读了工作代码(HAL代码,因此几乎被混淆)和文档之后,我仍然无法弄清这一点。

编辑:遵循old_timers建议清理代码。现在应该是一个可用的示例。

Edit2:删除了一些中断,使它们可以更广泛地用作基本示例。特别是由于这些中断位也使您可以通过NVIC启用UART中断。

解决方法

  1. 使用CMSIS时,也请使用人类可读的定义。

    RCC->APB1ENR |= 1 << 19; 
    

很容易在数字上犯一个错误,很快您就会忘记此行的作用。

 RCC->APB1ENR |= RCC_APB1ENR_UART4EN;

精确显示其功能。

您在这里有更好的示例,

 UART4->CR1 = 0b11011110100000;

 UART4->CR1 |= 0b1100;

我认为

 UART4 -> CR1 |= USART_CR1_RE | USART_CR1_TE; 

更容易阅读,而且更安全。

  1. 启用时钟后,您需要提供延迟或回读。

我不使用HAL-但是我真的很喜欢低级HAL宏

 __HAL_RCC_UART4_CLK_ENABLE(); 

正确启用时钟的时间(请记住,许多STM32在RCC域中存在错误,并且需要特殊的过程,这在勘误表中进行了介绍)

#define __HAL_RCC_UART4_CLK_ENABLE()  do { \
                                      __IO uint32_t tmpreg = 0x00U; \
                                      SET_BIT(RCC->APB1ENR,RCC_APB1ENR_UART4EN);\
                                      /* Delay after an RCC peripheral clock enabling */ \
                                      tmpreg = READ_BIT(RCC->APB1ENR,RCC_APB1ENR_UART4EN);\
                                      UNUSED(tmpreg); \
                                      } while(0U)

此宏与简单的寄存器分配+回读一样有效,但是正确执行并且其名称描述了它的作用。

,

经过一些指导性的拆卸(谢谢old_timer!),我现在得出的结论是,我在调试时从错误的地址读取内容,因此我认为一直无法正常工作的一切都一直在起作用。

从本质上来说,当UART4位于0x40004c00时我是从0x40024c00读取...

经过更正后,我发现CR1确实采用了我用二进制编写的0x37a0值(启用后变为0x37ac),BRR则采用了1666的期望值(如果我理解,应为9600波特)文档权限...)。

此后,在向卡发送测试字节后,我可以检查状态寄存器,并得出结论:我已接收到数据并验证以检查我的波特率是否足够接近,以便它可以正常工作(足以继续测试)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...