首页 > 解决方案 > 像STM8一样编程STM32(寄存器级GPIO)

问题描述

我对STM8 GPIO进行了编程,PD_ODR_ODR4 = 1;但stm32f10x.h没有这个功能。是否有任何.h文件具有位定义。

对不起,但我不知道如何更好地解释这个问题。

我尝试了多个 GPIO 库。

强文本

标签: cstm32iarstm8

解决方案


stm32f10x.h在问题中提到,所以我假设它与 STM32F1 系列控制器有关。其他系列有一些差异,但一般程序是相同的。

GPIO 引脚排列在 16 个称为端口的组中,每个端口都有自己的一组控制寄存器,命名为GPIOAGPIOB等。它们被定义为指向GPIO_TypeDef结构的指针。有 3 个控制寄存器影响引脚输出。

写入ODR一次设置所有 16 个引脚,例如GPIOB->ODR = 0xF00F将引脚设置为 1,然后设置为0 ,无论它们之前的状态如何B0。可以写入将引脚设置为 1,或将其重置。B3B12B15B4B11GPIOD->ODR |= (1<<4)GPIOD4GPIOD->ODR &= ~(1<<4)

写入BSRR将写入的值视为两个位掩码。低半字是设置掩码,值为 1 的位将相应位设置ODR为 1。高半字是复位掩码,值为 1 的位将相应位设置ODR为 0。GPIOC->BSRR = 0x000701E0将引脚设置C5为1 ,C8重置为0,并保留所有其他端口位。在写入时尝试设置和重置相同的位,然后它将被设置为 1。C0C2BSRR

写入BRR与在 中写入复位位掩码相同BSRR,即GPIOx->BRR = x等价于GPIOx->BSRR = (x << 16)

现在可以编写一些宏,例如

#define GPIOD_OUT(pin, value) GPIOD->BSRR = ((0x100 + value) << pin)
#define GPIOD4_OUT(value) GPIOD_SET(4, value)

更改单个引脚,但它不像它应该的那样灵活,例如,您不能获取单个引脚的地址并在变量中传递它。

位带

Cortex-M 控制器(不是全部,但该STM32F1系列有)具有此功能,可以使内部 RAM 和硬件寄存器中的各个位可寻址。范围内的每个位0x40000000-0x400FFFFF都映射到范围内的一个完整的 32 位字0x42000000-0x43FFFFFF。它不适用于此地址范围之外的外围设备,例如 USB 或 NVIC。

外设寄存器的位带地址可以用这个宏计算

#define BB(reg) ((uint32_t *)(PERIPH_BB_BASE + ((uint32_t)&(reg) - PERIPH_BASE) * 32U))

并且您可以将生成的指针视为包含 32 个字的数组的基数,每个字对应于外围寄存器中的一个位。现在可以

#define PD_ODR_ODR4 (BB(GPIOD->ODR)[4])

并在作业中使用它。读取它会给出 0 或 1 作为它的值,写入它的值会将写入值的最低有效位复制到外围寄存器位。您甚至可以获取它的地址,并将其传递给一个对引脚执行某些操作的函数。

位带记录在 PM0056 Cortex®-M3 编程手册中。


推荐阅读