繁体   English   中英

是否可以通过C变量而不是使用GPIO_Pin_N值读取和/或写入端口?

[英]Is it possible to read and/or write ports via a C variable instead of using GPIO_Pin_N values?

我可以找到的所有示例代码都可以访问端口,如下所示:

GPIO_SetBits(GPIOE, GPIO_Pin_9 | GPIO_Pin_13);

最初看起来还不错,直到我尝试通过索引(0-7)引用LED(我的端口E)。 switch或LUT是解决方案,但我都不喜欢。 是否可以声明例如uint8_t并将其映射到某个端口的特定引脚范围?

标准的Cortex-M3 / M4内存映射允许CPU具有区域的所谓“位带”别名,其中对位带别名中的每个字进行写入都会自动执行读取-修改-写入操作,以更改相应区域中的目标位。

以STM32F411(Cortex-M4F)手册为例,该示例显示外围区域0x40000000-0x400FFFFF被区域0x42000000-0x43FFFFFF的位带别名0x42000000-0x43FFFFFF 因此,例如在该设备上(如果我的数学正确的话),来自0x42420280-0x42420300每个单词对应于GPIO端口E数据寄存器GPIOE_ODR中位于0x40021014 ,因此:

volatile int *leds = (void *)0x42420280;
leds[x] = 1; /* only bit 0 of the bit-band word actually holds data */

使硬件执行与​​此类似的抽象方法:

volatile int *leds = (void *)0x40021014;
int val = *leds;
val |= (1 << x);
*leds = val;

如果您有合适的设备,则不想一次更新多个位,也不必介意额外的开销,而在某些情况下(例如,写入设置/清除寄存器而不是数据)与常规寄存器的一次访问无关),这是一个非常巧妙的技巧。

GPIO_Pin_X常量的值定义为16位值内的位位置,其中引脚0为最低有效位,引脚15为最高有效位:

#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
[...]
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */

(这就是为什么您可以将它们或在一起写入多个引脚的原因!)

如果您需要动态索引引脚,则可以使用如下宏:

#define GPIO_Pin(x) ((uint16_t) 1 << (x))

总线是固定宽度的,因此您无法使用软件更改硬件,也不能使用软件将外围设备中的固定大小的寄存器分解为较小的部分。 您可以使它出现在软件中来执行此操作,但是最终,由高级代码生成的实际代码仍会进行读取-修改-写入操作,或者根据总线或外围寄存器大小的事务进行所需或支持的操作。

试图使事情变得更小,甚至使变量的大小与寄存器的本机大小相比,最终都会产生更多或效率低下的代码。 因此,尝试了解您为什么仍要这样做。

我最近玩过的stm32有一个位清除/设置寄存器,在其中写入一个清除或设置引脚的输出状态。 在逻辑上,它只是清除或设置控制该端口输出的触发器,从逻辑上讲,它们可以/确实将控件的后端实现为更小的部分,但是您不能从软件中直接访问未对齐,大小不正确的传输中的那些。 一些公司要求您使用软件进行读-修改-写操作。 因此,使用具有这些功能的stm32(其他品牌可能也具有类似的功能,有时使用地址,有时像这样,但在单独的寄存器中设置一个清除位)实际上使您的代码尽可能简单。

我们非常欢迎您为gpio引脚组合创建任意数量的定义,以便在您的主代码中只需要一个助记符,而不是多个助记符即可。

如果可以使编译器可靠地生成正确大小的str,则不必具有设置位的功能;如果在单个定义中的位可以将代码简单地转换为a = b,则不必具有正确的组合。 情况。

从您模糊的问题中我猜得出,LUT是最佳解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM