摘 要: 首先介紹了MAX1202的基本性能和特點(diǎn),,詳細(xì)闡述了MAX1202在嵌入式Linux中驅(qū)動(dòng)程序的實(shí)現(xiàn)方法,,最后介紹了編寫應(yīng)用程序測(cè)試驅(qū)動(dòng)程序的基本方法,,為嵌入式Linux系統(tǒng)下的驅(qū)動(dòng)設(shè)計(jì)提供一個(gè)模板,。
關(guān)鍵詞: MAX1202;驅(qū)動(dòng)程序,;A/D轉(zhuǎn)換,;嵌入式Linux
0 引言
科技的進(jìn)步使智能化設(shè)備越來(lái)越多地應(yīng)用到工業(yè)生產(chǎn)、農(nóng)業(yè)種植,、醫(yī)療衛(wèi)生,、航天設(shè)備甚至是居民的日常生活中,智能化設(shè)備要處理一些環(huán)境中的物理量就需要使用相關(guān)傳感器將其轉(zhuǎn)化成電量,,如電壓,、電流等。但是這些量要送給處理器處理,,則必須要通過(guò)模/數(shù)轉(zhuǎn)換器進(jìn)行轉(zhuǎn)換,。
本文中采用MAX1202模/數(shù)轉(zhuǎn)換器和友善之臂的Micro2440開發(fā)板,開發(fā)板使用三星公司的s3c2440的ARM9微處理器,。在Linux系統(tǒng)中開發(fā)MAX1202驅(qū)動(dòng)程序并編寫應(yīng)用程序進(jìn)行驅(qū)動(dòng)程序的測(cè)試,。
1 芯片介紹
MAX1202是一款8通道12位串行A/D轉(zhuǎn)換器。串行接口工作頻率最高可以達(dá)到2 MHz[1],。工作采用單端+5 V供電或雙端±5 V供電,。內(nèi)部有一個(gè)8通道的多路轉(zhuǎn)換器,、高帶寬的跟蹤/保持電路以及高轉(zhuǎn)換速度和低功耗的串行接口,芯片提供了符合SPI通信標(biāo)準(zhǔn)的SPI接口,,以便于編程實(shí)現(xiàn)數(shù)據(jù)的轉(zhuǎn)換,。
其典型應(yīng)用電路如圖1所示。
2 驅(qū)動(dòng)程序設(shè)計(jì)
Linux驅(qū)動(dòng)程序使用module_init宏中所定義的初始化函數(shù)注冊(cè)該驅(qū)動(dòng)及初始化硬件設(shè)備,;使用module_exit宏中定義的注銷函數(shù)注銷設(shè)備,,釋放相關(guān)資源。
結(jié)構(gòu)struct file_operations列出了設(shè)備驅(qū)動(dòng)程序可供應(yīng)用程序調(diào)用的所有函數(shù),。其中的成員都是函數(shù)指針,,指向該函數(shù)的入口執(zhí)行位置,當(dāng)應(yīng)用程序調(diào)用open,、read、write等函數(shù)時(shí),,驅(qū)動(dòng)程序會(huì)通過(guò)該結(jié)構(gòu)找到對(duì)應(yīng)應(yīng)該執(zhí)行的M1202函數(shù),,進(jìn)而根據(jù)傳入的參數(shù)執(zhí)行,以響應(yīng)應(yīng)用程序的調(diào)用,。驅(qū)動(dòng)程序的編寫主要就在于file_operations結(jié)構(gòu)體中各驅(qū)動(dòng)函數(shù)的實(shí)現(xiàn),,并不是每一個(gè)函數(shù)都要實(shí)現(xiàn)[2],對(duì)于不需要實(shí)現(xiàn)的函數(shù)可以賦值為空,,也可以在函數(shù)實(shí)現(xiàn)中直接返回0,,或直接調(diào)用系統(tǒng)默認(rèn)的實(shí)現(xiàn)函數(shù)。MAX1202的file_operations結(jié)構(gòu)體定義如下:
static const struct file_operations M1202_fops=
{
.owner=THIS_MODULE,,
.open=M1202_open,,
.read=M1202_read,
.write=M1202_write,,
.ioctl=NULL,,
};
2.1 模塊初始化函數(shù)M1202_init
在驅(qū)動(dòng)加載時(shí),,系統(tǒng)進(jìn)程會(huì)通過(guò)module_init(M1202_init)宏找到所定義的驅(qū)動(dòng)初始化函數(shù)M1202_init(),,進(jìn)行驅(qū)動(dòng)程序的加載。主設(shè)備號(hào)可以自已定義,,向函數(shù)MKDEV(M1202_major,,0)傳遞主次設(shè)備號(hào)產(chǎn)生dev_t類型的devno結(jié)構(gòu)[3];也可以由alloc_chrdev_region(&devno,,0,,1,M1202_name)函數(shù)自動(dòng)分配主設(shè)備號(hào),;本例中自己定義主設(shè)備號(hào),,然后由register_chrdev_region(devno,,1,M1202_name)函數(shù)在Linux中為驅(qū)動(dòng)程序獲取設(shè)備編號(hào),;接著就是向Linux內(nèi)核注冊(cè)字符設(shè)備,,指出該驅(qū)動(dòng)可提供給應(yīng)用程序的接口結(jié)構(gòu)。實(shí)現(xiàn)代碼如下:
cdev_init(&M1202Cdev,,&M1202_fops),;
M1202Cdev.owner=THIS_MODULE;
M1202Cdev.ops=& M1202_fops,;
cdev_add(&M1202Cdev,,devno,1),;
代碼中省去了錯(cuò)誤調(diào)試信息,。
2.2 設(shè)備打開函數(shù)M1202_open
s3c2440芯片配備了2組SPI接口[4],Micro2440開發(fā)板引出了一組SPI1,,對(duì)應(yīng)是PA7,、PA8、PA9,、PA10引腳,,這是一組可以復(fù)用的端口,既可以用中斷,、普通端口,,也可以用于SPI通信。MAX1202在外部時(shí)鐘模式下的工作時(shí)序如圖2所示,。
查看MAX1202在外部時(shí)鐘模式下的工作時(shí)序可以發(fā)現(xiàn),,在控制字送入的8個(gè)時(shí)鐘后,芯片即開始了邊輸出邊轉(zhuǎn)換的過(guò)程,,相比較內(nèi)部時(shí)鐘模式的轉(zhuǎn)換完成后再讀取輸出結(jié)果而言,,有著更快的轉(zhuǎn)換效率,故采用外部時(shí)鐘模式,。在控制字輸出后,,轉(zhuǎn)換結(jié)果緊跟著輸出,為了減少頻繁對(duì)寄存器的操作,,降低編程的難度,,采用普通輸出端口輪流輸出高低電平的方法模擬主SPI設(shè)備的時(shí)鐘輸出。使用s3c2410_gpio_cfgpin(S3C2410_GPG11,,S3C2410_GPG11_OUTP),;將GPG11端配置成輸出端口用于輸出MAX1202工作時(shí)所需的片選信號(hào);類似地用s3c2410_gpio_cfgpin()函數(shù)配置GPG6,、GPG7端為輸出端,,分別用于產(chǎn)生MAX1202的控制字輸入與時(shí)鐘輸入,;使用s3c2410_gpio_cfgpin(S3C2410_GPG5,S3C2410_GPG5_INP),;將GPG5端口配置成輸入端口,,用于讀取MAX1202的Dout端的輸出結(jié)果。在MAX1202正式工作前需將片選端CS端置為1,,相應(yīng)地有s3c2410_gpio_setpin(S3C2410_GPG3,,1);函數(shù),;另外三個(gè)端口s3c2410_gpio_setpin函數(shù)配置為0,。這些就是open函數(shù)所需要完成的端口配置。
2.3 寫函數(shù)M1202_write
設(shè)備打開后,,每次轉(zhuǎn)換之前,,需要向MAX1202寫控制字,以設(shè)置MAX1202選通的工作通道,、時(shí)鐘模式,、信號(hào)輸入模式等。MAX1202控制字格式如表1所示,。
Bit7:起始位一般選擇1,用于標(biāo)識(shí)控制字的開始,;
Bit6~Bit4:是8路通道的選擇,,在單端模式下,依據(jù)8421編碼,,000對(duì)應(yīng)第0通道CH0,,001對(duì)應(yīng)第1通道CH1,010對(duì)應(yīng)第2通道CH2,,以此類推,;
Bit3:為信號(hào)的單雙極性選擇位,這里選擇1,,單極性,;
Bit2:為信號(hào)輸入方式選擇位,這里選擇1,,單端輸入,;
Bit1~Bit0:時(shí)鐘和斷電模式選擇位,這里選擇11,,外部時(shí)鐘,。
驅(qū)動(dòng)屬于內(nèi)核的一部分,而應(yīng)用程序?qū)儆谟脩艨臻g,,內(nèi)核空間和用戶空間的數(shù)據(jù)不能共享,,數(shù)據(jù)的傳輸需要使用特定的函數(shù)copy_from_user()和copy_to_user(),。因此,由應(yīng)用程序傳入的控制字信息需要使用copy_from_user()傳入內(nèi)核空間,。使用循環(huán)移位和與操作,,輪流讀取8位控制字的每一位,由s3c2410_gpio_setpin(S3C2410_GPG6,,X)函數(shù)將各位值輸出到MAX1202得DIN端,,在時(shí)鐘的下降沿由MAX1202讀取,X代表了要傳輸?shù)囊晃恢怠?/p>
2.4 讀函數(shù)M1202_read
在外部時(shí)鐘模式下,,控制字輸入完后即可在緊接著的16個(gè)時(shí)鐘周期內(nèi)讀取轉(zhuǎn)換結(jié)果,,這16位轉(zhuǎn)換結(jié)果的最低4位為無(wú)效位,均為0,,雖然無(wú)效,,但必須在時(shí)鐘的作用下讀取出來(lái),不然會(huì)影響到下一次的轉(zhuǎn)換結(jié)果,,故函數(shù)讀取16位后左移4位用于消除低4位的無(wú)效位,。while函數(shù)的執(zhí)行條件控制讀取次數(shù)為16次,s3c2410_gpio_getpin(S3C2410_GPG5)用于從MAX1202的DOUT端讀入當(dāng)前時(shí)鐘下的輸出值,。讀取結(jié)束后,,要使用copy_to_user()函數(shù)將得到的結(jié)果傳遞到用戶空間,以供顯示或處理,。
2.5 模塊卸載函數(shù)M1202_exit
模塊卸載函數(shù)首先要?jiǎng)h除字符設(shè)備,,然后釋放占用的驅(qū)動(dòng)設(shè)備號(hào),以供其他的設(shè)備使用,。
cdev_del(&M1202Cdev),;
unregister_chrdev_region(MKDEV(M1202_major,0),,1),;
3 MAX1202在嵌入式系統(tǒng)中的應(yīng)用
3.1 設(shè)備驅(qū)動(dòng)的加載
Linux下的驅(qū)動(dòng)有靜態(tài)加載和動(dòng)態(tài)加載兩種方式[5]。靜態(tài)加載將驅(qū)動(dòng)程序編譯到內(nèi)核里,,系統(tǒng)啟動(dòng)后直接可以由應(yīng)用程序調(diào)用,,但每次修改驅(qū)動(dòng)程序都必須重新編譯內(nèi)核,較麻煩,。動(dòng)態(tài)加載是在系統(tǒng)啟動(dòng)后使用insmod命令,,把編譯好的M1202.ko文件加載到系統(tǒng)中,不需要時(shí)可以使用rmmod命令卸載,。但是在重新開機(jī)之后,,該驅(qū)動(dòng)就沒了,需要重新加載,。故靜態(tài)加載適合于驅(qū)動(dòng)開發(fā)完成后的產(chǎn)品量化,;而動(dòng)態(tài)加載適合于驅(qū)動(dòng)開發(fā)過(guò)程中頻繁的修改,。
在開發(fā)板中驅(qū)動(dòng)的動(dòng)態(tài)加載方法:
#cd/lib/modules/2.6.32.3-FriendlyARM
#insmod M1202.ko
#mknod/dev/M1202 c 55 0
在Linux中,設(shè)備被當(dāng)做文件一樣處理,,任何可用設(shè)備在/dev/目錄下都會(huì)有一個(gè)對(duì)應(yīng)的設(shè)備文件,,使用mknod命令創(chuàng)建設(shè)備節(jié)點(diǎn),在應(yīng)用程序中即可像操作文件一樣操作該設(shè)備,。
3.2 數(shù)據(jù)采集
驅(qū)動(dòng)加載并且創(chuàng)建了設(shè)備節(jié)點(diǎn)后就可以編寫應(yīng)用程序進(jìn)行電壓數(shù)據(jù)的采集,。
使用open函數(shù)以只讀的方式打開已經(jīng)創(chuàng)建了的M1202節(jié)點(diǎn)即打開了MAX1202硬件。傳入控制字0x8F給write函數(shù),,開啟通道0的轉(zhuǎn)換,,使用單極性單端輸入外部時(shí)鐘模式,read函數(shù)將轉(zhuǎn)換結(jié)果保存到指針num所指向的地址中,,然后就可以打印或者處理轉(zhuǎn)換結(jié)果,,最后像關(guān)閉文件一樣使用close()函數(shù)關(guān)閉設(shè)備。使用交叉編譯指令#arm-linux-gcc╞o M1202test M1202test.c編譯后生成應(yīng)用程序文件M1202test,,通過(guò)串口導(dǎo)入Micro2440中或?qū)?yīng)用程序文件放到網(wǎng)絡(luò)根文件系統(tǒng)中,,#chmod+x M1202test增加文件的可執(zhí)行權(quán)限,#./M1202test執(zhí)行可執(zhí)行文件,,即可對(duì)通道0引腳的數(shù)據(jù)進(jìn)行采集轉(zhuǎn)換,。
部分應(yīng)用程序如下:
int fd=open(“/dev/M1202”,0_RDWR),;
int ctlword=0x8F,;
write(fd,ctlword,,1);
read(fd,,&num,,2);
printf(“num=%d\n”,,num),;
close(fd);
在實(shí)際使用中可以使用for(int i=0,,i<8,,i++)和ctlword=ctlword|(i<<4);改變控制字的Bit6-Bit4位,,循環(huán)采集引腳0-7端輸入的電壓,,或者根據(jù)需要使用其中部分引腳。經(jīng)測(cè)試,,A/D轉(zhuǎn)換結(jié)果較好,,在轉(zhuǎn)換誤差范圍內(nèi),。
4 結(jié)論
隨著智能化設(shè)備的發(fā)展,嵌入式系統(tǒng)將涉及生活中的方方面面,。本文詳細(xì)介紹了MAX1202在嵌入式Linux系統(tǒng)中的驅(qū)動(dòng)程序的開發(fā)方法,,對(duì)于相關(guān)驅(qū)動(dòng)程序的開發(fā)有一定的參考價(jià)值,且該MAX1202的A/D實(shí)現(xiàn)方法也可以應(yīng)用到一些工程實(shí)際中去,。
參考文獻(xiàn)
[1] 蔣雙梅,,高敦堂,都思丹.8通道12位串行A/D轉(zhuǎn)換器MAX1202及其應(yīng)用[J].微電子學(xué),,2000,,30(6):437-440.
[2] 韋東山.嵌入式Linux應(yīng)用開發(fā)完全手冊(cè)(第1版)[M].北京:人民郵電出版社,2008.
[3] 付興武,,張軍,,王洋.基于SPI總線協(xié)議的字符設(shè)備驅(qū)動(dòng)程序[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2013,,22(2):146-150.
[4] 楊小容,,陳建政.串口AD嵌入式Linux驅(qū)動(dòng)實(shí)現(xiàn)[J].中國(guó)測(cè)試,2010,,36(2):84-87.
[5] 黃智偉,,鄧月明,王彥.ARM9嵌入式系統(tǒng)設(shè)計(jì)基礎(chǔ)教程(第1版)[M].北京:北京航空航天大學(xué)出版社,,2008.