您的位置 首页 系统

Linux 驱动–ADC驱动

主机系统:Ubuntu11.04内核版本:LinuxKernel2.6.39硬件平台:FL2440开发板系统:LinuxKernel2.6.28下面是用CPU轮寻的方式来判断…

主机体系:Ubuntu 11.04

内核版别:Linux Kernel 2.6.39

硬件渠道: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. }

测验成果

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/xitong/264258.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部