在没有 Cube MX 库的情况下控制 STM32F3 GPIO
Controlling STM32F3 GPIOs without the Cube MX libraries
我正在调整 this bootloader for STM32F373CC 以适应我的设备。为了指示设备已通电但处于引导加载程序模式,我想打开一些状态 LED。但是,此引导加载程序不使用 STM Cube MX 库,因此我必须对其进行低级编码。包含头文件 stm32f373xc.h,因此我可以使用 GPIOB_BASE.
等表达式
我在 main() 中尝试了以下第一件事,但不幸的是它不起作用:
// turn on GPIOB clock: SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOBEN);
uint32_t* rcc = (uint32_t*)RCC_BASE;
*(rcc+0x14) |= RCC_AHBENR_GPIOBEN; // AHBENR is at offset 0x14
// configure Port B, pins 4 and 5 to GPIO, Open Drain, low.
uint32_t* gpiob = (uint32_t*)GPIOB_BASE;
*(gpiob) |= 0x500; // GPIO output mode --- GPIOB_MODER = 0x500; (bits 11:8 = 0101), offset 0
*(gpiob) &= ~0xA00;
*(gpiob+0x04) |= 0x30; // output type open drain --- GPIOB_OTYPER = 0x30; (bits 5:4 = 11), offset 0x04
*(gpiob+0x0c) &= ~0xF00; // pull up/down off --- GPIOB_PUPDR = 0x0; (bits 11:8 = 0000), offset 0x0c
*(gpiob+0x14) &= ~0x30; // output low --- GPIOB_ODR = 0x0; (bits 5:4 = 00), offset 0x14
知道我遗漏了什么吗?我如何确定问题是端口 B 的时钟还是引脚配置?
我找到了this similar post,但是第一个答案需要整个CMSIS,第二个答案缺少评论,所以我不完全明白他们在做什么。
我希望你知道开漏输出需要上拉(内部或外部)
使用 CMSIS 定义,而不是幻数和运算。
requires the entire CMSIS
问题是什么? CMSIS 不会给您的代码增加任何开销,只有方便的定义和 内联 函数,如果不使用它们不会改变代码的大小。
此外,HAL 有非常方便的宏,即使您不使用 HAL 库本身也很有用(即使增加一个字节也不会增加代码大小)
我不会检查你的魔法偏移量和数字。
- 第一个错误:启用外设时钟后需要等待。它在参考手册中有描述。您不等待,您的第一个 MODER 操作没有效果。 HAL 宏回读寄存器以确保操作已完成。
来自 STM32L4 的示例:
#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \
__IO uint32_t tmpreg; \
SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN); \
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN); \
UNUSED(tmpreg); \
} while(0)
然后使用 CMSIS 注册类型定义和定义。
#define PIN4 4
#define PIN5 5
GPIOB -> MODER &= ~((0b11 << (2 * PIN5)) | (0b11 << (2 * PIN4)));
GPIOB -> MODER |= ((0b01 << (2 * PIN5)) | (0b01 << (2 * PIN4)));
GPIOB -> OTYPER &= ~((1 << PIN4) | (1 << PIN5));
GPIOB -> OTYPER |= (1 << PIN4) | (1 << PIN5);
GPIOB -> BSRR = (1 << (PIN4 + 16)) | (1 << (PIN5 + 16)); // set the pins low
我正在调整 this bootloader for STM32F373CC 以适应我的设备。为了指示设备已通电但处于引导加载程序模式,我想打开一些状态 LED。但是,此引导加载程序不使用 STM Cube MX 库,因此我必须对其进行低级编码。包含头文件 stm32f373xc.h,因此我可以使用 GPIOB_BASE.
等表达式我在 main() 中尝试了以下第一件事,但不幸的是它不起作用:
// turn on GPIOB clock: SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOBEN);
uint32_t* rcc = (uint32_t*)RCC_BASE;
*(rcc+0x14) |= RCC_AHBENR_GPIOBEN; // AHBENR is at offset 0x14
// configure Port B, pins 4 and 5 to GPIO, Open Drain, low.
uint32_t* gpiob = (uint32_t*)GPIOB_BASE;
*(gpiob) |= 0x500; // GPIO output mode --- GPIOB_MODER = 0x500; (bits 11:8 = 0101), offset 0
*(gpiob) &= ~0xA00;
*(gpiob+0x04) |= 0x30; // output type open drain --- GPIOB_OTYPER = 0x30; (bits 5:4 = 11), offset 0x04
*(gpiob+0x0c) &= ~0xF00; // pull up/down off --- GPIOB_PUPDR = 0x0; (bits 11:8 = 0000), offset 0x0c
*(gpiob+0x14) &= ~0x30; // output low --- GPIOB_ODR = 0x0; (bits 5:4 = 00), offset 0x14
知道我遗漏了什么吗?我如何确定问题是端口 B 的时钟还是引脚配置?
我找到了this similar post,但是第一个答案需要整个CMSIS,第二个答案缺少评论,所以我不完全明白他们在做什么。
我希望你知道开漏输出需要上拉(内部或外部)
使用 CMSIS 定义,而不是幻数和运算。
requires the entire CMSIS
问题是什么? CMSIS 不会给您的代码增加任何开销,只有方便的定义和 内联 函数,如果不使用它们不会改变代码的大小。
此外,HAL 有非常方便的宏,即使您不使用 HAL 库本身也很有用(即使增加一个字节也不会增加代码大小)
我不会检查你的魔法偏移量和数字。
- 第一个错误:启用外设时钟后需要等待。它在参考手册中有描述。您不等待,您的第一个 MODER 操作没有效果。 HAL 宏回读寄存器以确保操作已完成。
来自 STM32L4 的示例:
#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \
__IO uint32_t tmpreg; \
SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN); \
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN); \
UNUSED(tmpreg); \
} while(0)
然后使用 CMSIS 注册类型定义和定义。
#define PIN4 4
#define PIN5 5
GPIOB -> MODER &= ~((0b11 << (2 * PIN5)) | (0b11 << (2 * PIN4)));
GPIOB -> MODER |= ((0b01 << (2 * PIN5)) | (0b01 << (2 * PIN4)));
GPIOB -> OTYPER &= ~((1 << PIN4) | (1 << PIN5));
GPIOB -> OTYPER |= (1 << PIN4) | (1 << PIN5);
GPIOB -> BSRR = (1 << (PIN4 + 16)) | (1 << (PIN5 + 16)); // set the pins low