我想了解this代码
但我无法理解这部分代码。
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= -_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
sbi
和cbi
稍后在代码中用作
void system_sleep()
{
sbi(MCUCR,PUD); //Disables All Internal Pullup Resistors
sbi(GIMSK,PCIE); //Enable Pin Change Interrupts Interrups
sbi(PCMSK,PCINT0); //Changes Interrupt to PIN1 (PCINT1)
cbi(ADCSRA,ADEN); //switch Analog to Digital Converter OFF
cbi(MCUCR,SM0); //Power Down Mode
sbi(MCUCR,SM1); //Power Down Mode
sbi(MCUCR,SE); //sleep Mode Power down enable (Sleep_enable(); should set this-- not tested yet)
sleep_enable(); //Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
sleep_mode(); //sleep begins here
sleep_disable(); //Coming out of sleep
sbi(ADCSRA,ADEN); //switch Analog to Digital Converter ON
cbi(MCUCR,PUD); //Enables Pullup Resistors Again
}
代码用于ATtiny85
,我阅读了数据表,我发现所有这些都是MCCUR
和ADCSRA
等都是寄存器。它还声明有两种说明SBI
和CBI
。
我还阅读了一些关于使用C的微控制器编程的教程,并了解每个寄存器都有8
位。可以使用针对不同功能的编程来设置这些位中的每一个。此外PUD
,PCIE
是这些寄存器的不同位,这些寄存器在system_sleep
函数中设置。所以我理解system_sleep
函数正在做什么,它正在设置寄存器中的位。
我无法理解的唯一部分是
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= -_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
数据表中没有任何内容,例如_SFR_BYTE
或_BV
。我查看了AVR / libc标题,在那里我发现_BV
但不知道它在做什么。
答案 0 :(得分:3)
宏的名称应该给你一些提示。 cbi
代表Clear Bit
,sbi
代表Set Bit
。 cbi(sfr, bit)
清除注册表bit
中sfr
指示的位数。 sbi
的类似解释。
如果您拥有整个项目,则可以搜索_SFR_BYTE
和_BV
的定义。但在本质上他们粗略地转化为
#define cbi(sfr, bit) ((sfr) &= ~(1 << (bit)))
#define sbi(sfr, bit) ((sfr) |= (1 << (bit)))
详细了解bit-masking。
答案 1 :(得分:1)
#define _BV(bit) (1 << (bit))
#define _SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr))
第一个_BV
作为示例,您可以只编写1<<0
而不是在代码中编写_BV(0)
。
第二个_SFR_BYTE
使用_MMIO_BYTE
宏从寄存器sfr获取数据,该数据可以是MCUCR或ADCSRA或任何8位IO寄存器。
有关更多信息,请参阅avr/sfr_defs.h
答案 2 :(得分:0)
可以使用输入和输出指令读取/写入从0x00到0x1F的AVR ATMega寄存器,此外还有适用于这些寄存器的特定指令。也可以使用存储器指令读取这些寄存器。在这种情况下,那些寄存器地址必须采用0x20到0x3F的值。
宏__SFR_xxxx考虑到了这种行为。
以下是ATMega 2560“注册摘要”段落的注释:
-2。地址范围$ 00 - $ 1F内的I / O寄存器可使用SBI和CBI指令直接进行位访问。在这些reg- 通过使用SBIS和,可以检查单个位的值 SBIC指示。
-4。使用I / O特定命令IN和OUT时,必须使用$ 00 - $ 3F的I / O地址。将I / O寄存器作为数据空间进行寻址时 使用LD和ST指令,必须将20美元添加到这些地址。 ATmega640 / 1280/1281/2560/2561是一款复杂的微控制器 64个位置内可支持的外围设备数量更多 在操作码中保留IN和OUT指令。对于扩展 SRAM中的I / O空间从$ 60 - $ 1FF,只有ST / STS / STD和LD / LDS / LDD 可以使用说明。