STM32/STM8技术william hill官网
直播中

刘强

7年用户 1180经验值
私信 关注
[问答]

STM32上的GPIO输出寄存器

嗨我目前正在尝试使用基于STM32F334R8的STM32 Nucleo开发板编写一个简单的程序。应用程序设置GPIO端口A和C,并读取按钮的状态。如果按下按钮,则会打开LED。如果没有,它会将其关闭。
从ST的文档(STM Nucleo 64)我已经确认按钮连接到引脚C13,LED2连接到引脚A5。
从数据表中,我一直在阅读GPIO寄存器(Long STM32F334数据表),看看有三个似乎与输出有关; ODR,BSRR和BRR。
在实现上述应用时,我首先想到的是使用ODR为输出LED写入GPIO引脚状态,如下所示:
SET_BIT(GPIOA->ODR, GPIO_ODR_5);CLEAR_BIT(GPIOA->ODR, GPIO_ODR_5);
这似乎不起作用。检测到我的按钮被按下,因为我可以通过看到它按照不同的路径在调试器中验证这一点。这是我的GPIO设置代码:
  1. // set one to input
  2. CLEAR_BIT(GPIOC->MODER, GPIO_MODER_MODER13_0);
  3. CLEAR_BIT(GPIOC->MODER, GPIO_MODER_MODER13_1);
  4. // set another to output
  5. SET_BIT(GPIOA->MODER, GPIO_MODER_MODER5_0);
  6. CLEAR_BIT(GPIOA->MODER, GPIO_MODER_MODER5_1);
  7. // set output to push-pull
  8. CLEAR_BIT(GPIOA->OTYPER, GPIO_OTYPER_OT_5);
  9. // set input with pull-up
  10. SET_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPDR13_1);
  11. CLEAR_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPDR13_0);

  12. // enable GPIOA and GPIOC clock
  13. SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN);
  14. SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOCEN);
我还看到了一块在我的主板上使用BSRR和BRR位的示例代码,如下所示:
  1. // set output high
  2. SET_BIT(GPIOA->BSRR, GPIO_BSRR_BS_5);
  3. // set output low
  4. SET_BIT(GPIOA->BRR, GPIO_BRR_BR_5);

....但这不起作用。
我不确定我理解三个寄存器及其功能之间的区别。
每个用例有哪些?哪一个适合我的要求?

回帖(3)

张波

2018-9-26 11:36:08
我在代码中看到的最明显的问题是,在为相应的外设启用时钟之前,您正在写入GPIO寄存器。

如果尚未启用时钟,外设将无法正确响应。在尝试对外围设备执行任何操作之前,请启用所有外设时钟。

尽管如此:ODR和BSRR / BRR之间的差异很小。但是,如果只需要更改一位,则单次写入BSRR(或BRR)比使用ODR上的读取/修改/写入周期更快,并且使用的代码空间更少。但是,如果您确实想要立即设置整个端口的状态,或者需要检查当前输出状态,则可以使用ODR。
举报

刘强

2018-9-26 11:37:41
你是对的,将时钟设置移动到该功能的顶部解决了问题并且应用程序正常工作!我没想到需要首先启用时钟,因为我认为它们只会控制引脚的采样,而不能完全启用外设。谢谢!
举报

周凯

2018-9-26 15:19:15
给楼主顶一顶。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分