新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Linux 驅(qū)動(dòng)--ADC驅(qū)動(dòng)

Linux 驅(qū)動(dòng)--ADC驅(qū)動(dòng)

作者: 時(shí)間:2016-11-20 來源:網(wǎng)絡(luò) 收藏
主機(jī)系統(tǒng):Ubuntu 11.04

內(nèi)核版本:Linux Kernel 2.6.39

本文引用地址:http://butianyuan.cn/article/201611/318848.htm

硬件平臺(tái):FL2440

開發(fā)板系統(tǒng):Linux Kernel 2.6.28

下面是用CPU輪尋的方式來判斷AD轉(zhuǎn)換完成的

  1. #include
  2. #include
  3. #include
  4. #include/*創(chuàng)建設(shè)備節(jié)點(diǎn)*/
  5. #include
  6. #include/*延時(shí)函數(shù)*/
  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");//獲取時(shí)鐘
  35. clk_enable(adc_clk);//使能時(shí)鐘
  36. ret=register_chrdev(ADC_MAJOR,ADC_NAME,&adc_ops);//注冊設(shè)備
  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)//打開設(shè)備函數(shù)
  56. {
  57. returnSUCCESS;
  58. }
  59. staticintadc_release(structinode*inode,structfile*file)//關(guān)閉設(shè)備函數(shù)
  60. {
  61. returnSUCCESS;
  62. }
  63. staticssize_tadc_read(structfile*file,
  64. char*buffer,
  65. size_tlength,
  66. loff_t*offset)//設(shè)備讀取函數(shù)
  67. {
  68. unsignedintbuf;
  69. inttmp;
  70. inti;
  71. writew((1<<14)|(0x31<<6),adc_con);//設(shè)置ADCCON
  72. writew((readw(adc_con)|0x1),adc_con);//啟動(dòng)AD轉(zhuǎn)換
  73. while(readw(adc_con)&0x1);//啟動(dòng)轉(zhuǎn)換后,等待啟動(dòng)位清零
  74. while(!(readw(adc_con)&0x8000));//等待轉(zhuǎn)換是否完畢
  75. //for(i=0;i<200000;i++);
  76. mdelay(100);
  77. buf=(readw(adc_dat0)&0x3ff);//取出轉(zhuǎn)換后得到的有效數(shù)據(jù)
  78. copy_to_user(buffer,(char*)&buf,sizeof(buf));
  79. //printk("Thevalueis%x/n",buf);
  80. return2;
  81. }
  82. staticint__exitadc_exit(void)//驅(qū)動(dòng)卸載函數(shù)
  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未標(biāo)明AD轉(zhuǎn)換是否完成,當(dāng)AD完成轉(zhuǎn)換時(shí),控制寄存器自動(dòng)置一,但是由于數(shù)據(jù)存在延遲,當(dāng)?shù)?5位置一的時(shí)候讀出的數(shù)據(jù)并不穩(wěn)定,需要在其后加個(gè)延遲的函數(shù),在內(nèi)核態(tài)使用的延遲函數(shù)包含頭文件./linux/delay.h

mdelay(int x);延時(shí)x毫秒

udelay(int x);延時(shí)x微秒

ndelay(int x);延時(shí)x納秒

測試函數(shù)如下:

  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. }

測試結(jié)果




評(píng)論


技術(shù)專區(qū)

關(guān)閉