查看: 4339|回复: 6

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

[复制链接]
  • TA的每日心情
    奋斗
    2022-9-16 05:52
  • 签到天数: 1368 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2014-8-23 13:57:36 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 tjcfeng 于 2014-8-23 14:20 编辑

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

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

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

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

    接线方式:
    1.JPG
    灰线接地,绿线接到ADC0口。

    另一边(忽略蓝线和紫线,没接):
    2.JPG
    灰线接电池的负极,绿线接正极。

    好了,下面开始写程序:
    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. /**********************************************************************/
    17.         volatile static unsigned long* REG_LRADC_CTRL;
    18.         volatile static unsigned long* REG_LRADC_INTC;
    19.         volatile static unsigned long* REG_LRADC_INTS;
    20.         volatile static unsigned long* REG_LRADC_DATA0;
    21.         
    22.         static struct task_struct* pThread;
    23.         static int Inited = 0;
    24.         
    25. int LRADC_thread(void* Data)
    26. {
    27.         while (1)
    28.         {
    29.                 set_current_state(TASK_UNINTERRUPTIBLE);
    30.                 if (kthread_should_stop()) break;
    31.                
    32.                 *REG_LRADC_CTRL |= (0x1 << 0); //LRADC Enable
    33.                 while (!(*REG_LRADC_INTS & 0x1)) mdelay(1); //Waitting INT
    34.                 ADC[0] = *REG_LRADC_DATA0;
    35.                
    36.                 printk("ADC0: %d\n", ADC[0]);
    37.                 *REG_LRADC_INTS |= (0x1 << 0); //Clear Pending
    38.                
    39.                 schedule_timeout(100);
    40.         }
    41.         
    42.         return 0;
    43. }

    44. static int LRADC_open(struct inode* n, struct file* f)
    45. {
    46.         int Result = 0;

    47.         Inited++;
    48.         if (Inited > 1)
    49.         {
    50.                 return 0;
    51.         }

    52.         REG_LRADC_CTRL = (volatile unsigned long*) ioremap(LRADC_CTRL, 4);
    53.         REG_LRADC_INTC = (volatile unsigned long*) ioremap(LRADC_INTC, 4);
    54.         REG_LRADC_INTS = (volatile unsigned long*) ioremap(LRADC_INTS, 4);
    55.         REG_LRADC_DATA0= (volatile unsigned long*) ioremap(LRADC_DATA0, 4);
    56.         
    57.         *REG_LRADC_INTC |= (0x1 << 0); //ADC0 IRQ Enable
    58.         
    59.         pThread = kthread_create(LRADC_thread, NULL, "GY80");
    60.         if (IS_ERR(pThread))
    61.         {
    62.                 pThread = NULL;
    63.                 printk("Create Thread Error!");
    64.                 return -1;
    65.         }
    66.         wake_up_process(pThread);

    67.         printk("Open Finished!\n");
    68.         return Result;
    69. }

    70. static ssize_t LRADC_write(struct file* f, const char __user* buf, size_t len, loff_t* l)
    71. {
    72.         //printk("Write Finished!\n");
    73.         return 0;
    74. }

    75. static ssize_t LRADC_read(struct file* f, char __user* buf, size_t len, loff_t* l)
    76. {
    77.         //printk("Read Finished!\n");
    78.         return 0;
    79. }

    80. static int LRADC_close(struct inode* n, struct file* f)
    81. {
    82.         Inited--;
    83.         if (Inited > 0)
    84.         {
    85.                 return 0;
    86.         }

    87.         kthread_stop(pThread);
    88.         pThread = NULL;

    89.         *REG_LRADC_CTRL &= ~(0x1 << 0); //LRADC Disable
    90.         
    91.         iounmap(REG_LRADC_CTRL);
    92.         iounmap(REG_LRADC_INTC);
    93.         iounmap(REG_LRADC_INTS);
    94.         iounmap(REG_LRADC_DATA0);

    95.         printk("Close Finished!\n");
    96.         return 0;
    97. }

    98. /**********************************************************************/
    99.         #define DEV_NAME        "LRADC"
    100.         #define DEV_COUNT        1

    101.         static struct class* pClass;
    102.         int major;
    103.         
    104.         static struct file_operations fops =
    105.         {
    106.                 .owner = THIS_MODULE,
    107.                 .open = LRADC_open,
    108.                 .write = LRADC_write,
    109.                 .read = LRADC_read,
    110.                 .release = LRADC_close,
    111.         };

    112. static int __init LRADC_init(void)
    113. {
    114.         major = register_chrdev(0, DEV_NAME, &fops);
    115.         pClass = class_create(THIS_MODULE, DEV_NAME);
    116.         if (pClass == NULL)
    117.         {
    118.                 unregister_chrdev(major, DEV_NAME);
    119.                 return -1;
    120.         }
    121.         device_create(pClass, NULL, MKDEV(major, 0),  NULL, DEV_NAME);
    122.         
    123.         LRADC_open(NULL, NULL);
    124.         //printk("Init Finished!\n");

    125.         return 0;
    126. }

    127. static void __exit LRADC_exit(void)
    128. {
    129.         LRADC_close(NULL, NULL);
    130.         
    131.         unregister_chrdev(major, DEV_NAME);
    132.         if (pClass)
    133.         {
    134.                 device_destroy(pClass, MKDEV(major, 0));
    135.                 class_destroy(pClass);
    136.         }
    137.         //printk("Exit Finished!\n");
    138. }

    139. MODULE_LICENSE("GPL");
    140. MODULE_AUTHOR("LiuYang");
    141. module_init(LRADC_init);
    142. module_exit(LRADC_exit);
    复制代码
    程序没什么好说的,还是为了简单,用了一个线程让它去循环检测。也可以不使用线程放到write、read里控制检测和获取值,看自己的需要了。

    看一下输出结果:
    3.JPG

    由于是用手捏着线和电池,所以有时会有些虚。等读数正常了,可以看到数据是39。
    39是多少伏呢? LRADC是6位,也就是0~63, 计算的话就是 ((39 + 1) / 64) * 2V = 1.25V

    这个结果对吗?还是用表来看一下吧:
    4.JPG


    最后再次感谢爱板网和各位版主管理员以及大家的支持,申请BananaPI试用通过,所以最近几天准备学习下香蕉派,pcDuino先放一放。不过都是全志的东西,寄存器相差不大,后面写笔记会将两种板子合在一起。如果帖子中有错误的地方还请大家多多指教,谢谢!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-3-28 19:29
  • 签到天数: 45 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2014-8-23 15:09:42 | 显示全部楼层
    樓主好厲害~學習中~~幫頂一下!!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-8-15 09:28
  • 签到天数: 222 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2014-8-23 16:05:24 | 显示全部楼层
    学习,帮顶!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2022-9-16 05:52
  • 签到天数: 1368 天

    连续签到: 1 天

    [LV.10]以坛为家III

     楼主| 发表于 2014-8-23 17:14:31 | 显示全部楼层
    感谢楼上两位
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-3-20 21:41
  • 签到天数: 728 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2014-8-24 12:57:21 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2015-8-5 08:38
  • 签到天数: 12 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2014-8-25 22:00:28 | 显示全部楼层
    多谢楼主分享
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2016-8-15 09:30
  • 签到天数: 162 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2014-8-25 22:00:42 | 显示全部楼层
    学习学习
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-22 20:08 , Processed in 0.170636 second(s), 28 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.