我用的是Atmega328。我有“随机”分布在引脚上的输出引脚,也就是说,它们不属于同一端口例如,我的输出管脚可以是PB0、PB4、PC1、PC3和PD1。
我一直用汇编语言编写微控制器程序,所以这将是我第一次使用C语言。我想知道的是,是否有办法避免对每个管脚使用DDRx和Px来设置或清除它们。
例如,我想用这样的方法设置端口B的第一位:

#define NAME_1 DDRB,0

sbi NAME_1;

这可能吗?
编辑:
也许我没有把自己说清楚。我想要的是能够用一些有意义的名称引用某些I/O端口管脚。例如,将PD3命名为“blue_LED”,这样代码可读性更强,如果以后更改了blue LED的位置,则可以轻松修改代码。换句话说,我希望能够打开和关闭某些别针,它们的名称没有硬编码有办法吗?

最佳答案

sbi指令的特殊之处在于它直接操作AVR平台上I/O端口中的一个位使用I/O端口的正常过程是,必须使用其他指令(如out)在I/O端口和寄存器之间复制整字。
也就是说,在C.C中没有sbi只是不知道某个特定平台的这些特殊功能对于作为示例提供的程序集,您可以用C编写:

DDRB |= 1<<0;

我个人认为这看起来很简洁,但是你当然可以定义一个宏
#define sbi(x,b) (x) |= 1<<(b)

sbi(DDRB, 0);

(其中b是“位号”)或者相反
#define cbi(x,b) (x) &= ~(1<<(b))

cbi(DDRB, 0)

这可以用,但我建议不要用虽然第一个符号DDRB |= 1<<0;对任何C程序员来说都是显而易见的,但使用这样的宏可能不是。
最后一点,如果您关心性能:我还没有验证这一点,但我很确定avr-gcc足够聪明,可以在I/O端口上的位掩码操作只改变一个位时发出sbicbi指令编辑:请参阅JLH的答案,以获得一个实验结果,即gcc-avr确实足够聪明,能够发出这些sbi/cbi指令。

07-24 09:44