看了開發板配套光盤中的非操作系統示例代碼,試著進行簡化,只留下最核心的啟動代碼,然后自己編寫makefile進行編譯,燒錄到開發板中進行實驗,總算成功了。第一個程序運行后只是簡單地讓4個LED輪流開啟關閉,雖然沒有看懂是怎么做到控制LED的,但看懂了系統啟動部分,而且把有點亂的代碼整理得整齊了些;第二個程序運行后可以從串口輸出文本,這對以后的進一步學習很重要,因為串口輸出是很重要的調試手段(從顯示屏輸出文本太復雜,不是初學者可以容易搞定的)。此外,看了《基于ARM的嵌入式系統開發與實例》,雖然第4章,第5章看得很暈,因為存儲器控制器比較復雜,書中講了好多硬件連接以及操作時序的問題,以前完全沒接觸過,基礎不夠,看不懂。但第6章和第7章講的中斷控制器和PWM定時器,看門狗定時器還是比較好懂的,然后結合S3C2440A用戶手冊,了解了S3C2440A與書中講的S3C44B0X的區別。把書中的例子改成可以在自己的開發板上運行的程序,燒錄進去,運行得與預期效果一致。 0 說明
本文引用地址:http://www.104case.com/article/201611/318885.htm 我用的開發板是mini2440,它采用的處理器是基于ARM920T的S3C2440A;而看的教材《基于ARM的嵌入式系統開發與實例》是以基于ARM7TDMI的S3C44B0X為例進行講解的。
1 中斷控制器
S3C2440A可以接受60個來自內部外設或者外部中斷引腳的中斷請求,多個中斷請求經過仲裁判優后向ARM920T核心發出IRQ或者FIQ請求。S3C2440A與S3C44B0X有幾處不同:
(1) 有些中斷請求是帶子寄存器的。這些請求先對子源中斷請求寄存器(SUBSRCPND)相應位置1,再通過子中斷屏蔽寄存器(INTSUBMASK),然后才能進入到源中斷寄存器(SRCPND)中,最后通過中斷屏蔽寄存器(INTMASK),再進行模式(INTMOD)和優先級(PRIORITY)判斷。在處理通過子中斷寄存器的中斷時,要記得清除SUBSRCPND的相應位。
(2)從用戶手冊上看,S3C2440A是沒有像S3C44B0X那樣的中斷控制寄存器的,不能選擇是使用向量中斷還是非向量中斷。書中講的IRQ向量模式寄存器應該是對應S3C2440A的中斷優先級寄存器,S3C2440A的優先級輪轉也比較好理解;至于中斷請求清除寄存器,S3C2440A好像是沒有對應的寄存器的。在這上面,S3C44B0X似乎復雜一些。
下面是來自S3C2440A用戶手冊的中斷處理過程圖:
2 PWM定時器
這方面S3C2440A與S3C44B0X沒有太大的不同,書中講的基本原理與定時器特性適用于S3C2440A。
3 看門狗定時器
除主時鐘輸入頻率不同外,S3C2440A與S3C44B0X沒有大的差別。
4 源代碼
(1)PWM定時器處理代碼
static int int_count;
static __irq void Timer0_Int(void)
{
Uart_Printf("nTimer 0 interrupt %d times",++int_count);
rSRCPND = BIT_TIMER0;
rINTPND = BIT_TIMER0;
}
void Timer0_Start(void)
{
int i;
rTCFG0 = 0xFF;// 定時器0,1的預分頻值為255
rTCFG1 = 0x2; // 定時器0的時鐘分割器采用1/8分頻
rTCNTB0 = 25600;
rTCON = 0x06;
for(i=0;i<1000;i++);
rTCON = 0x09;
pISR_TIMER0 = (unsigned int)Timer0_Int;
rINTMSK &= (~BIT_TIMER0);
}
(2)看門狗定時器處理代碼
static int int_count;
#define SUB_BIT_WDT (0x01 << 13)
static __irq void Watchdog_Int(void)
{
Uart_Printf("nWatchdog interrupt %d times",++int_count);
rSUBSRCPND = SUB_BIT_WDT;
rSRCPND = BIT_WDT_AC97;
rINTPND = BIT_WDT_AC97;
}
void Watchdog_Start(void)
{
rWTCNT = 16000;
rWTDAT = 16000;
pISR_WDT_AC97 = (unsigned int)Watchdog_Int;
rINTMSK &= (~BIT_WDT_AC97);
rINTSUBMSK &= (~SUB_BIT_WDT);
// 0xFF3C=不產生復位信號 0xFF3D=產生復位信號,約10秒后系統復位
rWTCON = 0xFF3C;
}
(3)說明
主函數中執行下列代碼:
Timer0_Start();
Watchdog_Start();
while(1);
會看到串口約1秒輸出一次定時器中斷處理消息,約10秒輸出一次看門狗中斷處理消息。如果設置看門狗定時器控制寄存器的值為0xFF3D,則看門狗定時器超時時,會發出復位信號,即大約每隔10秒,系統會復位一次。
主程序在運行死循環,但串口輸出還是可以進行的,這就是中斷的功能了:中斷程序的執行,處理其他事務。以前學微機原理的時候,講中斷只是抽象的概念,不好理解,這里就看得比較清楚了。
中斷處理函數中,應該清除相應的中斷請求位。對于看門狗中斷,由于是通過子中斷寄存器的,所以還要清除子中斷源請求寄存器。如果不進行清除動作,則中斷請求一直保持,相當于不停地發生中斷,無法返回到主程序中。
armcc擴展了C語言,提供__irq關鍵字用以定義中斷處理函數。曾試著不使用__irq,但無論是用C語言還是匯編語言編程,都無法正確實現中斷處理,還是對中斷處理中應該進行的保存恢復寄存器,以及返回到主程序的操作不熟悉,等以后熟悉了再試著不用這個關鍵字吧。
5 兩個術語
PWM:Pulse Width Modulation,脈寬調制。
脈寬調制(PWM:(Pulse Width Modulation)是利用微處理器的數字輸出來對模擬電路進行控制的一種非常有效的技術,廣泛應用在從測量、通信到功率控制與變換的許多領域中。
簡而言之,PWM是一種對模擬信號電平進行數字編碼的方法。通過高分辨率計數器的使用,方波的占空比被調制用來對一個具體模擬信號的電平進行編碼。PWM信號仍然是數字的,因為在給定的任何時刻,滿幅值的直流供電要么完全有(ON),要么完全無(OFF)。電壓或電流源是以一種通(ON)或斷(OFF)的重復脈沖序列被加到模擬負載上去的。通的時候即是直流供電被加到負載上的時候,斷的時候即是供電被斷開的時候。只要帶寬足夠,任何模擬值都可以使用PWM進行編碼。
看門狗:Watchdog
在由單片機構成的微型計算機系統中,由于單片機的工作常常會受到來自外界電磁場的干擾,造成程序的跑飛,而陷入死循環,程序的正常運行被打斷,由單片機控制的系統無法繼續工作,會造成整個系統的陷入停滯狀態,發生不可預料的后果,所以出于對單片機運行狀態進行實時監測的考慮,便產生了一種專門用于監測單片機程序運行狀態的芯片,俗稱“看門狗”。
看門狗電路電路的應用,使單片機可以在無人狀態下實現連續工作,其工作原理是:看門狗芯片和單片機的一個I/O引腳相連,該I/O引腳通過程序控制它定時地往看門狗的這個引腳上送入高電平(或低電平),這一程序語句是分散地放在單片機其他控制語句中間的,一旦單片機由于干擾造成程序跑飛后而陷入某一程序段進入死循環狀態時,寫看門狗引腳的程序便不能被執行,這個時候,看門狗電路就會由于得不到單片機送來的信號,便在它和單片機復位引腳相連的引腳上送出一個復位信號,使單片機發生復位,即程序從程序存儲器的起始位置開始執行,這樣便實現了單片機的自動復位。
看門狗,又叫 watchdog timer,是一個定時器電路, 一般有一個輸入,叫喂狗,一個輸出到MCU的RST端,MCU正常工作的時候,每隔一端時間輸出一個信號到喂狗端,給 WDT 清零,如果超過規定的時間不喂狗,(一般在程序跑飛時),WDT 定時超過,就回給出一個復位信號到MCU,是MCU復位. 防止MCU死機. 看門狗的作用就是防止程序發生死循環,或者說程序跑飛。(
評論