Programmer Notepad的配置與AVRGCC入門(mén)
單片機(jī)AVR的編程工具很多,有C,ASM,PASCAL,BASIC等等。除ASM由ATMEL公司免費(fèi)提供外,其它大多數(shù)的工具都是需要收費(fèi)的。而C編譯器更是其中收費(fèi)最高的編譯器。但也有例外,那就是GCC——它不但免費(fèi)而且功能也幾乎是“最強(qiáng)”的。所以我作為入門(mén)者,就開(kāi)始學(xué)習(xí)它了!
一、 單片機(jī) 編程
1、 單片機(jī) 與電腦的編程有些許不同,它除一些必要地算法外,更重要的是對(duì)端口的操作。如開(kāi)關(guān)量
采集、開(kāi)關(guān)量控制輸出、模擬量的輸入、通訊的操作、顯示器與鍵的控制等等都需要操作端口。
2、 電腦存儲(chǔ)永久數(shù)據(jù)一般都在硬盤(pán)等介質(zhì)中。而 單片機(jī) 則存放在EPROM、EEPROM、FLASH等存儲(chǔ)器中。
3、 通訊接口的編程對(duì) 單片機(jī) 來(lái)說(shuō)是至關(guān)重要的,特別在工控、網(wǎng)絡(luò)等的應(yīng)用中猶為重要。
4、 單片機(jī) 的編程與電腦編程相比有諸多限制。這就要求編程者對(duì)單片機(jī)硬件有一定的了解。
二、 AVR 單片機(jī) 編程
1、 AVR單片的硬件:我們以ATMega 16為例為說(shuō)明一下AVR 單片機(jī) 吧!
這是ATMEGA 16的引腳及其功能圖(來(lái)自其DataSheet)
A、 從圖中我們可以看出有4個(gè)8位端口共32個(gè)引腳,大多有雙重功能。它們分別命名為PORTA、PORTB、PORTC、PORTD。
B、 PORTA具備普通IO口功能外還有AD轉(zhuǎn)換功能,其精度可以達(dá)到10位,即采集到的ADC的值最大不超過(guò)1023(0-1023),對(duì)應(yīng)外面實(shí)際電壓值的精度需要一定的簡(jiǎn)單換算(主要看其參考電壓)。如參考電壓為2.5V,則有2.5V為1023,則其精度為2.5V/1023就是0.00244V。如參考電壓為5V,則有5V/1023也就是0.0049V。
C、 PORTB口除了基本的IO功能外,特別要提的是PB4、5、6、7的功能,它是SPI(同步串行接口),更重要的是,它可以用來(lái)下載程序。
D、 其它的暫且不說(shuō),必竟不是AVR 單片機(jī) 的介紹文章嘛。
2、 AVR 單片機(jī) 的軟件:
軟件當(dāng)然是用來(lái)控控制這些接口的運(yùn)作及其代表的含義的。這也是個(gè)非常大的問(wèn)題,如果你一點(diǎn)都不懂軟件,請(qǐng)也找本計(jì)算機(jī)編程的書(shū)看看吧。
三、 開(kāi)始AVRGCC編程吧
好了,下面我們來(lái)看一個(gè)簡(jiǎn)單的程序吧。
在WinAVR的Programmer NotePad 2中的圖:
圖2
執(zhí)行Make All后,生成HEX文件(本例中的文件名2.HEX)。以下是它的全過(guò)程。
> "make.exe" all
-------- begin --------
avr-gcc (GCC) 3.4.1 //告知avr-gcc的版本號(hào)
Copyright (C)2004 FreeSOFtware Foundation,Inc. //編譯器所屬于公司及其版權(quán)信息
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//這是ELF文件的一些信息,ELF文件用于調(diào)試。
Size before: //轉(zhuǎn)換前的ELF文件信息
2.elf :
section size addr
.text 208 0
.data 0 8388704
.bss 0 8388704
.noinit 0 8388704
.eeprom 0 8454144
.stab 780 0
.stabstr 1469 0
Total 2457
Converting to AVR Extended COFF: 2.cof//將ELF文件轉(zhuǎn)換成AVR Studio能夠接受的格式
avr-objcopy --debugging --change-section-address .data-0x800000 --change-section-address .bss-0x800000 --change-section-address .noinit-0x800000 --change-section-address .eeprom-0x810000 -O coff-ext-avr 2.elf 2.cof
DiscardingLOCal symbol outside any compilation unit: .do_copy_data_start
Discarding local symbol outside any compilation unit: .do_copy_data_loop
Discarding local symbol outside any compilation unit: .do_clear_bss_start
Discarding local symbol outside any compilation unit: .do_clear_bss_loop
Size after: //轉(zhuǎn)換后的文件信息。
2.elf :
section size addr
.text 208 0
.data 0 8388704
.bss 0 8388704
.noinit 0 8388704
.eeprom 0 8454144
.stab 780 0
.stabstr 1469 0
Total 2457
Errors: none //編譯過(guò)程中產(chǎn)生的錯(cuò)誤數(shù)
-------- end -------- //編譯結(jié)束
> Process Exit Code: 0 //avr-gcc結(jié)束信息,0表示正常結(jié)束
接下來(lái)用AVRISP程序?qū)?.hex文件下載后AVR 單片機(jī) 中,觀看效果。(可以考慮買(mǎi)個(gè)雙龍的試驗(yàn)器SL_AVRAD)。
下面我們來(lái)看看avr-gcc的IDE吧。
主窗口(圖3)
這是非常標(biāo)準(zhǔn)的WindowsStyle窗口。當(dāng)然它由于不是專為avr-gcc設(shè)計(jì),所以對(duì)它進(jìn)行設(shè)置是必不可少的!下面我就來(lái)設(shè)置它,以使它成為我們好用的工具吧。(呵呵!可千萬(wàn)別小看它哦)
在設(shè)置它之前讓我們來(lái)看看,我們希望是一個(gè)怎樣的工具吧。參照其它軟件的IDE。
首先,我們得有個(gè)工程(項(xiàng)目)管理器,這點(diǎn)PN已有,不需我們?nèi)ピO(shè)它。
其次,得方便我們編輯源代碼,最好是有關(guān)鍵字(代碼)高度顯示,以方便我們識(shí)別它們。如果能再給我們實(shí)時(shí)的一些提示就更好了!這方便PN做得非常很好(有人說(shuō)SI很好,不過(guò)我覺(jué)得每個(gè)人有每個(gè)人的習(xí)慣,不必強(qiáng)求)。
再次,我們得在不離開(kāi)IDE的情況下,編輯C語(yǔ)言的makefile文件。生成我“目標(biāo)代碼”(計(jì)算機(jī)中術(shù)語(yǔ)的話叫可執(zhí)行文件),并且,下載到我們 單片機(jī) 中。
好了!來(lái)看看我們對(duì)它的設(shè)置吧!
1、代碼高亮設(shè)置將它設(shè)置成你習(xí)慣的模式。步驟如下:打開(kāi)PN菜單Tools->Options,在Options對(duì)話框中選擇Style->Schemes,你說(shuō)看到了如圖4、5、6所示的內(nèi)容了?,F(xiàn)在開(kāi)始你的設(shè)置吧。
代碼高亮設(shè)置1-預(yù)編譯(圖4)
代碼高亮設(shè)置2-操作符(如+-*/括號(hào)等)(圖5)
代碼高亮設(shè)置3-數(shù)字(圖6)
別小看這點(diǎn)小功能啊,它能幫你找到不少編程錯(cuò)誤哦(圖7)
想將代碼打印出來(lái)嗎,有幫助的!(圖8)
其它高亮設(shè)置同上請(qǐng)大家自已動(dòng)手吧!一定要按自己的習(xí)慣哦。
3、 設(shè)置PN中的菜單“新建”和工具欄圖標(biāo) ,點(diǎn)擊它新建文件時(shí)的文件缺省類型。我們當(dāng)然希望是C類型文件啦,如下圖:
定義新建缺省的文件類型(圖9)
4、 下面開(kāi)始設(shè)置的我們的avr-gcc工具菜單吧!
C語(yǔ)文的Make工具設(shè)定(圖10): 精心的設(shè)置可以讓你的PN,不必其它工具差哦。
5、 C語(yǔ)言Makefile對(duì)于初學(xué)者來(lái)說(shuō)太難了,根本不知道它是干嘛的,怎么工作(說(shuō)的有點(diǎn)夸張)及怎么編寫(xiě)。幸好WinAVR提供給了我們一個(gè)非常好用的工具mfile。下面就將它集成到我們的PN中來(lái)吧!
Makefile工具在PN中的設(shè)定(圖11)(注意本工具設(shè)置為特殊設(shè)置)
Makefile的設(shè)置是將C:WinAVRbin下的wish84.exe、tcl84.dll、tk84.dll三個(gè)文件復(fù)制到C:WinAVRmfile目錄下。并用PN打開(kāi)C:WinAVRmfilemfile.tcl。修改成下圖所示
修改mfile.tcl為圖中選中的部分并保存(圖12)
6、 設(shè)置ISP Programmer工具
ISP串行下載器的設(shè)置(圖13)
按下F4后運(yùn)行的結(jié)果(圖14)
7、 到現(xiàn)在,我想你對(duì)PN有了一些了解了吧??纯聪旅鎺讉€(gè)圖吧!
幾個(gè)快捷鍵及其對(duì)應(yīng)工具的設(shè)置(圖15)它們用著實(shí)在是方便啊
Makefile執(zhí)行后的圖(圖16)
這是PN對(duì)大項(xiàng)目、大工程管理的超強(qiáng)部分了(圖17)
到此,Programmer NotePad 設(shè)置完成。
四、 Avr-gcc簡(jiǎn)易入門(mén)
1、 對(duì)端口的操作:
A、 如果我想將PORTB端口設(shè)置為輸出口(8位),則在gcc中用如下方式
DDRB=0xFF; 注意:0xFF=0B1111 1111表示全為1,代表了輸出。如果你改上式為:
DDRB=0x01; //即0B0000 0001,則表示,你將PORTB的第0位(PB0)設(shè)置為輸出,其它PB1-7為輸入。
DDRB為AVR的端口設(shè)置寄存器。
B、 從端口PORTB中讀入狀態(tài),用如下方式:
Unsigned Char a=PINB; //讀入端口PORTB的狀態(tài)。若端口PORTB的狀態(tài)如下:
PB0為高電平1
PB1為低電平 0
PB2為高電平 1
PB3為高電平 1
PB4為高電平 1
PB5為低電平 0
PB6為低電平 0
PB7為高電平 1
則有a = 0b1001 1101 = 0x9D
C、 向端口PORTB寫(xiě)狀態(tài)(設(shè)置狀態(tài)):若要裝PORTB第0位和第2位置1(高電平)。
DDRB=0;//PORTB全部為輸出。
PORTB=0x03; //0b0000 0101
D、 而更多的情況,我們是要將端口的某一位改變狀態(tài),而不是對(duì)整個(gè)端口操作?;蛑幌胫蓝丝诘哪骋晃坏臓顟B(tài)如何的?那么如何來(lái)做呢?
例如:
將PB4置1,PORTB=PORTB | 0x10; //0x10=0b0001 0000
將PB4置0,PORTB=PORTB & 0xEF; //0xEF=0b1110 1111
將PB4置翻轉(zhuǎn),PORTB=PORTB^0x10; //0x10=0001 0000
檢驗(yàn)PB4的狀態(tài),char a=PINB & 0x10; //如果PB4為1,是a>0,否則a=0
當(dāng)然,上面寫(xiě)法對(duì)C語(yǔ)言來(lái)說(shuō),簡(jiǎn)直就是垃圾代碼了。C語(yǔ)言有它自己的方式,
例如:
PORTB |= 0x10;
PORTB &= 0xEF;
PORTB ^=0x10;
If (PINB & 0x10){ 你的語(yǔ)句; }
是否感覺(jué)到比較簡(jiǎn)潔???!
E、 當(dāng)然avr-gcc也提供了兩個(gè)函數(shù)對(duì)操作位,如:sbi (PORTB,4); cbi (PORTB,4);分別將PB4置1和清零。
2、 變量的類型
char
unsigned char
short
unsigned short
int
unsigned int
long
unsigned long
long long
unsigned long long
float
double
void
等等等等,這就請(qǐng)讀者自己看資料了。
3、 程序控制語(yǔ)句,C語(yǔ)言提供了非常豐富的程序流程控制語(yǔ)句。
i. 循環(huán)語(yǔ)句
A、 For(;;)語(yǔ)句,如:
for(i=0;i<8;i++){
循環(huán)體;
} //本例循環(huán)8次。
注意!for語(yǔ)句是先比較后加減的。
B、 While(exp)語(yǔ)句,如:
i=0; While(i<8){
循環(huán)體;
i++;
} //本例循環(huán)8次。也是先比較后執(zhí)行循環(huán)體的。
C、 Do while語(yǔ)句,如:
i=0;
do{
i++;
循環(huán)體;
}while(x<8);
//本例循環(huán)7次,因?yàn)樗窍葓?zhí)行后比較的語(yǔ)句。因?yàn)閕++在第一次比較時(shí)i已經(jīng)是1了。
ii. 分支語(yǔ)句。
A、 if語(yǔ)句,大名鼎鼎語(yǔ)句了,幾乎所有編程軟件都有它的身影。沒(méi)什么好說(shuō)的。
B、 switch語(yǔ)句。等
好了,這些就不說(shuō)下去了,因?yàn)槿绻氵B這些都不清楚。你該做的是找本C教程吧。
4、 中斷服務(wù)控制(SIGNAL)
voidUART_Init(void){ //中斷初始化函數(shù)//
UART_Ready = 1;
UART_ReceivedChar = 0;
pUART_Buffer = 0;
outp(BV(RXCIE)|BV(RXEN),UCR); // 允許串行接收中斷 //
outp( (u08)UART_BAUD_SELECT, UBRR); // 設(shè)置UART波特率 //
sei(); // 打開(kāi)全局中斷 //
}
SIGNAL(SIG_UART_RECV){ //串口接收完