新聞中心

AVR編程_位定義

作者: 時(shí)間:2016-11-23 來源:網(wǎng)絡(luò) 收藏
Question
在我的源代碼中如何進(jìn)行位定義
Answer

我們總是在AVR器件數(shù)據(jù)手冊(cè)中推薦使用位定義的方式來編寫你的C或匯編源代碼。

本文引用地址:http://www.butianyuan.cn/article/201611/320369.htm

位定義與器件手冊(cè)的該位定義一致的話可以很方便的理解代碼的含義和讓其他人更好的理解你的代碼。同時(shí),如果你需要移植你的代碼到其他的AVR器件,用位定義可以很方便的進(jìn)行移植,因?yàn)椴煌腁VR器件的絕對(duì)地址和位的位置或許不同,但是位定義通常都保持一致。當(dāng)移植一個(gè)設(shè)計(jì),經(jīng)常需要包含正確的定義文件。

在不同的AVR器件的編譯器包含文件中,所有的I/O寄存器位命名和位置都被定義了。

下面是一個(gè)Atmega16在WinAVR中的例子,iom16.h包含文件中TXEN(使能USART發(fā)送器)和RXEN位(使能USART接收器)定義如下:

#define UCSRB _SFR_IO8(0x0A)
#define TXEN 3 //Bit 3
#define RXEN 4 //Bit 4

因此,在代碼中,寫UCSRB = (1<

另一個(gè)匯編和c代碼的例子如下:

匯編代碼

***************************************************************
...
; Define pull-ups and set outputs high
; Define directions for port pins
ldi r16,(1<ldi r17,(1<out PORTB,r16
out DDRB,r17
; Insert nop for synchronization
nop
; Read port pins
in r16,PINB
...
***************************************************************

C代碼
***************************************************************
unsigned char i;
...


PORTB = (1<DDRB = (1<
asm("nop");

i = PINB;
...
***************************************************************

為了避免各多的附加功能和寄存器功能的沖突,不要訪問被標(biāo)注為保留的寄存器位。保留的寄存器總是被寫為0。這能確保前向兼容性,同時(shí)當(dāng)前未用的功能將都保持在默認(rèn)的狀態(tài)。

____________________以下為老于添加,2009/06/07________________________

讀取外部引腳電平時(shí),應(yīng)讀取PINX.n的值,比如,

1)判斷PD6是否高電平:

if(PIND & (1<<6))...

2)等待PD6變?yōu)榈碗娖?,如判斷ADC轉(zhuǎn)換完成

while( !(PIND & (1<<6) );

或者寫成:

while( (PIND & 0x40) == 0x40 );

需要注意的是,在純粹軟件環(huán)境下,如VC,一個(gè)變量與一個(gè)常量與操作之后,往往會(huì)改變?cè)撟兞康闹?,?/p>

unsigned char ch = 0xc0;

unsigned char ch1 = ch & 0x40;

此時(shí)ch1 = 0x40,其值已經(jīng)改變。

而讀取管腳的輸入狀態(tài),PINX,或者讀取寄存器數(shù)據(jù),如UCSR0A串口接收寄存器的內(nèi)容,該數(shù)值與一個(gè)常量與操作之后,并不會(huì)改變其內(nèi)容本身,即,下次再讀取PINX和UCSR0A,其值不會(huì)改變,除非硬件條件發(fā)生了改變它才會(huì)發(fā)生變化。這些變量依存于硬件環(huán)境。

這也是初學(xué)者對(duì)變量,常量,位操作使用上容易混淆的問題所在。




關(guān)鍵詞: AVR編程位定

評(píng)論


技術(shù)專區(qū)

關(guān)閉