不使用 Cube MX 库控制 STM32F3 GPIO

Posted

技术标签:

【中文标题】不使用 Cube MX 库控制 STM32F3 GPIO【英文标题】:Controlling STM32F3 GPIOs without the Cube MX libraries 【发布时间】:2021-07-07 11:52:04 【问题描述】:

我正在为STM32F373CC 调整this bootloader 以适应我的设备。为了表明设备已通电但处于引导加载程序模式,我想打开一些状态 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,而第二个答案缺少cmets,所以我不完全理解他们在做什么。

【问题讨论】:

【参考方案1】:

我希望您知道开漏输出需要上拉(内部或外部)

使用 CMSIS 定义,而不是幻数和运算。

需要整个 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 寄存器 typedef 和定义。

#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

【讨论】:

谢谢,时钟启用是问题所在。它适用于RCC -&gt; AHBENR |= RCC_AHBENR_GPIOBEN; while( ( (RCC-&gt;AHBENR) &amp; RCC_AHBENR_GPIOBEN ) == 0 ); 虽然不需要。由于公共汽车操作非常有序,(void)RCC-&gt;AHBENR; 就足够了,或者您可以简单地添加 __DSB();,这会增加足够的延迟并设置障碍

以上是关于不使用 Cube MX 库控制 STM32F3 GPIO的主要内容,如果未能解决你的问题,请参考以下文章

用HAL库结合STM cube编写代码控制stm32f103c8t6来驱动减速电机实现慢快逐步切换转动

ST的STM32系列单片机

如何将带有 SPL 的 STM32F3 代码移植到 STM32F7

STM32F4系列单片机上使用CUBE配置MBEDTLS实现pem格式公钥导入

STM32F3 DISCOVERY USART 不工作

配置为使用外部振荡器的 STM32F3 器件上的 RCC 振荡器配置错误