1
1
如果你能提供一个 MCVE 所以其他人可以很容易地编译你的代码,看看它是如何工作的,并尝试调整它。
你不需要定义这样的事情
问题的一个主要前提是,您发布的带有数组和宏的代码与
如果你不相信我,你可以看看这个神箭。org链接,用于比较两种方法的程序集:
看起来你可以通过添加
现在转到您的主要问题,即如何消除冗余阵列。我不认为有一种简单的方法可以做到这一点,在你的程序中有两个常量数组并不是什么大问题,它们可能会在编译时被优化掉。你可以做的是扩展这些阵列,使它们包含芯片上每个引脚的条目。然后,当你想写入一个管脚时,你只需要使用一个管脚号,它是数组的索引(而不需要定义新的数组)。然后,您的大部分代码都会处理这些pin码,而不必担心阵列。下面是我的写作方式:
上面的每个GPIO函数调用最终都会编译成一条汇编指令。
如果你仔细研究Arduino的核心代码,你会发现像这样的数组。(但是Arduino人在他们的工作中犯了一个错误,即以一种浪费的方式访问这些阵列。)
请注意,使用我上面提供的代码,您可能会意外地传递一个不是编译时常量的pin码,因此编译器将无法对其进行优化,并生成浪费/不安全的代码。这就是为什么最好使用内联汇编和C++模板,比如 FastGPIO library 做 |
2
1
如果希望代码与
1) 假设我们已经定义了某个地方(例如通过
2) 你需要这样的声明:
就为了像这样使用它们
等等,其中每一行都是对相应IO寄存器中的一位的简单写入。 为了实现这一点,你可以定义成吨的
然后
然后,每次代码中都会发生类似的事情
但是
如果您想将它们存储在数组中并按数组索引进行访问,就像在您的示例中一样,那么除了定义两个数组或结构数组之外,没有其他方法,其中两个元素都将包含位号或位掩码,以及指向IO/寄存器的指针。
虽然名字
但在这里,我可以给你一些生活小技巧:
1) 由于寄存器PINx、DDRx、PORTx总是按顺序依次运行(请参阅数据表中的寄存器集摘要),您不需要全部存储它们,只存储对PINx寄存器的引用就足够了,只需在地址中添加1或2即可计算DDRx和PORTx的位置,因为AVR具有指令,可以通过移位来阻止内存访问,代码将足够有效。
2) 这些寄存器位于较低的内存地址中,因此不必存储2/4字节的指针,您可以将它们转换为
|
3
0
最后我利用了
这样就可以轻松地将管脚定义为管脚阵列或单个管脚:
然后可以像这样操纵销:
源代码 这里是: https://github.com/morefigs/avr-bit-funcs . 这只是为Mega 2560编写的,但应该很容易适应其他板。 |
Timo · 如果宏变量后跟构成有效标识符的字符,则不会展开宏变量 6 年前 |
user3623498 · 在#if中更改变量时出现问题 6 年前 |
einpoklum · 来自#cmakedefine替换的意外结果 6 年前 |
Joseph Franciscus · C中预处理器方法的别名++ 6 年前 |
stoper · 防止同一宏在多个转换单元中具有不同的定义 6 年前 |
СеÑгей · MinGW中预处理器g++的奇怪行为 7 年前 |