μC/OS-II實(shí)時(shí)內核下的A/D驅動(dòng)程序設計
關(guān)鍵詞:μC/OS-II A/D 驅動(dòng)程序 C8051F015
A/D轉換是單片機數據采集系統的重要組成部分,實(shí)時(shí)內核下A/D驅動(dòng)程序的實(shí)現過(guò)程主取決于A(yíng)/D轉換器的轉換時(shí)間。本文首先比較和分析μC/OS-II下A/D采樣數據的三種方法;其次介紹C8051F015單片機A/D模數轉換器配置及特點(diǎn);最后,在μC/OS-II內核移植到8位單片機C8051F015的基礎上,介紹編寫(xiě)A/D驅動(dòng)程序的一般思想和方法。
1 μC/OS-II實(shí)時(shí)內核下的A/D讀方法
實(shí)時(shí)內核下,驅動(dòng)程序采用什么方法讀取A/D采樣數據是首先考慮的問(wèn)題。許多因素將影響讀取A/D,如A/D的轉換時(shí)間、模擬值的轉換頻率、輸入通道數等,但最主要的取決于A(yíng)/D的轉換時(shí)間。典型的A/D轉換典型的A/D轉換電路由模擬多路復用器(MUX)、放大器和模數轉換器(ADC)三部分組成。下面描述讀取A/D的三種方法。
圖1所示的是第1種讀取方法。假設A/D轉換器的轉換時(shí)間較慢(5ms以上)。應用程序調用圖1所示的驅動(dòng)程序,并傳遞要讀取的通道。驅動(dòng)程序通過(guò)MUX選擇要讀取的模擬通道(①)開(kāi)始讀。有,延時(shí)幾μs以便使信號通過(guò)MUX傳遞,并之穩定下來(lái)。接著(zhù),ADC被觸發(fā)開(kāi)始轉換(②)。然后驅動(dòng)程序延時(shí)一段時(shí)間以完成轉換(③_。延時(shí)時(shí)間必須比ADC轉換時(shí)間長(cháng)。最后驅動(dòng)程序讀取ADC轉換結果(④)。并將轉換結果返回到應用程序(⑤)。
圖2所示的是第2種讀取方法。當模擬轉換完成后,ADC產(chǎn)生的個(gè)中斷信號。若ADC轉換完成,ISR給信號量發(fā)一個(gè)信號(⑤),通知驅動(dòng)程序,ADC已經(jīng)完成轉換。如果ADC在規定的時(shí)限內沒(méi)有完成轉換。信號量超過(guò)(③),則驅動(dòng)程序不再等待下去。驅動(dòng)程序和中斷服務(wù)子程序(ISR)的偽代碼如下:
ADRd(ChannelNumber)
{
選擇要讀取的模擬輸入通道;
等待AMUX輸出穩定;
啟動(dòng)ADC轉換;
等待來(lái)自ADC轉換結束中斷產(chǎn)生的信號量;
if(超時(shí)){
*eer=信號錯誤;
return;
}else{
讀取ADC轉換結果并將其返回到應用程序;
}
}
保存全部CPU寄存器; /*將CPU的PSW、ACC、B、DPL、DPH及Rn入棧*/
通知內核進(jìn)入ISR(調用OSIntEnter()或OSIntNesting直接加1);
發(fā)送ADC轉換完成信號; /*利用μC/OS-II內核的OSSemPost()*/
通知內核退出ISR(調用OSIntExit());
恢復所有CPU寄存器;/*將CPU的PSW、ACC、B、DPL、DPH及Rn出棧*/
執行中斷返回指令(即RETI);
}
在這種方法里,要求ISR執行時(shí)間與調用等待信號的時(shí)間之和為A/D轉換時(shí)間。
如果A/D轉換時(shí)間小于處理中斷時(shí)間與等待信號所需的時(shí)間之和,則可以用第三種方法。如圖3所示,前兩步(①②同以上兩種方法)結束后,驅動(dòng)程序接著(zhù)在一個(gè)軟件循環(huán)中等待(③)ADC直到完成轉換。在循環(huán)等待時(shí),驅動(dòng)程序檢測ADC的狀態(tài)(BUSY)信號。如果等待時(shí)間超過(guò)設定的定時(shí)值(軟件定時(shí)),則結束等待循環(huán)(循環(huán)等超時(shí))。如果在循環(huán)等待中,檢測到ADC發(fā)出轉換結束的信號(BUSY)時(shí),驅動(dòng)程序讀取ADC轉換結果(④)并將結果返回到應用程序(⑤)。驅動(dòng)程序偽代碼如下:
ADRd(ChannelNumber){
選擇要讀取的模擬輸入通道;
等待AMUX輸出穩定;
啟動(dòng)ADC轉換;
啟動(dòng)超時(shí)定時(shí)器;
while(ADC Busy Counter 0);/*循環(huán)檢測*/
if(Counter==0){
*err=信號錯誤;
return;
}else{
讀取ADC轉換結果并將其返回到應用程序;
}
}
A、D轉換速度快,這種驅動(dòng)程序的實(shí)現是最好的。
2 C8051F015單片機的A/D轉換器
2.1 C8051C015單片機
C8051C015的美國Cygnal公司新推出的高速SOC型C8051Fxxx系列單片機。它的內核CIP-51與MCS-51的指令集完全兼容,CIP-51的系統時(shí)鐘頻率在0~25MHz。C8051Fxxx系列單片機采用流水線(xiàn)結構,與標準的8051相比,指令執行速度有很大的提高。CIP-51內核的指令執行時(shí)間是以系統時(shí)鐘為單位,70%的指令執行時(shí)間為1個(gè)或2個(gè)系統時(shí)鐘周期。C8051F015具有32KB的內存、2304B的RAM(片內256B、片外2048B)。CIP-51內核具有標準8052的所有外設部件,片上還集成有9通道10位A/D轉換接口電路、SMBus/I2C、SPI串行接口。
2.2 C8051F015的A/D轉換電路
C8051F015的A/D轉換電路包括1個(gè)9通道可配置模擬多路開(kāi)關(guān)AMUX(8路用于外部模擬輸入、1路用于芯片環(huán)境溫度的測量)、1個(gè)可編程增益放大器PGA和1個(gè)100ksps 10位分辨率的逐次逼近型ADC。A/D中還集成了跟蹤保持電路和可編程窗口檢測器。
ADC有4種啟動(dòng)方式:軟件命令、定時(shí)器2溢出、定時(shí)器3溢出及外部信號輸入。寄存器ADC0CN是配置啟動(dòng)和跟蹤方式的控制寄存器。每次轉換結束時(shí),ADC0CH的ADBUSY(忙標志)的下降沿觸發(fā)中斷,也可用軟件查詢(xún)這個(gè)狀態(tài)位。
2.3 ADC轉換速度
C8051Fxxx系列單片機中ADC的速率都是可編程設置的。表1給出了所需最小分頻系數與SYSCLK(系統時(shí)鐘)的關(guān)系(ADC0CF為ADC配置寄存器)。
表1 ADC時(shí)鐘分頻系數與SYSCLK頻率的關(guān)系
SYSCLK頻率/MHz | ADC時(shí)鐘分頻系數 | ADC0CF的ADCSC2~1 |
時(shí)鐘頻率2.5 | 1 | 000 |
2.5~5 | 2 | 001 |
5~10 | 4 | 010 |
10~20 | 8(復位值) | 011 |
時(shí)鐘頻率>20 | 16 | 1xx |
在C8051F015單片機中,ADC的轉換時(shí)鐘周期至少在400ns,轉換時(shí)鐘應不大于2MHz。一般在啟動(dòng)ADC之前都要處于跟蹤方式,而ADC一次轉換完成要用16個(gè)系統時(shí)鐘。另外,在轉換之前還要加上3個(gè)系統時(shí)鐘的跟蹤/保持捕獲時(shí)間,所以完成一次轉換需19個(gè)ADC轉換時(shí)鐘(9.5μs)。
圖1中的方法簡(jiǎn)單,轉換時(shí)間在ms級以上,一般用于變化慢的模擬輸入信號,不適用于C8051F015。圖2中的方法,為了減少μC/OS-II內核調用ISR所用時(shí)間,ISR一般都用于匯編語(yǔ)言編寫(xiě)。從程序1中ISR偽代碼可以看出,盡管ISR用匯編語(yǔ)言編寫(xiě)。代碼效率高,但μC/OS-II調用ISR的時(shí)間與調用等待信號時(shí)間之和大于A(yíng)/D的轉換時(shí)間,所以CPU用于ISR和循環(huán)檢測的開(kāi)銷(xiāo)大。
圖3所示的方法顯然適合于C8051F015單片機,其優(yōu)點(diǎn)是:可以獲得快速的轉換時(shí)間;不需要增加一個(gè)復雜的ISR;轉換時(shí)信號改變時(shí)間更短;CPU的開(kāi)銷(xiāo)??;循環(huán)檢測程序可被中斷,為中斷信號服務(wù)。
圖4 A/D驅動(dòng)程序模塊流程圖
3 A/D驅動(dòng)程序的編寫(xiě)
外設驅動(dòng)程序是實(shí)時(shí)內核和硬件之間的接口,是連接底層硬件和內核的紐帶。編寫(xiě)驅動(dòng)程序模塊應滿(mǎn)足以下主要功能:①對設備初始化;②把數據從內核傳送到硬件從硬件讀取數據;③讀取應用程序傳送給設備的數據和回送應用程序請求的數據;④監測和處理設備出現的異常。
A/D轉換電路作為一個(gè)模擬輸入模塊,μC/OS-II內核應把它作為一個(gè)獨立的任務(wù)(以下稱(chēng)為ADTask())來(lái)調用。A/D驅動(dòng)程序模塊流程如圖4所示。ADInit()初始化所有的模擬輸入通道、硬件ADC以及應用程序調用A/D模塊的參量,并且ADInit()創(chuàng )建任務(wù)ADTask()。ADTb1[]是一個(gè)模擬輸入通道信息、ADC硬件狀態(tài)等參數配置以及轉換結果存儲表。ADUpdate()負責讀取所有模擬輸入通道,訪(fǎng)問(wèn)ADRd()并傳遞給它一個(gè)通道數。ADRd()負責通過(guò)多路復用器選擇合適的模擬輸入,啟動(dòng)并等待ADC轉換,以及返回ADC轉換結果到ADUpdate()。
在μC/OS-II這時(shí)內核下各原型函數、數據結構和常量的定義如下:
INT16S ADRd(INT8U ch);
/*定義如何讀取A/D,A/D必須通過(guò)AIRd()來(lái)驅動(dòng)*/
void ADUpdate(void);
/*一定時(shí)間內更新輸入通道*/
void ADInit(void);
/*A/D模塊初始化代碼,包括初始化所有內部變量(通過(guò)ADInit()初始化ADTb[]),初始化硬件A/D(通過(guò)ADInitI())及創(chuàng )建任務(wù)ADTask()*/
void ADTask (void data);
/*由ADInit()創(chuàng )建,負責更新輸入通道(調用ADUpdate ())*/
void ADInitI (void);
/*初始化硬件A/D*/
AD_TaskPrio:設置任務(wù)ADTask()的優(yōu)先級。
AD_TaskStkSize:設置分配給任務(wù)ADTask()的堆棧大小。
AD_MaxNummber:AMUX的輸入通道數。
AD_TaskDly:設定更新通道的間隔時(shí)間。
AD ADTbl[AD_MaxNummber]:AD類(lèi)型的數組(AD是定義的數據結構)。
4 結論
對于A(yíng)/D轉換器接口電路驅動(dòng)程序的編寫(xiě)歸納出以下幾點(diǎn):
①在決定采用具體的驅動(dòng)方案之前,分析接口電路的特點(diǎn),尤其是了解A/D的轉換速度;
②對于轉換速度快的A/D轉換器,可能出現CPU的處理速度與A/D轉換速度不匹配,一般的A/D中不帶有FIFO緩沖區,須有內存中開(kāi)辟緩沖區;
③在應用程序讀取設備之前,一定要初始化硬件(調用初始化函數),合理定義硬件的信息和狀態(tài)變量;
④不同的輸入通道采集到不同類(lèi)型數據,環(huán)境、轉換精度都會(huì )影響到轉換結果,要對各個(gè)模擬輸入通道進(jìn)行校準和補償(通常在應用程序中編寫(xiě)通道補償函數)。
評論