Avr單片機和其他單片機一樣,有自己的指令和寄存器,特定的IO口操作方法,有定時器,AD轉(zhuǎn)換,串行口,PWM輸出,EEPROM等。為了縮短大家學習的時間,快速的了解avr編程思路,擬定avr程序設計系列教程。我使用avr也不是很長時間,技術(shù)有限,錯誤再所難免,還請指出,以期改正。
【說明】:本頁是針對從來沒有碰過單片機或者用過單片機而沒有用c語言的朋友,如果你已經(jīng)用過其他單片機,此頁說明可能對你沒有很大幫助,且顯得有些幼稚,請你跳過。
本站所有程序都是在icc+avrstudio下進行的,如果你沒有配置好環(huán)境
采用icc的原因之一是它自帶一個非常好用的application builder,生成的代碼結(jié)構(gòu)清晰,層次清楚,特別適合新手,如下圖。
非常好用的 icc application builder
icc的程序生成器
進入該界面后,我更改設置,Target CPU,及目標芯片設置位mega16這個非常常用的芯片,Xtal speed 及晶振頻率,我選了我用的7.3728MHz。
下面我們來看看我們得到的代碼?!菊f明】:“#”只是為了方便解釋代碼,并非為程序內(nèi)容。
#1 //ICC-AVR application builder : 2006-11-3 14:42:54
#2 // Target : M16
#3 // Crystal: 7.3728Mhz
#4 #include
#5 #include
#6 void port_init(void)
#7 {
#8 PORTA = 0x00;
#9 DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
#10 }
#11 //call this routine to initialize all peripherals
#12 void init_devices(void)
#13 {
#14 //stop errant interrupts until set up
#15 CLI(); //disable all interrupts
#16 port_init();
#17 MCUCR = 0x00;
#18 GICR = 0x00;
#19 TIMSK = 0x00; //timer interrupt sources
#20 SEI(); //re-enable interrupts
#21 //all peripherals are now initialized
#13 }
#1——#3,注釋行,分別說明了程序生成者是ICC-AVR application builder,生成時間,CPU類型,晶振大小,在本例中晶振大小沒有用途,但在實際操作中,晶振大小將影響定時器的設置,PWM波形的輸出,串口波特率的設定,總線時序等多方面的問題。
#4——#5,包含特定頭文件,學過c語言的人都知道,c語言里幾乎每個程序都要包含特定的頭文件,在這里,iom16v.h和macros.h都在icc程序安裝文件夾下一個include的目錄中,iom16v.h和你選擇的芯片相對應,如果你選擇的是atmega32,那個這個文件就是iom32v.h,等等,在這樣的文件中定義了對應的芯片的各個硬件地址。macros.h文件中定義了一些宏命令和一些老的語言寫法。通常每一個程序都要包含這個頭文件。
#6 void port_init(void),定義函數(shù)port_init,函數(shù)的用途是初始化串口,前面一個void表示函數(shù)沒有輸出,括號里的void表示這個函數(shù)沒有輸入變量。
#7,#10 C語言中所有函數(shù)體都要寫在{}內(nèi),一個開始,一個結(jié)束。
#8,定義PA口為0x00,及PA口上的所有管腳輸出為低電平,同樣道理,如果些微PORTA=0xFF,則都輸入高電平,0xFF及二進制的11111111,如果想讓某一位輸出高,其他為低,如00000001,則是PA0輸出為高電平,PA1——PA7輸出為低電平。說明:每個口線與單片機實際引腳的對應關(guān)系請參看技術(shù)手冊。
#9,定義引腳的輸出輸入模式,1為輸出,0為輸入。當使用輸出模式及設置為1時,PORTA的值將影響內(nèi)部上拉電阻的使用,如果PORTA對應管腳的值為1,則使用內(nèi)部上拉電阻,否則不采用。 除了這里說的“=”之外,管腳的控制還有其他算符,|= ,&=! ,^=,==,請參考學習筆記:avr端口操作的例子理解,將在本頁后面部分說明。
同理,下面部分為BCD口的操作。
#11,注釋,說明你可以使用下面的程序來實現(xiàn)初始化。
#13,程序的開始和結(jié)束。
#15,內(nèi)部定義的宏,關(guān)閉所有中斷。
#16,調(diào)用端口初始化的程序。
#17,MCUCR = 0x00;電源管理及睡眠模式寄存器設置,這里設為0x00,為空閑模式,更多內(nèi)容,請參看atmega16技術(shù)手冊。
#18,GICR = 0x00;通用中斷控制寄存器設置,0x00,代表禁用任何中斷,更多內(nèi)容請參考技術(shù)手冊。
#19,TIMSK = 0x00;定時器設置,0x00代表不使用定時器。
#20,與#15對應,內(nèi)部定義的宏,開中斷。
#21,注釋,所有功能初始化完成。
到此,一個簡單的程序就看完了,本程序并不能真正運行,因為沒有main主函數(shù)。進一步的學習請看
【icc + AVRStudio】下的第一個程序【一】AVR端口操作說明
一些端口操作的運算符總結(jié),我初學時總結(jié)出來的東西,端口操作是單片機操作的基本要素。 以下給出不是完整的程序,只是對端口操作的一些理解。
#include
void main(void)
{
PORTA=0xff; //在定義DDRA之前定義PORTA將影響上拉電阻的使用。 1為使用上拉電阻,0為不使用。
DDRA=0xff; //輸出 模式 ,IO口上,1為輸出,0為輸入。
PORTA=0xf0; //等
PORTA&=~0xf0; //清零
PORTA|=0x77; //置一
PORTA^=0x70; //翻轉(zhuǎn)
(P & 0x80)==0x80; //按位與 判斷p的第七位是否是一,是則成立
}
ADIF就是4 跟手冊的為定義是一樣的
(1<
ADCSR=(1<
ADCSR|=(1<
ADCSR&=~(1<
while(ADCSR&(1<
while(1)
{
while(ADCSR&(1<
{
程序......
}
}