STM32 裸机 C - 无法让 LED 工作
STM32 Bare Metal C - Can't get LED to work
所以我目前正在学习 STM32 微处理器的课程,但是,我似乎连最基本的事情都失败了:打开 LED。完整的代码在这个post.
的底部
重要:
- 硬件运行正常。
- 我正在使用 STM32L432KC。
首先我们要搞清楚内置LED是在什么管脚上。根据制造商手册,LED 应位于引脚 D13 (PB3) 上。
好的,我们正在寻找 PB3。根据 STM32L432KC 的数据表,PB3 在 B 端口上,因此连接到高性能总线,如下图所示。
酷。所以我们的总线是 AHB2,我们正在使用 GPIOB。现在我们必须使用 RCC_AHB3ENR 寄存器启用该总线上的时钟。现在,这是我可能会犯错误的部分(因为这个 post 否则不会存在),所以请密切注意。如果我理解正确,我希望位 1 设置为 1,因为这表示 'GPIOBEN' 设置为 'IO port B clock enabled.'。
这让我相信我应该按如下方式设置总线寄存器:
RCC->AHB2ENR |= 0x2;
接下来我必须将GPIO引脚的模式设置为输出。根据课程和我的文档,这是使用 GPIOx_MODER 完成的。
这让我相信我应该按如下方式设置 GPIO 模式:
GPIOB->MODER |= 0x40;
最后但同样重要的是,要打开实际的 LED,我们必须设置输出数据寄存器 GPIOx_ODR。
这让我相信我应该按如下方式设置数据:
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;
}
}
您的模式寄存器配置不正确。你的代码行
GPIOB->MODER |= 0x40;
只能设置位,不能清除它们。而且您设置的位太多,因为每对的复位值为 11
并且整个寄存器对于端口 C-E 为 FFFF FFFF
,对于端口 B 为 FFFF FEBF
。
你应该使用
GPIOB->MODER = (GPIOB->MODER & 0xFFFFFF3F) | 0x00000040;
虽然因为复位状态是有保证的,这也行得通:
GPIOB->MODER &= 0xFFFFFF7F; // equivalently, ~0x0080
11 analog mode (reset state)
文档中的说明对所有引脚都不准确。有几个在复位时处于 10 alternate function
模式,包括 PB3。所以你需要清除一位并设置一位。
所以我目前正在学习 STM32 微处理器的课程,但是,我似乎连最基本的事情都失败了:打开 LED。完整的代码在这个post.
的底部重要:
- 硬件运行正常。
- 我正在使用 STM32L432KC。
首先我们要搞清楚内置LED是在什么管脚上。根据制造商手册,LED 应位于引脚 D13 (PB3) 上。
好的,我们正在寻找 PB3。根据 STM32L432KC 的数据表,PB3 在 B 端口上,因此连接到高性能总线,如下图所示。
酷。所以我们的总线是 AHB2,我们正在使用 GPIOB。现在我们必须使用 RCC_AHB3ENR 寄存器启用该总线上的时钟。现在,这是我可能会犯错误的部分(因为这个 post 否则不会存在),所以请密切注意。如果我理解正确,我希望位 1 设置为 1,因为这表示 'GPIOBEN' 设置为 'IO port B clock enabled.'。
这让我相信我应该按如下方式设置总线寄存器:
RCC->AHB2ENR |= 0x2;
接下来我必须将GPIO引脚的模式设置为输出。根据课程和我的文档,这是使用 GPIOx_MODER 完成的。
这让我相信我应该按如下方式设置 GPIO 模式:
GPIOB->MODER |= 0x40;
最后但同样重要的是,要打开实际的 LED,我们必须设置输出数据寄存器 GPIOx_ODR。
这让我相信我应该按如下方式设置数据:
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;
}
}
您的模式寄存器配置不正确。你的代码行
GPIOB->MODER |= 0x40;
只能设置位,不能清除它们。而且您设置的位太多,因为每对的复位值为 11
并且整个寄存器对于端口 C-E 为 FFFF FFFF
,对于端口 B 为 FFFF FEBF
。
你应该使用
GPIOB->MODER = (GPIOB->MODER & 0xFFFFFF3F) | 0x00000040;
虽然因为复位状态是有保证的,这也行得通:
GPIOB->MODER &= 0xFFFFFF7F; // equivalently, ~0x0080
11 analog mode (reset state)
文档中的说明对所有引脚都不准确。有几个在复位时处于 10 alternate function
模式,包括 PB3。所以你需要清除一位并设置一位。