1

このコードを理解しようとしています

しかし、コードのこの部分を理解するのに苦労しています。

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= -_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

sbicbi後でコード内で次のように使用されます。

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 
 }

コードは forATtiny85で、データシートを読んだところ、これらのようなものはすべてレジスタであることがわかりMCCURましADCSRAた。SBIまた、命令にはとの 2 種類があると記載されていますCBI

また、C を使用したマイクロ コントローラーのプログラミングに関するチュートリアルをいくつか読み、各レジスタに8ビットがあることを理解しました。これらの各ビットは、さまざまな機能のプログラミングを使用して設定できます。またPUDPCIEこれらのレジスタの異なるビットであり、これらは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_BV私は AVR/libc ヘッダーを調べましたが、それが何をしているのかわかりませんでした。

4

3 に答える 3

3

マクロの名前からヒントが得られるはずです。cbiを表し、Clear Bitsbi表しSet Bitます。レジスタの でcbi(sfr, bit)示されるビット番号をクリアします。についても同様の説明。bitsfrsbi

プロジェクト全体がある場合は、 と の定義を検索でき_SFR_BYTEます_BV。しかし、本質的に、それらは大まかに次のように翻訳されます

#define  cbi(sfr, bit)   ((sfr) &= ~(1 << (bit)))

#define  sbi(sfr, bit)   ((sfr) |= (1 << (bit)))

ビットマスキングの詳細をお読みください。

于 2012-09-04T06:31:48.533 に答える
1
#define _BV(bit)       (1 << (bit))
#define _SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr))

最初のもの_BVは、例として、1<<0 コードを書く代わりに、ただ書くことができます_BV(0)。2 つ目_SFR_BYTE_MMIO_BYTEマクロを使用して、レジスタ sfr からデータを取得します。これは MCUCR または ADCSRA または任意の 8 ビット IO レジスタである可能性があります。

詳細については、avr/sfr_defs.hを参照してください。

于 2014-12-15T11:34:12.440 に答える
0

0x00 から 0x1F までの AVR ATMega レジスタは、in および out 命令を使用して読み書きできます。さらに、これらのレジスタで動作する特定の命令があります。これらのレジスタは、メモリ命令を使用して読み取ることもできます。この場合、これらのレジスタ アドレスは 0x20 から 0x3F までの値を取る必要があります。

マクロ __SFR_xxxx は、この動作を考慮しています。

これらは、ATMega 2560 の「レジスタの概要」の段落のメモの引用です。

-2. アドレス範囲 $00 ~ $1F 内の I/O レジスタは、SBI および CBI 命令を使用して直接ビット アクセスできます。これらのレジスタでは、SBIS 命令と SBIC 命令を使用して 1 ビットの値を確認できます。

-4. I/O 固有のコマンド IN および OUT を使用する場合、I/O アドレス $00 ~ $3F を使用する必要があります。LD および ST 命令を使用してデータ空間として I/O レジスタをアドレス指定する場合、これらのアドレスに $20 を追加する必要があります。ATmega640/1280/1281/2560/2561 は、IN および OUT 命令用に Opcode で予約された 64 のロケーション内でサポートできるよりも多くの周辺ユニットを備えた複雑なマイクロコントローラーです。SRAM の $60 ~ $1FF の拡張 I/O 空間では、ST/STS/STD および LD/LDS/LDD 命令のみを使用できます。

于 2015-04-10T22:13:26.993 に答える