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