STM32 裸机 C - 无法让 LED 工作

STM32 Bare Metal C - Can't get LED to work

提问人:Arjan 提问时间:7/21/2019 更新时间:7/21/2019 访问量:1436

问:

因此,我目前正在学习STM32微处理器的课程,但是,我似乎甚至在最基本的事情上都失败了:打开LED。完整的代码在这篇文章的底部。

重要:

  • 硬件运行正常。
  • 我正在使用STM32L432KC。

首先,我们必须弄清楚内置 LED 的引脚是什么。根据制造商手册,LED 应位于引脚 D13 (PB3) 上。enter image description here


好的,所以我们正在寻找 PB3。根据STM32L432KC的数据表,PB3 位于 B 端口上,因此连接到高性能总线,如下图所示。enter image description here


凉。所以我们的总线是AHB2,我们正在与GPIOB合作。现在,我们必须使用RCC_AHB3ENR寄存器使能该总线上的时钟。现在,这是我可能会犯错误的部分(否则这篇文章就不会存在),所以请密切注意。如果我理解正确,我希望将位 1 设置为 1,因为这表明“GPIOBEN”设置为“启用 IO 端口 B 时钟”。enter image description here enter image description here

这使我相信我应该按如下方式设置总线寄存器:

RCC->AHB2ENR |= 0x2;

接下来,我必须设置GPIO引脚的输出模式。根据课程和我的文档,这是使用 GPIOx_MODER 完成的。enter image description here

这使我相信我应该按如下方式设置GPIO模式:

GPIOB->MODER |= 0x40;

最后但并非最不重要的一点是,要打开实际的LED,我们必须设置输出数据寄存器,这是GPIOx_ODR。enter image description here

这使我相信我应该按如下方式设置数据:

GPIOB->ODR = 0x8;

我不确定我哪里出了问题,但这是我第一次在如此深层次上使用寄存器。我一定忽略了什么,但我尝试了多个例子,但没有成功。感谢所有帮助。 这是完整的代码:

// PB3 - User LED
// RCC->AHB2ENR
// GPIOx_MODER
// GPIOx_ODR

#include "stm32l4xx.h"

int main(void)
{
    RCC->AHB2ENR |= 0x2;
    GPIOB->MODER |= 0x40;

    while(1)
    {
        GPIOB->ODR = 0x8;
    }
}
C Arm 嵌入式 微控制器 微处理器

评论


答:

3赞 Ben Voigt 7/21/2019 #1

您的模式寄存器配置不正确。您的代码行

GPIOB->MODER |= 0x40;

只能设置位,不能清除。而且您设置了太多位,因为每对的复位值都是,而整个寄存器是端口 C-E,端口 B 的。11FFFF FFFFFFFF FEBF

你应该使用

GPIOB->MODER = (GPIOB->MODER & 0xFFFFFF3F) | 0x00000040;

尽管由于重置状态是有保证的,这也将起作用:

GPIOB->MODER &= 0xFFFFFF7F; // equivalently, ~0x0080

文档中的注释并非对所有引脚都准确。有几个在复位时处于模式,包括 PB3。因此,您需要清除一位并设置一位。11 analog mode (reset state)10 alternate function

评论

0赞 Arjan 7/21/2019
我已经接受了你的回答,因为这解决了我的问题,但是,有两件事我不清楚。首先: - 我不明白整个寄存器是如何 FFFF FFFF 的,因为它指出端口 B 的重置值是 FFFF FEBF。- 您的 &= 速记似乎不起作用。你的第一个答案是。我想我必须阅读一些更多的按位运算符。
0赞 Arjan 7/21/2019
“GPIOB->MODER &= 0xFFFFFF7F;”不应为复合 AND。如果删除 & 符号,它就可以工作了。
0赞 Ben Voigt 7/21/2019
@Arjan:这是正确的,假设您不想重新配置任何其他引脚。好吧,如果文档没有撒谎,那就太好了。答案已更新。&=
0赞 Lundin 7/22/2019
由于这是初始化代码,因此只需执行 .在第一次写入未初始化的寄存器之前读取它没有意义。GPIOB->MODER = 0x00000040u;
2赞 Ben Voigt 7/22/2019
@Lundin:最后,我相信您的建议会禁用调试端口