2011年7月3日 星期日

AVR GCC中 位元測試,設定 ,清除指令 BV用法

AVR-GCC裡要如何實現位元定址呢?須用_BV(),bit_is_set( , )函數,bit_is_clear( , )函數

1 BV : marco _BV(bit) 是我們操作I/O 寄存器時頻繁用到的,avr-libc 建議使用這一marco進行 寄存器的位元操作,它在檔sfr_defs.h 中定義如下:
#define _BV(bit) (1 << (bit))

以下是它的使用示例:
DDRB=_BV(PB0)|_BV(PB1); // io.h 中定義 PB0: 0 PB1: 1

它等同於 DDRB=0X03; ,這樣寫的目的是為了提高程式的可讀性。不要擔心它會生成DDRB=0X03; 更大的代碼,編譯器會處理這種事情,最終會輸出與DDRB=0X03; 同樣的結果。

用法:BV(pos); #define _BV(bit) (1 << (bit))說明:將位定義轉換成遮罩碼(MASK)。與head file文件io.h裏的位定義一起使用。例如,置位WDTOEWDE可表示為“BV(WDTOE) | BV(WDE)”

2bit_is_clear用法:uint8_t bit_is_clear(uint8_t port, uint8_t bit);描述:如果portbit位清零則返回1。此函數調用sbic指令,故port應為有效位址。

3bit_is_set用法:uint8_t bit_is_set(uint8_t port, uint8_t bit);描述:如果portbit位置位則返回1。此函數調用sbis指令,故port應為有效位址。

4loop_until_bit_is_clear用法:oidoid loop_until_bit_is_clear (uint8_t port, uint8_t bit);說明:此函數簡單地調用sbic指令來測試埠portbit位是否清零。port必須為有效埠。

5loop_until_bit_is_set用法:oidoid loop_until_bit_is_set (uint8_t port, uint8_t bit);說明:此函數簡單地調用sbis指令來測試埠portbit位是否置位。port必須為有效埠。

6cbi用法:void cbi(uint8_t port, uint8_t bit);說明:清零portbit位。bit的值為0~7。如果port為實際I/O寄存器,則此函數生成一條cbi指令;否則,函數生成相應的優化代碼。

7sbi用法:void sbi(uint8_t port, uint8_t bit);說明:置位portbit位。bit的值為0~7。如果port為實際I/O寄存器,則此函數生成一條 sbi指令;否則,函數生成相應的優化代碼。
8
inp用法:uint8_t inp(uint8_t port);說明:從埠port讀入8比特的數值。如果port為常數,則函數生成一條in指令;若為變數,則函數用直接定址指令。

9outp用法:void outp(uint8_t val, uint8_t port);說明:將val寫入埠port。如果port為常數,則函數生成一條out指令;若為變數,則函數用直接定址指令。

範例如下:
#include "avr/io.h"
#define  flag_a_0 0x01;
#define  flag_a_1 0x02;
#define  flag_a_2 0x04;
#define  flag_a_3 0x08;
#define  flag_a_4 0x10;
#define  flag_a_5 0x20;
#define  flag_a_6 0x40;
#define  flag_a_7 0x80;

#define  _set_aa    flag_a=flag_a|flag_a_2;
#define  _clr_aa    flag_a=flag_a&~flag_a_2;
unsigned char flag_a,flag_b;

int main(void)
{
   DDRB=0XFF;
   PORTB=0XFF;
   PORTB|=_BV(5);  //
portb5bit
1
   PORTB&=~_BV(5); //
portb5bit0

   PORTB^=_BV(6);  //portb6bit反轉
   PORTB^=_BV(6);  //
portb6bit反轉

   flag_a^=_BV(3);  //flag_a3bit反轉
   // flag_a^=_BV(3);
   if ((flag_a&_BV(3))==0) //
測試flag_a3bit是否為0
      {  
   flag_a^=_BV(7); //
flag_a7bit反轉

      }
      else    flag_a^=_BV(6);  //
flag_a6bit反轉

   //flag_b^=_BV(3);

    if (bit_is_clear (flag_b,0x03)) //
測試flag_b3bit是否為
0
  {
  flag_b|=_BV(04);//
flag_b4bit
1
  }

    if (bit_is_set (flag_b,0x03)) //測試flag_b3bit是否為1
  {
     flag_b&=~_BV(04);//
flag_b4bit
0
  }

   flag_a=0xa1;
   flag_a=flag_a|flag_a_2;
   _clr_aa;
   _set_aa ;
   flag_a=flag_a&~flag_a_2;
 }



沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。