采用MAXQ610評估套件(EV kit)和IAR嵌入式工作臺進行設計
摘要:應用筆記介紹怎樣面向MAXQ610低功耗RISC微控制器開發、構建并調試應用程序。文章使用了IAR?系統公司提供的IAR Embedded Workbench?工具箱和C編譯器。
引言
MAXQ610是Maxim Integrated Products提供的低功耗微控制器,設計用于電池供電的應用,提供低電流工作模式(1MHz時的典型值為1.4mA,12MHz時為3.5mA),以及低電流停止模式(典型值200nA)。微控制器還具有效率非常高的16位單周期RISC處理器核以及靈活的時鐘配置,有助于動態控制性能和功耗。MAXQ610適合于需要大量I/O引腳以及對功耗要求比較高的應用。
MAXQ610具有很多重要的特性,包括:
- 1.7V至3.6V的寬范圍工作電壓
- 64KB應用程序(IAP)閃存
- 2KB數據SRAM
- SPI?和兩個USART
- 8kHz低功耗“異或”喚醒定時器
- IR載頻發生器和調制
- 擾碼功能可防止攻擊者下載軟件,提供IP保護
- 存儲器保護功能隔離了內核庫,提供IP保護,防止第三方應用
MAXQ610評估套件(EV)為MAXQ610處理器開發低功耗應用提供成熟可靠的平臺。套件包括IR發射器和接收器;兩個串口;用于用戶輸入的8個按鍵;出于應用目的的4個LED;原型區;以及用于訪問MAXQ610所有I/O引腳的插頭等。此外,還提供跳線,可以方便地監監MAXQ610處理器在工作時的實際功耗。
設置MAXQ610評估套件
MAXQ610評估套件電路板如圖1所示。評估套件含有下面的硬件元件,這些元件用于實現并驗證本應用筆記中的演示程序:
更詳細的圖(PDF, 284kB)
圖1. MAXQ610評估套件
MAXQ610評估套件電路板和JTAG電路板都有很多跳線需要進行配置。在本應用筆記中,應按照表1和表2配置這些跳線。
表1. MAXQ610評估套件的電路板跳線配置
Jumper(s) | State | Purpose |
JH1, JH2 | Don't Care | Control RS-232 level shifters FORCEON and active-low FORCEOFF inputs |
JH3, JH4 | Don't Care | Configure RS-232 transmitter inputs |
JH20, JH21 | Don't Care | Connect RS-232 receiver outputs to MAXQ610 signals |
JH18 | Don't Care | Connect RS-232 active-low INVALID input to MAXQ610 control pin |
JH5 | Connect Pins 1 (Square Pad) and 2 | Connects regulated voltage to MAXQ610 supply |
JH22, JH23, JH24, JH25 | Closed | Connects MAXQ610 port pins to LEDs |
JH15, JH16, JH17 | Don't Care | Connect IR circuitry to MAXQ610 pins |
JH26 | Closed | Uses power from JTAG connection to power the MAXQ610 board |
JH14 | Closed | Connects board power to MAXQ610 |
表2. JTAG電路板跳線配置
Jumper(s) | State | Purpose |
JH1, JH2 | Don't Care | External DTR used to control loading the on-board microcontroller. |
JH3 | Closed | Connects JTAG board's 5.0V supply to JTAG connector pin 8 (feeds target board). |
用JTAG電纜連接JTAG電路板和MAXQ610評估套件電路板。電纜上的紅條應連接至JTAG電路板上標有引腳9和引腳10的連接器一側,以及MAXQ610評估套件電路板上標有TDI-GND的連接器一側。
用9針串行電纜連接PC和JTAG電路板(不要將其連接至MAXQ610評估套件電路板)。最后,將5V電源連接至JTAG電路板的電源連接器。
采用IAR編譯器開始設計:blinker
我們不以“Hello World”開始,而是構建一個簡單的應用程序,該應用程序使MAXQ610評估套件電路板上的4個LED閃爍(例如,DS1、DS2、DS3和DS4)。我們要使用的工具包是IAR嵌入式工作臺,由IAR系統公司提供。本應用筆記的軟件采用IAR系統公司2.12版KickStart試驗包來編寫并進行了測試。
在開始一個新工程之前,需要將一些MAXQ610特殊文件復制到IAR安裝目錄(通常是C:\Program Files\IAR Systems\Embedded Workbench 4.0,下面將其稱為[IAR])中。網上提供本應用筆記的文件(請參考文檔最后的了解詳細信息一節),評估套件的CD-ROM也提供這些文件。請復制這里提到的這些文件:
- 將
iomaxq610.h
復制到[IAR]\MAXQ\inc
- 將
lnkmaxq610.xcl
復制到[IAR]\MAXQ\config
- 將
maxq610.sfr
復制到[IAR]\MAXQ\config
- 將
maxq610.ddf
復制到[IAR]\MAXQ\config
- 將
maxq610.menu
復制到[IAR]\MAXQ\config\devices
現在啟動IAR嵌入式工作臺。選擇“Create new project in current workspace” (圖2)。選擇MAXQ?工具鏈,確定選擇了“Empty project” (圖3)。單擊OK,打開一個文件對話框。在這個例子中,工程文件名為“blinker” (圖4)。
圖2. 工作臺啟動
圖3. 建立一個空的工程
圖4. 如圖所示,保存工程“blinker”
工作空間將顯示“blinker”工程。現在,建立一個新文件(File New File),將以下文本復制到該文件中。
#include#include void main() { /* * Try to get a 1Hz blink on the LEDs. System clock = 12MHz. * Timer reload = 0x5B8D = 23437. Running at div 256, so we get a timer * interrupt once every 23437*256 cycles = 5,999,872, or roughly 500ms. * We toggle every 500ms, so we get a 1Hz cycle. */ TB0R = 0x5B8D; // reload for timer 0 TB0CN = 0x0416; // timer set to run, enable interrupt, down count, div 256 PD3 = 0x0f; // set port 2 lower nibble to output IC_bit.IGE = 1; // set global interrupt enable while (1) { } }
在這個簡單的應用程序中,采用一個定時器中斷來啟動使評估套件LED不斷接通和關斷的代碼。要重新裝入的值在定時器寄存器中斷時自動裝入該寄存器,大約每500ms周期性中斷一次。設置定時器運行之后,將連接LED的端口引腳配置為輸出,然后,全局使能中斷。應用程序進入無限while循環。中斷服務例程(ISR)代碼完成應用程序(請參見下面圖5)。
單擊save,將文件命名為main.c
(確定代碼保存目錄與您建立新工程的目錄相同)。在工作窗口下,右鍵單擊“blinker”,選擇Add Add main.c
。
下一步,將另外兩個文件從軟件分配源復制到您的工程目錄中:isr.c
和clib.r66
。C文件含有中斷部分,編譯器需要利用它來編譯程序。r66文件含有應用程序運行需要的啟動代碼和標準庫代碼。每次開始新的MAXQ610工程時,都需要重復這一復制步驟。
再次右鍵單擊工作窗口中的“blinker”行,找到Add Add Files,選擇isr.c
。
現在,需要配置工程選項。選擇Project Options,打開選項窗口。請按照以下步驟進行:
- 在General選項下:Target,選擇MAXQ610。
- 在General選項下:Library Configuration,從下拉菜單中選擇Custom CLIB。瀏覽Library File文本區,選擇剛剛復制到工程目錄中的
clib.r66
文件。 - 在Debugger下:Setup,從driver下拉菜單中選擇JTAG。
- 在JTAG下:輸入您將使用的連接JTAG電路板的串口。
現在,構建應用程序就非常簡單了。按下F7或者選擇Project Make。您首先會被詢問保存工作空間。對此,請輸入“gettingstarted”。工程應該被正確構建。
如果您希望在此處運行應用程序(例如,Project Debug,然后單擊右箭頭按鈕),電路板上不會有任何事情發生。這是因為應用程序代碼試圖使用定時器中斷來確定LED什么時候應該改變,而定時器的ISR中沒有代碼。因此,必須為定時器(ISR)編寫代碼。
打開文件isr.c
,找到函數isr6(void)
,在它旁邊應該有注釋//timers
。在函數中輸入以下代碼:
TB0CN = TB0CN & 0xFF7F; // clear timer 0 interrupt PO3 = PO3 ^ 0x0f; // toggle lower nibble
這些代碼首先清除定時器中斷標志(必須由軟件清除中斷標志,否則,將導致中斷矢量不斷啟動)。第二行觸發所有4個LED,這些LED連接到端口引腳P3.0至P3.3。
現在開始構建工程,進行調試(Project Debug把您帶到執行C代碼的第一行,如圖5所示)。代碼第一行下面高亮顯示,左側空白區有一個箭頭,指示程序在此暫停。現在,單擊Run按鈕(圖6)。該按鈕使程序運行至結束(或者到下一個斷點)。當程序執行無限循環時,LED塊在一直閃爍。
圖5. 程序在代碼第一行暫停
圖6. 程序Run按鈕
使用IAR嵌入式工作臺調試應用程序
現在,我們看一下MAXQ610和嵌入式工作臺工具的調試功能。MAXQ610處理器有內置JTAG引擎,支持在實際芯片中進行調試。這一特性還避免了使用昂貴的模擬器或者有可能出錯的仿真器。
返回到最初的blinker應用程序,開始上面介紹的調試過程。第一行高亮顯示后,點擊Go按鈕,繼續執行。您將看到LED接通500ms,然后關斷500ms。
單擊Break按鈕,或者選擇Debug Break,暫停執行(圖7)。程序應暫停在while(1)
聲明上,這是因為該聲明占用了無限循環的大部分運行時間,而中斷矢量只占用了很少的時間(每500ms只有幾個周期)。
圖7. Break按鈕
在檢查一些處理器寄存器中的數值時,打開寄存器窗口(View Register)。此處,從下拉菜單中選擇Timer 0,您將看到與定時器控制閃爍LED相關的寄存器(圖8)。這里顯示的Timer 0寄存器包括重裝寄存器(TB0R),控制寄存器(TB0CN),計數寄存器(TB0C)和數值寄存器(TB0V)。
圖8. Register窗口顯示Timer 0寄存器
作為演示,我們將執行幾行代碼,觀察這些定時器寄存器會有什么變化。按下Step Over按鈕幾次(圖9),或者選擇Debug Step Over。觀察TB0V中的數值。Step Over按鈕執行一行C代碼,但是不會進入任何函數調用。該按鈕按下時,您將看到TB0V中的數值變化范圍很大,這是因為調試引擎執行時,定時器在不斷運行。您還將看到,TB0CN寄存器隨著定時器中斷出現和結束的變化。
圖9. Step Over按鈕
寄存器窗口不但顯示了寄存器內容,而且,在調試進程中,還可以向其寫入數值。程序暫停時,雙擊TB0R寄存器中的數值。將寄存器改為0x2DC6
(這是0x5B8C/2
),然后,單擊Go按鈕。LED現在閃爍應比以前快兩倍,這是因為定時器重新裝入的計數值減小了,從而減小了定時器中斷之間的時間。
在另一個演示中,我們把光閃爍模式由全通/全關(1111 0000 1111
)改為交替模式(1010 0101 1010
)。而這種改變并不需要重新編譯程序。首先,我們必須加入一個斷點。程序運行時,打開isr.c
文件,找到定時器中斷矢量。雙擊代碼第一行左側的灰色區,將出現一個紅色X。這一X表示加入了一個斷點。當程序執行到這一行代碼時,程序將停止,其屏幕顯示如圖10所示。綠色箭頭和高亮顯示的代碼表示已經到達斷點,程序暫停在這里。
圖10. 斷點設置和到達斷點
在寄存器窗口中,從下拉列表中選擇Port I/O。注意,代碼使用了XOR (^)運算符來觸發端口3 (P3)最下面的4個引腳,而這些引腳從未明確設置。為改變這一操作,單擊PO3中的數值,輸入新值0x05
。輸入后,您將看到,按照0101的模式,2個LED接通,2個LED關斷。現在,單擊Run。程序開始運行,直至到達斷點而再次停止,LED將轉換狀態,因此,處理器現在輸出1010
模式。雙擊紅色X,清除斷點,然后,單擊Go。程序將以交替LED模式不斷運行。
在IAR嵌入式工作臺中,您可以按照與寄存器一樣的方法來觀察并改變變量值。對此進行演示時,單擊Stop或者選擇Debug Stop Debugging,停止應用程序。現在,修改代碼,在主函數中加入變量x,在while循環中嵌入延時循環。如下所示,輸入對程序的一些修改。注意,在代碼中故意設置了錯誤,稍后對它進行討論。
void main() { /* * Try to get a 1Hz blink on the LEDs. System clock = 12MHz. * Timer reload = 0x5B8D = 23437. Running at div 256, so we get a timer * interrupt once every 23437*256 cycles = 5,999,872, or roughly 500ms. * We toggle every 500ms, so we get a 1Hz cycle. */ long int x; TB0R = 0x5B8D; // reload for timer 0 TB0CN = 0x0416; // timer set to run, enable interrupt, down count, div 256 PD3 = 0x0f; // set port 2 lower nibble to output IC_bit.IGE = 1; // set global interrupt enable while (1) { for (x=0;x<100000;x++) { if (x==100000) PO3 = PO3 ^ 0x01; } } }
這些改變用于偶爾觸發端口3最下面一個引腳,因此,3個LED同步閃爍,而1個將獨立閃爍。延時循環間隔并不重要,但是必須提供足夠的延時才能觀察到結果。運行該應用程序(開始調試,然后,運行),您將很快看到和最初的應用程序并沒有什么不同;所有LED以1秒的間隔同時接通和關斷。暫停應用程序,打開本地變量觀察窗口(View Locals)。如果程序停在主應用程序的while循環(很有可能)中,窗口中將顯示變量x (圖11)。
前面曾提到上面的代碼中有錯誤。現在,按下Step Over按鈕幾次,您將看到執行從循環對比(x<100000
)跳到條件測試“if”聲明(x ==100000
),直到遞增(x++
),然后是本地窗口中x值的變化。在PO3 = PO3 ^ 0x01
99999
,單擊Step Over幾次。您將注意到,由于x=0
部分被執行,“for”循環終止,然后再次開始。問題很明顯—x值永遠不會到達“for”循環中的100000,這是因為進行了“less than”測試。停止程序,將“if”聲明中的對比值改為99999
。重新編譯程序,啟動調試器,單擊Go。LED開始閃爍,LED DS1自己獨立閃爍。
圖11. 本地變量窗口
評論
查看更多