查看: 2370|回复: 0

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

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

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2014-11-30 23:14:52 | 显示全部楼层 |阅读模式
    分享到:
    先来说一下A10的ADC。A10的ADC共有两种,一种是LRADC,另一种是TPController。
        LARADC,是一种低分辨率的模数转换器,按照用途A10常把它当作按键检测的通道,可以检测长按、短按、按下、抬起等动作,最高电压可以支持到2V,有些低了。
        TPController一般用来检测触摸屏的控制,根据电压的变化获取坐标。玩过单片机+显示屏的应该都很熟悉,这个功能被集成到A10中了。TPController最大可以支持到5V。
        这次主要试验一下LRADC,对于TPController就不多说了。
        LRADC很简单,简单到所有的寄存器参数都使用默认值,只要控制一下启动就可以了,甚至比IO口都要简单。当然,它也有许多功能,为了简单起见先不考虑。
        本来按照手册说明LRADC可以检测按键的状态,但是还要接按键、电阻,还得动烙铁,有点麻烦;也想过接个光敏电阻,同样还是要找块板子来焊件连线,所以干脆用个最简单的办法,直接测试电池吧。
    接线方式:

    灰线接地,绿线接到ADC0口。
    另一边(忽略蓝线和紫线,没接):

    灰线接电池的负极,绿线接正极。
    好了,下面开始写程序:

    • #include <linux/init.h>
    • #include <linux/module.h>
    • #include <linux/fs.h>
    • #include <linux/cdev.h>
    • #include <linux/device.h>
    • #include <linux/wait.h>
    • #include <linux/delay.h>
    • #include <asm/io.h>
    • #include <asm/uaccess.h>
    • #include <linux/kthread.h>
    • #include <linux/sched.h>
    • #include <linux/err.h>
    • #include "../A10.h"
    •      static uint8_t ADC[2];

    • /**********************************************************************/
    •      volatile static unsigned long* REG_LRADC_CTRL;
    •      volatile static unsigned long* REG_LRADC_INTC;
    •      volatile static unsigned long* REG_LRADC_INTS;
    •      volatile static unsigned long* REG_LRADC_DATA0;

    •      static struct task_struct* pThread;
    •      static int Inited = 0;

    • int LRADC_thread(void* Data)
    • {
    •      while (1)
    •      {
    •             set_current_state(TASK_UNINTERRUPTIBLE);
    •             if (kthread_should_stop()) break;

    •             *REG_LRADC_CTRL |= (0x1 << 0); //LRADC Enable
    •             while (!(*REG_LRADC_INTS & 0x1)) mdelay(1); //Waitting INT
    •             ADC[0] = *REG_LRADC_DATA0;

    •             printk("ADC0: %d\n", ADC[0]);
    •             *REG_LRADC_INTS |= (0x1 << 0); //Clear Pending

    •             schedule_timeout(100);
    •      }

    •      return 0;
    • }
    • static int LRADC_open(struct inode* n, struct file* f)
    • {
    •      int Result = 0;
    •      Inited++;
    •      if (Inited > 1)
    •      {
    •             return 0;
    •      }
    •      REG_LRADC_CTRL = (volatile unsigned long*) ioremap(LRADC_CTRL, 4);
    •      REG_LRADC_INTC = (volatile unsigned long*) ioremap(LRADC_INTC, 4);
    •      REG_LRADC_INTS = (volatile unsigned long*) ioremap(LRADC_INTS, 4);
    •      REG_LRADC_DATA0= (volatile unsigned long*) ioremap(LRADC_DATA0, 4);

    •      *REG_LRADC_INTC |= (0x1 << 0); //ADC0 IRQ Enable

    •      pThread = kthread_create(LRADC_thread, NULL, "GY80");
    •      if (IS_ERR(pThread))
    •      {
    •             pThread = NULL;
    •             printk("Create Thread Error!");
    •             return -1;
    •      }
    •      wake_up_process(pThread);
    •      printk("Open Finished!\n");
    •      return Result;
    • }
    • static ssize_t LRADC_write(struct file* f, const char __user* buf, size_t len, loff_t* l)
    • {
    •      //printk("Write Finished!\n");
    •      return 0;
    • }
    • static ssize_t LRADC_read(struct file* f, char __user* buf, size_t len, loff_t* l)
    • {
    •      //printk("Read Finished!\n");
    •      return 0;
    • }
    • static int LRADC_close(struct inode* n, struct file* f)
    • {
    •      Inited--;
    •      if (Inited > 0)
    •      {
    •             return 0;
    •      }
    •      kthread_stop(pThread);
    •      pThread = NULL;
    •      *REG_LRADC_CTRL &= ~(0x1 << 0); //LRADC Disable

    •      iounmap(REG_LRADC_CTRL);
    •      iounmap(REG_LRADC_INTC);
    •      iounmap(REG_LRADC_INTS);
    •      iounmap(REG_LRADC_DATA0);
    •      printk("Close Finished!\n");
    •      return 0;
    • }
    • /**********************************************************************/
    •      #define DEV_NAME     "LRADC"
    •      #define DEV_COUNT     1
    •      static struct class* pClass;
    •      int major;

    •      static struct file_operations fops =
    •      {
    •             .owner = THIS_MODULE,
    •             .open = LRADC_open,
    •             .write = LRADC_write,
    •             .read = LRADC_read,
    •             .release = LRADC_close,
    •      };
    • static int __init LRADC_init(void)
    • {
    •      major = register_chrdev(0, DEV_NAME, &fops);
    •      pClass = class_create(THIS_MODULE, DEV_NAME);
    •      if (pClass == NULL)
    •      {
    •             unregister_chrdev(major, DEV_NAME);
    •             return -1;
    •      }
    •      device_create(pClass, NULL, MKDEV(major, 0), NULL, DEV_NAME);

    •      LRADC_open(NULL, NULL);
    •      //printk("Init Finished!\n");
    •      return 0;
    • }
    • static void __exit LRADC_exit(void)
    • {
    •      LRADC_close(NULL, NULL);

    •      unregister_chrdev(major, DEV_NAME);
    •      if (pClass)
    •      {
    •             device_destroy(pClass, MKDEV(major, 0));
    •             class_destroy(pClass);
    •      }
    •      //printk("Exit Finished!\n");
    • }
    • MODULE_LICENSE("GPL");
    • MODULE_AUTHOR("LiuYang");
    • module_init(LRADC_init);
    • module_exit(LRADC_exit);
    复制代码
    程序没什么好说的,还是为了简单,用了一个线程让它去循环检测。也可以不使用线程放到write、read里控制检测和获取值,看自己的需要了。
    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

    手机版|小黑屋|与非网

    GMT+8, 2024-12-19 00:46 , Processed in 0.118804 second(s), 17 queries , MemCache On.

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

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.