c - 像STM8一样编程STM32(寄存器级GPIO)
问题描述
我对STM8 GPIO进行了编程,PD_ODR_ODR4 = 1;
但stm32f10x.h没有这个功能。是否有任何.h文件具有位定义。
对不起,但我不知道如何更好地解释这个问题。
我尝试了多个 GPIO 库。
强文本
解决方案
您stm32f10x.h
在问题中提到,所以我假设它与 STM32F1 系列控制器有关。其他系列有一些差异,但一般程序是相同的。
GPIO 引脚排列在 16 个称为端口的组中,每个端口都有自己的一组控制寄存器,命名为GPIOA
、GPIOB
等。它们被定义为指向GPIO_TypeDef
结构的指针。有 3 个控制寄存器影响引脚输出。
写入ODR
一次设置所有 16 个引脚,例如GPIOB->ODR = 0xF00F
将引脚设置为 1,然后设置为0 ,无论它们之前的状态如何B0
。可以写入将引脚设置为 1,或将其重置。B3
B12
B15
B4
B11
GPIOD->ODR |= (1<<4)
GPIOD4
GPIOD->ODR &= ~(1<<4)
写入BSRR
将写入的值视为两个位掩码。低半字是设置掩码,值为 1 的位将相应位设置ODR
为 1。高半字是复位掩码,值为 1 的位将相应位设置ODR
为 0。GPIOC->BSRR = 0x000701E0
将引脚设置C5
为1 ,C8
重置为0,并保留所有其他端口位。在写入时尝试设置和重置相同的位,然后它将被设置为 1。C0
C2
BSRR
写入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 编程手册中。