pcDuino Linux驱动开发六 -- 最简单的LRADC驱动

作者: tjcfeng
上传时间为: 2014-11-30 11:14 PM

先来说一下A10的ADC。A10的ADC共有两种,一种是LRADC,另一种是TPController。

LARADC,是一种低分辨率的模数转换器,按照用途A10常把它当作按键检测的通道,可以检测长按、短按、按下、抬起等动作,最高电压可以支持到2V,有些低了。
TPController一般用来检测触摸屏的控制,根据电压的变化获取坐标。玩过单片机+显示屏的应该都很熟悉,这个功能被集成到A10中了。TPController最大可以支持到5V。

这次主要试验一下LRADC,对于TPController就不多说了。

LRADC很简单,简单到所有的寄存器参数都使用默认值,只要控制一下启动就可以了,甚至比IO口都要简单。当然,它也有许多功能,为了简单起见先不考虑。

本来按照手册说明LRADC可以检测按键的状态,但是还要接按键、电阻,还得动烙铁,有点麻烦;也想过接个光敏电阻,同样还是要找块板子来焊件连线,所以干脆用个最简单的办法,直接测试电池吧。

接线方式:

灰线接地,绿线接到ADC0口。

另一边(忽略蓝线和紫线,没接):

灰线接电池的负极,绿线接正极。

好了,下面开始写程序:

  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/fs.h>
  4. #include <linux/cdev.h>
  5. #include <linux/device.h>
  6. #include <linux/wait.h>
  7. #include <linux/delay.h>
  8. #include <asm/io.h>
  9. #include <asm/uaccess.h>
  10. #include <linux/kthread.h>
  11. #include <linux/sched.h>
  12. #include <linux/err.h>
  13. #include "../A10.h"
  14. static uint8_t ADC[2];
  15. /**********************************************************************/
  16. volatile static unsigned long* REG_LRADC_CTRL;
  17. volatile static unsigned long* REG_LRADC_INTC;
  18. volatile static unsigned long* REG_LRADC_INTS;
  19. volatile static unsigned long* REG_LRADC_DATA0;
  20. static struct task_struct* pThread;
  21. static int Inited = 0;
  22. int LRADC_thread(void* Data)
  23. {
  24. while (1)
  25. {
  26. set_current_state(TASK_UNINTERRUPTIBLE);
  27. if (kthread_should_stop()) break;
  28. *REG_LRADC_CTRL |= (0x1 << 0); //LRADC Enable
  29. while (!(*REG_LRADC_INTS & 0x1)) mdelay(1); //Waitting INT
  30. ADC[0] = *REG_LRADC_DATA0;
  31. printk("ADC0: %d\n", ADC[0]);
  32. *REG_LRADC_INTS |= (0x1 << 0); //Clear Pending
  33. schedule_timeout(100);
  34. }
  35. return 0;
  36. }
  37. static int LRADC_open(struct inode* n, struct file* f)
  38. {
  39. int Result = 0;
  40. Inited++;
  41. if (Inited > 1)
  42. {
  43. return 0;
  44. }
  45. REG_LRADC_CTRL = (volatile unsigned long*) ioremap(LRADC_CTRL, 4);
  46. REG_LRADC_INTC = (volatile unsigned long*) ioremap(LRADC_INTC, 4);
  47. REG_LRADC_INTS = (volatile unsigned long*) ioremap(LRADC_INTS, 4);
  48. REG_LRADC_DATA0= (volatile unsigned long*) ioremap(LRADC_DATA0, 4);
  49. *REG_LRADC_INTC |= (0x1 << 0); //ADC0 IRQ Enable
  50. pThread = kthread_create(LRADC_thread, NULL, "GY80");
  51. if (IS_ERR(pThread))
  52. {
  53. pThread = NULL;
  54. printk("Create Thread Error!");
  55. return -1;
  56. }
  57. wake_up_process(pThread);
  58. printk("Open Finished!\n");
  59. return Result;
  60. }
  61. static ssize_t LRADC_write(struct file* f, const char __user* buf, size_t len, loff_t* l)
  62. {
  63. //printk("Write Finished!\n");
  64. return 0;
  65. }
  66. static ssize_t LRADC_read(struct file* f, char __user* buf, size_t len, loff_t* l)
  67. {
  68. //printk("Read Finished!\n");
  69. return 0;
  70. }
  71. static int LRADC_close(struct inode* n, struct file* f)
  72. {
  73. Inited--;
  74. if (Inited > 0)
  75. {
  76. return 0;
  77. }
  78. kthread_stop(pThread);
  79. pThread = NULL;
  80. *REG_LRADC_CTRL &= ~(0x1 << 0); //LRADC Disable
  81. iounmap(REG_LRADC_CTRL);
  82. iounmap(REG_LRADC_INTC);
  83. iounmap(REG_LRADC_INTS);
  84. iounmap(REG_LRADC_DATA0);
  85. printk("Close Finished!\n");
  86. return 0;
  87. }
  88. /**********************************************************************/
  89. #define DEV_NAME "LRADC"
  90. #define DEV_COUNT 1
  91. static struct class* pClass;
  92. int major;
  93. static struct file_operations fops =
  94. {
  95. .owner = THIS_MODULE,
  96. .open = LRADC_open,
  97. .write = LRADC_write,
  98. .read = LRADC_read,
  99. .release = LRADC_close,
  100. };
  101. static int __init LRADC_init(void)
  102. {
  103. major = register_chrdev(0, DEV_NAME, &fops);
  104. pClass = class_create(THIS_MODULE, DEV_NAME);
  105. if (pClass == NULL)
  106. {
  107. unregister_chrdev(major, DEV_NAME);
  108. return -1;
  109. }
  110. device_create(pClass, NULL, MKDEV(major, 0), NULL, DEV_NAME);
  111. LRADC_open(NULL, NULL);
  112. //printk("Init Finished!\n");
  113. return 0;
  114. }
  115. static void __exit LRADC_exit(void)
  116. {
  117. LRADC_close(NULL, NULL);
  118. unregister_chrdev(major, DEV_NAME);
  119. if (pClass)
  120. {
  121. device_destroy(pClass, MKDEV(major, 0));
  122. class_destroy(pClass);
  123. }
  124. //printk("Exit Finished!\n");
  125. }
  126. MODULE_LICENSE("GPL");
  127. MODULE_AUTHOR("LiuYang");
  128. module_init(LRADC_init);
  129. module_exit(LRADC_exit);

复制代码

程序没什么好说的,还是为了简单,用了一个线程让它去循环检测。也可以不使用线程放到write、read里控制检测和获取值,看自己的需要了。

全部评论 ()

创建讨论帖子

登录 后参与评论
系统提示