TA的每日心情 | 奋斗 2022-9-16 05:52 |
---|
签到天数: 1368 天 连续签到: 1 天 [LV.10]以坛为家III
|
先来说一下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里控制检测和获取值,看自己的需要了。 |
|