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裏的位定義一起使用。例如,置位WDTOE和WDE可表示為“BV(WDTOE) | BV(WDE)”

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

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

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

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

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

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

9.outp用法: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);  //
令portb第5bit為
1
   PORTB&=~_BV(5); //
令portb第5bit為0

   PORTB^=_BV(6);  //令portb第6bit反轉
   PORTB^=_BV(6);  //
令portb第6bit反轉

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

      }
      else    flag_a^=_BV(6);  //
令flag_a第6bit反轉

   //flag_b^=_BV(3);

    if (bit_is_clear (flag_b,0x03)) //
測試flag_b第3bit是否為
0
  {
  flag_b|=_BV(04);//
令flag_b第4bit為
1
  }

    if (bit_is_set (flag_b,0x03)) //測試flag_b第3bit是否為1
  {
     flag_b&=~_BV(04);//
令flag_b第4bit為
0
  }

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



沒有留言:

張貼留言

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