新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Linux 驅動--ADC驅動

        Linux 驅動--ADC驅動

        作者: 時間:2016-11-20 來源:網絡 收藏
        主機系統:Ubuntu 11.04

        內核版本:Linux Kernel 2.6.39

        本文引用地址:http://www.104case.com/article/201611/318848.htm

        硬件平臺:FL2440

        開發板系統:Linux Kernel 2.6.28

        下面是用CPU輪尋的方式來判斷AD轉換完成的

        1. #include
        2. #include
        3. #include
        4. #include/*創建設備節點*/
        5. #include
        6. #include/*延時函數*/
        7. #include
        8. #include
        9. #includeadc.h>
        10. #include
        11. #defineADC_MAJOR102
        12. #defineADC_NAME"my_adc"
        13. #defineSUCCESS0
        14. staticintadc_open(structinode*,structfile*);
        15. staticintadc_release(structinode*,structfile*);
        16. staticint__initadc_init(void);
        17. staticint__exitadc_exit(void);
        18. staticssize_tadc_read(structfile*,char*,size_t,loff_t*);
        19. volatileunsignedlongadc_con;
        20. unsignedlongadc_dat0;
        21. //#defineadc_con(unsignedlong)ioremap(0x58000000,4)
        22. //#defineadc_dat0(volatileunsignedlong)ioremap(0x5800000c,4)
        23. structclk*adc_clk;
        24. structfile_operationsadc_ops=
        25. {
        26. .owner=THIS_MODULE,
        27. .read=adc_read,
        28. .open=adc_open,
        29. .release=adc_release,
        30. };
        31. staticint__initadc_init(void)
        32. {
        33. intret;
        34. adc_clk=clk_get(NULL,"adc");//獲取時鐘
        35. clk_enable(adc_clk);//使能時鐘
        36. ret=register_chrdev(ADC_MAJOR,ADC_NAME,&adc_ops);//注冊設備
        37. if(ret<0)
        38. {
        39. printk("registerdevicefail/n");
        40. returnret;
        41. }
        42. adc_con=(unsignedlong)ioremap(0x58000000,4);
        43. adc_dat0=(volatileunsignedlong)ioremap(0x58000000+S3C2410_ADCDAT0,4);
        44. if(adc_con&adc_dat0==0)
        45. {
        46. printk("Failedtoioremap/n");
        47. gotohandle;
        48. }
        49. printk("Initialized.../n");
        50. returnSUCCESS;
        51. handle:
        52. unregister_chrdev(ADC_MAJOR,ADC_NAME);
        53. return-1;
        54. }
        55. staticintadc_open(structinode*inode,structfile*file)//打開設備函數
        56. {
        57. returnSUCCESS;
        58. }
        59. staticintadc_release(structinode*inode,structfile*file)//關閉設備函數
        60. {
        61. returnSUCCESS;
        62. }
        63. staticssize_tadc_read(structfile*file,
        64. char*buffer,
        65. size_tlength,
        66. loff_t*offset)//設備讀取函數
        67. {
        68. unsignedintbuf;
        69. inttmp;
        70. inti;
        71. writew((1<<14)|(0x31<<6),adc_con);//設置ADCCON
        72. writew((readw(adc_con)|0x1),adc_con);//啟動AD轉換
        73. while(readw(adc_con)&0x1);//啟動轉換后,等待啟動位清零
        74. while(!(readw(adc_con)&0x8000));//等待轉換是否完畢
        75. //for(i=0;i<200000;i++);
        76. mdelay(100);
        77. buf=(readw(adc_dat0)&0x3ff);//取出轉換后得到的有效數據
        78. copy_to_user(buffer,(char*)&buf,sizeof(buf));
        79. //printk("Thevalueis%x/n",buf);
        80. return2;
        81. }
        82. staticint__exitadc_exit(void)//驅動卸載函數
        83. {
        84. iounmap(adc_con);
        85. iounmap(adc_dat0);
        86. unregister_chrdev(ADC_MAJOR,ADC_NAME);
        87. clk_disable(adc_clk);
        88. clk_put(adc_clk);
        89. printk("Theadcisunintialized/n");
        90. returnSUCCESS;
        91. }
        92. module_init(adc_init);
        93. module_exit(adc_exit);
        94. MODULE_LICENSE("GPL");

        其中控制寄存器的第15未標明AD轉換是否完成,當AD完成轉換時,控制寄存器自動置一,但是由于數據存在延遲,當第15位置一的時候讀出的數據并不穩定,需要在其后加個延遲的函數,在內核態使用的延遲函數包含頭文件./linux/delay.h

        mdelay(int x);延時x毫秒

        udelay(int x);延時x微秒

        ndelay(int x);延時x納秒

        測試函數如下:

        1. #include
        2. #include
        3. #include
        4. #defineADC_DEVICE"/dev/my_adc"
        5. intmain()
        6. {
        7. intret;
        8. unsignedintdata;
        9. ret=open(ADC_DEVICE,0);
        10. if(ret<0)
        11. {
        12. printf("Openadcfail/n");
        13. returnret;
        14. }
        15. for(;;)
        16. {
        17. //printf("cnt=%d/n",cnt);
        18. read(ret,&data,sizeof(data));
        19. printf("Thevalueis0x%x/n",data);
        20. }
        21. close(ret);
        22. return0;
        23. }

        測試結果




        關鍵詞: Linux驅動ADC驅

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 兰西县| 泰顺县| 中超| 香河县| 固安县| 安乡县| 景谷| 天镇县| 宁阳县| 邵东县| 广宁县| 德昌县| 玉屏| 个旧市| 赤水市| 富平县| 屏山县| 昆明市| 惠水县| 达州市| 邹城市| 铜陵市| 深泽县| 佛坪县| 云南省| 临江市| 东乡族自治县| 嘉义市| 当阳市| 鸡泽县| 岳阳市| 合作市| 凤城市| 青神县| 新乐市| 靖江市| 泰兴市| 恩平市| 津市市| 北海市| 钟祥市|