問:我想使用AVR單片機中的Mega 系列,有哪些開發工具支持這種單片機?
答AVR 單片機 中的Mega 系列有一套完善的開發工具評估/編程板,
ATMEL 的STK500(980 元/套)起步工具包是適用于開發Atmega103 芯片的對芯片的編程是通過在系統編程(ISP)接口完成的
C 編譯器:
所有的C 編譯器均已在ATMEL 網站上有關第三方工具供應商的網頁上列出;ATMEL 公司在它的網站:http://www.atmel.com 上還提供了許多自由軟件它們可用于對AVR 單片機 的程序進行匯編和模擬這些軟件可以自由下載,上述產品也可通過ATMEL 授權的地區分銷商和銷售代理獲得。
問:有哪些支持AVR 的起步工具包
答STK100,SL-AVR,SL-OKAVR,SL-AVRL 支持AVR 的Tiny 系列 單片機
STK200,SL-AVR,SL-OKAVR,SL-AVRL 支持AVR 單片機 即AT90S 系列
STK300,SL-AVR,SL-OKAVR,SL-AVRL 還支持AVR 的Mega103 單片機 。
STK500,SL-AVR,SL-OKAVR,SL-AVRL 還支持AVR 的Mega103 單片機
所有的起步工具包都包括按鈕LED指示燈RS232 通信接口I/O 口通過分布在PCB板邊沿的連接插頭可以使用STK200/300 起步工具包還有一條在線編程ISP 電纜它可用以對AVR芯片編程STK300 還提供了AVR 應用程序生成器可用來生成外圍設備的初始化代碼
問: 即使看門狗沒有使用我也有時在AVR Studio 調試軟件的狀態欄中看到“WDT reset” WDT 復位的信息這是為什么?答當目標器件運行在較高的頻率大于6 MHz)時來自扁平電纜FPC 電纜的噪聲信號可能錯誤地觸發WDT 復位檢測電路這對程序的仿真和執行沒有影響它們不會由于噪聲的原因而產生復位噪聲僅僅影響AVR Studio 調試軟件的信息處理在這種情況下不要理睬這個信息當目標器件運行在較低的頻率小于或等于4 MHZ 時應該不會出現這個問題
問: 我剛買了一臺ICE 200 仿真器在使用不同的芯片和不同的時間運行診斷程序時都是失敗的而其它一切正常這是什么原因?
答在ICE200 仿真器的第一批產品中是一個固件監控程序的問題而導致這個現象這個現象可以通過升級新版本的監控程序來修正當使用2.02 版或更高版本的AVR Studio 軟件時AVRStudio 將讀取固件版本并檢查這個問題如果你的ICE200 需要升級它會引導你完成升級處理這個檢查工作只有在裝載應用程序時才能被執行而當運行診斷程序時是不被啟動的如果你首先嘗試運行診斷程序診斷仿真器診斷程序不會檢查固件版本并且可能診斷失敗如果你碰巧有這種情況不要理睬診斷失敗而直接去裝載應用程序這時你將可以升級ICE200 的監控程序在升級后再回過來運行診斷程序診斷結果應該全部是正確了(注現在銷售的ICE200 已沒有這個問題了)
問:如何檢查我的AVR 仿真器的版本號?
答在仿真器被連接的時候打開AVR Studio 程序選擇菜單中Help-》About-》Info 來獲得你的仿真器的有關信息AT90ICEPRO 在1.20 之前的版本和ATmegaICE 在1.11 之前的版本是不能被AVR Studio 軟件檢測到的較新的版本已經有了而且可以從Atmel 網站自由下載。
問:程序在仿真器或 單片機 中不工作,而在模擬器中看來工作很正常這是什么原因?
答這是堆棧指針設置中的常見問題對所有帶SRAM 的AVR 單片機 堆棧指針必須設置在SRAM最后的地址
在匯編程序中這樣做是正確的
ldi R16 low(RAMEND) 裝載堆棧指針的低字節到R16
out SPL R16 輸出這個數值到堆棧指針寄存器
ldi R16 high(RAMEND) 裝載堆棧指針的高字節到R16
out SPH R16 如果AVR 的SRAM 小于256 字節就將這行注釋掉
在C 程序中堆棧指針是在啟動代碼中自動設置的注意鏈接文件(XCL 文件)定義了堆棧指針的位置請參考應用筆記AVR032 ---- C 編譯器的鏈接文件”
問:從哪里我能找到完整的AVR 指令集?
答指令集在Atmel 的網站的Products-》AVR 8 bit RISC-》Datasheets 下面的網頁上或者直接連接http://www. atmel.com/atmel/products/prod200.htm網頁; 《》附錄
3 AVR 指令速查表
問:當開始做一個使用AVR 單片機 的新項目時最常見最共同問題有哪些?
答最常見最共同的錯誤是忘記對不帶硬件堆棧的芯片設置堆棧指針對AT90S8515 單片機 上這樣做是妥當的
LDI R16 low(RAMEND)
OUT SPL R16
LDI R16 high(RAMEND)
OUT SPH R16
注在ATMEL 的匯編語言源程序中經常將R16 寄存器用temp 符號來代替
另一個常見的錯誤是將端口作為輸出使用時忘記設置端口在AVR 單片機 中設置端口作為輸出使用是通過寫一個1 到數據方向寄存器(DDR)中完成的比如設置端口PORTB輸出高電平
LDI R16 0xFF 裝載十六進制數FF 到寄存器R16
OUT DDRB R16 設置端口PORTB作為輸出使用
OUT PORTB R16 設置端口PORTB輸出高電平
使用AVR 匯編器時第三個常見的錯誤是在使用裝載程序存儲器(LPM)指令時指向了程序存貯器中錯誤的地址AVR 的程序存貯器是組織成字16 bit 的形式而LPM 指令是讀取字節8bit LPM 指令可以讀16 位字的高位字節或低位字節中的任意一個因為這個原因必須將16 位的程序存貯器地址分解成兩個指向你所希望裝入的字節的地址
問:我在AT90ICEPRO 中使用回溯(Trace 功能選項感覺很困難好象每次都不能啟動回溯功能為什么?
答: 讓我們假設你在地址0x20 處停止仿真如果你現在設置啟動回溯功能的觸發地址是同一個地址即也是0x20 那么在程序重新到達0x20 之前的回溯功能是無效的原因是觸發條件與斷點信息應該在指令之前裝入AVR 核中所以盡管指令和觸發條件在0x20 地址但對在這之前裝入AVR核中的指令沒有任何效果如果你設置觸發條件為一個程序還沒有到達的地址應該不會有任何問題
問: Mega103/603 微控制器的哪些引腳用于在線編程(ISP)?
答Mega103/603 微控制器用于在線編程界面的引腳如下列
SCK- SCK (PB1PIN11)
MISO - PDO (PE1 pin 3)
MOSI - PDI (PE0 pin 2)
RESET- RESET (RESET pin 20)
PEN(編程使能)引腳和RESET 引腳可以選擇其中一個使用這兩個引腳有同樣的功能它們都激活內部iRESET 信號) 但PEN 引腳只有在上電時(VCC大約1.2V)被讀取如果PEN 引腳不使用推薦將此引腳接VCC 所有其它型號的AVR 單片機 都是使用RESET 引腳來允許使能串行編程的
問:我不能使用AVR 仿真器正確地驅動外部負載當我使用電壓表來測量仿真器POD 上的引腳時好象引腳不能驅動負載這是什么錯誤?
答這是1.21 版的ICEPRPO 和1.10 版的MegaICE 存在的問題,可用于仿真器升級的新版本軟件可以從http://www.atmel.com網站的products-》AVR 8bit RISC-》SOFtware 網頁中下載
為升級ICEPRPO 的版本到1.22 版請下載UPGRD122.ZIP 文件
為升級MegaICE 的版本到1.11 版請下載M111UPGR.ZIP 文件
這些文件是壓縮文件它包括了一個適用于仿真器的新的程序文件和一個PC 程序PC 程序可以用來對代碼檢查和對仿真器自動升級
問:我使用了帶A/D轉換器的AVR 單片機 單片機工作非常好我也喜歡AVR 的速度但我有一個問題當我改變A/D 轉換器的輸入通道時好象A/D 轉換器讀取的數據仍然是上一個通道的,如果我第二次讀我又得到正確的數值為什么會出現這件事?
答A/D 控制和狀態寄存器ADCSR 中有兩個位是用來檢測A/D 轉換的結束的當一個新的轉換啟動時ADSC 啟動轉換控制位是用于測試的不管是否準備就緒前一次的轉換結果仍然被送入A/D 數據寄存器當讀取A/D 數據寄存器時讀到的自然仍是上一次的轉換結果
為了得到最近的轉換結果應該測試A/D 中斷標志位ADIF 或使能全局中斷并且在中斷服務程序中讀取
例子代碼
ldi R16 1 選擇通道
out ADMUX R16
sbi ADCSR adif 復位中斷標識
sbi ADCSR adsc 開始A/D 轉換
wait sbis ADCSR adif 等待直到ADIF 已經置位
rjmp wait
問:當將一個文件裝入AVR STUDIO 時它始終使用我第一次使用過的文件工作這是什么錯誤?
答AVD 文件包含了有關窗口設置和當前目標文件的信息有時由AVR STUDIO 創建的AVD文件可能被破壞根據文件破壞部位的不同會出現不同的現象當運行AVR STUDIO 過程中出現奇怪問題時首先應嘗試刪除位于存放源代碼的文件夾中護展名為avd 的文件
問:在AVR 系列中如AT90S2313 單片機 全部數據存儲器不超過256 字節而且它不能訪問外部存儲器能否忽略X Y 和Z 指針的高位字節而僅使用指針的低位字節來訪問可以使用的存儲器?
答在全部數據存儲器寄存器I/O 寄存器和SRAM 少于256 字節的AVR 單片機 中當使用
LD/ST 指令訪問數據存儲器時CPU 將忽略指針的高位字節這時允許每個指針的高位字節(R27、R29 和R31)用于普通的儲存用途自增和預減指令(如LD -Z Rd)不會影響高位字節注意當使用Z 指針訪問FLASH 程序存儲器和使用ADIW/SBIW 指令時將影響使用的Z 指針的高位字節
問在IAR C 編譯器中怎樣才能訪問AVR 內部的EEPROM 數據存儲器
答AVR 內部的EEPROM 是AVR 微控制器I/O 存貯器的一部分以I/O 接口形式訪問不能使用普通變量進行訪問IAR 在標準庫例程“ina90.h”中定義了特殊的宏來讀寫EEPROM
讀寫EEPROM 的宏有下列原形
_EEGET(VAR ADR) /* 從EERPOM 的地址ADR 讀取數值*/
_EEPUT(ADR VAL) /* 寫VAL 到EERPOM 的地址ADR *
IAR C 編譯器不支持將常量定義到EEPROM 中不能生成EEPROM 的初始化數據文件
用AVR 匯編器來做這件事是很容易的先寫一些定義EEPROM 中常量的代碼
.ESEG
.org 0x50
datatable: .db $01,$02,$03,$04,$05
dtableend: .db $00
當這段代碼被匯編后它產生一個.EEP 文件這個文件可以被下載到微控制器MCU 或仿真器中這個.org 聲明給出數據的地址這個變量在C 編繹器中可以用_EEGET()和_EEPUT()進行訪問
問:我無法使MCU 在掉電模式時消耗的電流下降到數據簿中的值我應該怎么做?
答當AVR 進入掉電模式時I/O 引腳的狀態應該是不變化的如果你有一些未連接引腳是三態輸入并且沒有上拉這些引腳的電平是浮動的并且很可能引起振蕩從而導致額外的電流消耗為解決這種問題應該激活所有未連接的輸入引腳的上拉電阻這會使這些引腳具有一個明確的邏輯電平在由于引腳振蕩而產生這個問題的例子中在活動模式非休眠狀態打開未使用引腳的上拉是一個好方法
其次你再查看一下連接到輸出引腳的接線任何輸出引腳上的負載都會在掉電模式時消耗額外的電流
問:我觀察到我現有的微控制器在上電過程中I/O 端口是活動的在我的應用中有一個問題系統一旦設定I/O 引腳中的一個為高電平MCU 可以關閉電源而即使用一個電阻把該引腳電平拉低在上電過程中它有時仍然出現高電平因此當電源打開時系統立刻關閉在使用者看來系統不能工作如果我換成AVR 我猜想會有一些同樣的問題?
答大多數微控制器是同步復位比如在RESET 尚未完全完成時MCU 需要一定數量的有效時鐘在上電過程中當VCC 上升到啟動晶體振蕩器的數值之前上電復位是有效的但不能影響I/O引腳的數值而且I/O 引腳是處于隨機狀態AVR 的I/O 端口與復位是異步的而且保證在整個上電過程中是處于三態換成AVR 單片機 將可以解決你的問題
問:怎樣處理AVR 微控制器的NC 引腳空引腳?
答不要將任何線路連接到NC 引腳NC 引腳是為將來的需用而保留的
問:在AVR 匯編器中怎樣定義字符串常量
答字符串可以作為常量定義在FLASH 存儲器或EEPROM 數據存儲器中
例如在FLASH 中定義一個字符串常量
.CSEG
fstring .db “This is a string in flash” 0x00
在EEPROM 中規定一串常量:
.ESEG
eestring .db “This is a string in EEPROM” 0x00
問:我正在編寫一個很大的匯編程序當我往程序中加入新的行時文件末尾的字符好象消失了我怎樣才能防止這種現象?
答: 匯編器的編輯器有30K 字節的文件尺寸限制如果要克服這個限制文件必須被分成幾個模塊并用“.include”鏈接還有一種方法使用其它編輯器如NotePad UltraEdit 程序等和命令行方式工作的匯編器(DOS 版本)
問:AT90S8515 有8KB 的程序存儲器由于RJMP 和RCALL 指令只能在2K 的相對范圍內跳轉而這個部件的指令集沒有JMP 或CALL 指令我怎樣做才能跳轉到全部的程序存儲器中
答程序存儲器是組織成4Kx16 的形式的所以只有4K 的程序存儲器地址空間在匯編器中選擇“Options 》》 Wrap Relative Jumps”選項這時將允許你跳過程序存儲器的邊界例如如果你從$FFE至$00A 做一個相對跳轉程序計數器將被增加12 并且隱藏了程序存儲器的邊界這個功能只能用在8K 的 單片機 4K 的單片機不需要隱藏邊界16K 的單片機需要使用JUMP 和CALL 指令。
問:當我使用UART時定時/計數器的任意一個是否都可用于產生波特率?
答不對有一個專用的定時器被UART 用來產生波特率所有定時/計數器只可以用作普通用途
問:怎樣才能從外部將AT90S1200 從掉電模式下喚醒?
答要從掉電模式喚醒AT90S1200 你必須使能外部INT0 中斷并且是低電平觸發中斷當你以掉電模式進入休眠狀態時如果INT0 引腳上低電平的保持時間大于16384 個內部RC 振蕩周期時AT90S1200 將被喚醒內部RC 振蕩器是用于延時MCU 的啟動直到XTAL 振蕩器工作穩定參考AT90S1200 數據簿RC 振蕩器的頻率是受VCC 電壓影響的
問:當我使用SBI 和CBI 指令來設置或清除I/O 端口的一個信號位時是否會影響同一端口的其它位?
答不會不像多數 單片機 那樣在AVR 單片機中允許你100%安全地操作I/O 端口的信號位這也適用于整個端口的操作有疑問可參考每個I/O 端口的三個地址
問:為什么每個I/O 端口有三個地址?
答為使你能建立100%安全的系統AVR 支持真正的讀-修改-寫I/O 端口如果你希望讀取I/O引腳的物理電平讀PIN 寄存器當你希望改變輸出時讀PORT 鎖存能確保正確的數據寫回到端口保證全部輸出這種方式始終能給出你所希望的結果而不依賴于引腳的物理電平這個特點使你省去了為建立一個安全的系統而拷貝你的端口數據進入存貯器的所有工作這個工作使用了許多指令當你使用SBI 和CBI 指令來設置/清除I/O 端口的信號位時必須始終使用PORT 的地址
問:為什么SBI 和CBI 指令只能對$00 -$1F的I/O 寄存器進行操作?
答所有AVR 指令中除少數外都為兩個字節長度這也意味著只有65,536(64K)種可能的組合來安排指令集當我們指定AVR 指令集時采取一些折衷的辦法是為了盡可能充分地利用這64K 種組合不像CISC 微控制器指令可以是一個兩個三個或更多個字節在AVR 結構上我們不能實現全部指令都象這樣作為例子在一個立即尋址而且包含全部32 個寄存器地址的指令中常數需要8 位而寄存器地址需要另外的5 位這種指令將占用全部指令組合空間中的8K 換句話講我們只能安排八個這樣的指令而沒有更多的指令能夠實現如果做一個17 位長度的指令是不經濟和不方便的方案不會被考慮在設計AVR 指令集的過程中設置我們聽取了許多建義我們請教了C 編譯器專家他們在如何調整指令集來適應C 編譯器方面提出了許多意見作為例子編譯器專家建議我們為SBCI 帶進位的立即數減法犧牲ADDI 指令
對那些缺少的指令操作也是方便的AVR 的代碼效率應該能證明我們已經找到一種在實現的指令和省略的指令之間進行折衷的好辦法
問:為什么立即尋址指令在寄存器R0-R15 中不能工作?
答所有AVR 指令中除少數外都為兩個字節長度這也意味著只有65,536(64K)種可能的組合來安排指令集當我們指定AVR 指令集時采取一些折衷的辦法是為了盡可能充分地利用這64K 種組合不像CISC 微控制器指令可以是一個兩個三個或更多個字節在AVR 結構上我們不能實現全部指令都象這樣作為例子在一個立即尋址而且包含全部32 個寄存器地址的指令中常數需要8 位而寄存器地址需要另外的5 位這種指令將占用全部指令組合空間中的8K 換句話講我們只能安排八個這樣的指令而沒有更多的指令能夠實現而做一個17 位長度的指令是不經濟和不方便的方案不會被考慮在設計AVR 指令集的過程中設置我們聽取了許多建義我們請教了C 編譯器專家他們在如何調整指令集來適應C 編譯器方面提出了許多意見作為例子編譯器專家建議我們為SBCI 帶進位的立即數減法犧牲ADDI 指令
對那些缺少的指令操作也是方便的AVR 的代碼效率應該能證明我們已經找到一種在實現的指令和省略的指令之間進行折衷的好辦法
問:為什么沒有EORI 指令?
答所有AVR 指令中除少數外都為兩個字節長度這也意味著只有65,536(64K)種可能的組合來安排指令集當我們指定AVR 指令集時采取一些折衷的辦法是為了盡可能充分地利用這64K 種組合不像CISC 微控制器指令可以是一個兩個三個或更多個字節在AVR 結構上我們不能實現全部指令都象這樣作為例子在一個立即尋址而且包含全部32 個寄存器地址的指令中常數需要8 位而寄存器地址需要另外的5 位這種指令將占用全部指令組合空間中的8K 換句話講我們只能安排八個這樣的指令而沒有更多的指令能夠實現而做一個17 位長度的指令是不經濟和不方便的方案不會被考慮在設計AVR 指令集的過程中設置我們聽取了許多建義我們請教了C 編譯器專家他們在如何調整指令集來適應C 編譯器方面提出了許多意見作為例子編譯器專家建議我們為SBCI 帶進位的立即數減法犧牲ADDI 指令
對那些缺少的指令操作也是方便的AVR 的代碼效率應該能證明我們已經找到一種在實現的指令和省略的指令之間進行折衷的好辦法
問:我用“sbr r30,3”指令在寄存器30 中設置D3 位好象對D3 位不起作用但D0 位與D1 位可以被設置我的做法在哪里有錯誤?
答“SBR” 可以用來在一個寄存器中同時設置多位(象“CBR”可以用來同時清除寄存器中的多位)指令的第二個參數不是指定位號而是用來與寄存器中的數作邏輯或運算在這個例子中$03 與R30 的內容相或所以導致最低的兩位置位為了只設置D3 位應嘗試下列方法的一種
sbr r30 $08
sbr r30 0b00001000
sbr r30 (1《《3)
上面三行都會產生同樣的結果你可以選擇一個你最習慣的用法
問:在我的多任務系統中除了中斷標志以外我還需要定義可以設置和清除的標志我應該怎樣做?
答每個標志使用一個寄存器為了設置標志用
ldi flag 01
或者如果你想使用低位的寄存器(R0-R15) 在復位后先清除它然后用
inc flag
來設置標志
當檢查和清除標志時這樣做
lsr flag 移動標志到進位標志位(標志清除)
brne flag_was_set 如果標志被設置就跳轉
象在你所有的中斷例程中一樣在退出之前要恢復狀態寄存器這種方式十分安全
問:在AT90S1200 中如何實現常數表功能?
答由于AT90S1200 沒有LPM 指令比較有效的方法是將一個較小的常數表放置在EEPROM 中你可以使用EEPROM 地址寄存器和EEPROM 數據寄存器有效地直接訪問常數表如
.ESEG 定義EEPROM 段
.db my_var00=$45
.db my_var01=$4c
.db my_var02=$5f
.CSEG 定義通用代碼段
如果你的表不適合于放置在EEPROM 中你可以象下面這樣放置在FLASH 中
.def tp =r16 表指針表索引
.def output=r17 輸出表的中常數
table
ldi output,$45
cpi tp,01
breq end
ldi output,$4c
cpi tp,02
breq end
ldi output,$5f
cpi tp,03
breq end
end
ret
為了訪問表中的2 號元素可以這樣做
ldi tp 2
rcall table
當從表格子程序返回時“output”將包括“$4c”
問:在沒有ADDI 指令的情況下怎樣將一個常數立即數和寄存器的內容相加?
答一個較簡單的方法是減去一個負數下面的代碼是將寄存器R20 中和5 的相加的例子
subi r20 -5
注意無論如何在這種情況下進位標志位不能用于檢測溢出如果你已經將常數放入另一個寄存器你可以使用通用的ADD 指令如果常量是1 你能使用INC 指令來增加寄存器的值16 位的加法是同樣的下列代碼是將r17 r16 和$0b3c 相加的例子
subi r16 low(-$0b3c) 減去低位字節
sbci r17 high(-$0b3c) 減去高位字節
問:為實現指令的單周期運行是否對外部時鐘倍頻?
答沒有這個時鐘是MCU 真正使用的沒有使用時鐘分頻或倍頻電路
問: AVR 的一個指令周期使用了多少個時鐘周期?
答只有一個時鐘周期例如在寄存器中加入兩個數全部執行時間等于在XTAL1 引腳上的時鐘信號正半周加負半周的時間
問:為什么AT90S8515 稱8K 的MCU?
答大多數CISC 微控制器的指令是變長度的一些指令由單字節組成其它的指令也可以是四個字節長度大多數AVR 指令是兩個字節長度只有很少也是四個字節所以CPU 在啟動運行時不能每次只讀取和解釋一個字節而我們的代碼尺寸基準始終是和字節相比較的因此在80C51上填滿8K 的一個C 程序肯定也適合的8K 的AVR
問:我從哪里能找到數據簿?
答你可以從網站www.atmel.com有選擇地下載它們你也可從當地分銷商和ATMEL 辦事處得到數據簿你還可以發電子郵件到literature@atmel.com索取
問:AVR 有哪些超過我現有MCU 的附加性能?
答十分緊湊的代碼, 特別是對C 程序4-10 倍的高速度可編程FLASH 存儲器可在系統編程芯片內含EEPROM 存貯器可在系統編程低功耗
評論