gpt4 book ai didi

c - AVR 使用 struct 或 #define 定义引脚

转载 作者:行者123 更新时间:2023-11-30 16:32:18 25 4
gpt4 key购买 nike

我见过很多人说“总是使用#define 来定义库中某些东西的引脚和端口”,目前,我也是这么做的。但我正在考虑使用结构而不是这种方法。

我使用移位寄存器及其库的示例

我所认为的专业

  • 使用一个库轻松处理多个移位寄存器
  • 您无需更改库源文件中的任何内容

我认为的缺点

  • 占用空间(与#define 不同)
  • 可能需要更多时间来计算,因为您必须考虑到每个移位寄存器可以使用不同的端口,并且您必须检查这一点

您知道使用结构体而不是某些 #define 的更多优点或缺点吗?您是否会认为缺点比优点更重要,因此您永远不会使用结构(即使它不是时间或空间关键的)?

最佳答案

以下代码将 AVR 引脚 (PD1) 设置为高电平(假设它已启用为输出):

PORTD |= (1 << 1);

AVR GCC 编译器擅长将这样的代码编译成单个 AVR 汇编指令(名为 sbi),但前提是它在编译时确切知道您要写入哪个寄存器(PORTD),以及您要设置的位(位 1)。

使用一条指令而不是多条指令来设置位有很多优点:

  • 占用的代码空间更少。
  • 运行速度更快。
  • 即使可能运行修改同一寄存器的中断也是安全的,因为读取、修改和写入步骤都发生在一条无法中断的指令中。

如果您使用用#define定义的预处理器宏来定义引脚,那么在预处理器运行后,您的代码将与上面的代码类似,并且应该编译为单个指令。

另一方面,如果您使用结构体来定义引脚,并将这些结构体动态传递给您的库,则编译器很可能无法进行此优化。

这里是一个链接,您可以在其中看到设置 pin 的两种方法,并且可以看到 struct 方法的效率要低得多:

https://godbolt.org/g/mkxHc2

请注意,除了此处讨论的两种方法之外,还有许多其他方法可以指定和操作引脚。 Arduino 库通常将引脚表示为单个数字,然后调用 pinModedigitalWrite 等函数来操作指定的引脚。 (pinModedigitalWrite 的实现效率相当低,必须禁用中断,但它们可以改进。)

更高级的技术是使用 C++ 模板参数来指定引脚,例如 FastGPIO library确实如此。

关于c - AVR 使用 struct 或 #define 定义引脚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50214953/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com