S3C2440 ADC采样光敏电阻传感器驱动
通过光敏电阻传感器获取外界光线的变化,并通过ADC采样,上报,获取阻值。电路接口图如下。
驱动实现
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/of.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <plat/gpio-cfg.h>
#include <mach/regs-gpio.h>
#include <linux/input.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/sched.h>#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>//#define DEB_PRINTk printk
#define DEB_PRINTk(...)#define LM393_MAJOR 253 /* 主设备号 */struct s3c_adc_regs { unsigned long adccon;unsigned long adctsc;unsigned long adcdly;unsigned long adcdat0;unsigned long adcdat1;unsigned long adcupdn;
};struct s3c_adc_dev { wait_queue_head_t wait; int data; int flag;
}; static volatile struct s3c_adc_regs *s3c_adc_regs;
static struct s3c_adc_dev s3c_adc_dev;static struct class *lm393_class;
static struct clk *clock;//ADC中断服务
static irqreturn_t adc_irq(int irq, void *dev_id)
{s3c_adc_dev.data = (s3c_adc_regs->adcdat0 & 0x3ff); //获取转换数据s3c_adc_dev.flag = 1; wake_up_interruptible(&s3c_adc_dev.wait); //唤醒等待事件 return IRQ_HANDLED;
} static int lm393_drv_open (struct inode *inode, struct file *file)
{s3c_adc_regs->adccon = (1<<14) | (49<<6) | (0x01<<3); s3c_adc_regs->adcdly = 0xff;s3c_adc_dev.data = 0; s3c_adc_dev.flag = 0; init_waitqueue_head(&s3c_adc_dev.wait); //初始化等待事件return 0;
}static ssize_t lm393_drv_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
{int err;/* [15] : ECFLG, 1 = End of A/D conversion* [14] : PRSCEN, 1 = A/D converter prescaler enable* [13:6]: PRSCVL, adc clk = PCLK / (PRSCVL + 1)* [5:3] : SEL_MUX, 000 = AIN 0* [2] : STDBM* [0] : 1 = A/D conversion starts and this bit is cleared after the startup.*/s3c_adc_regs->adccon |= (0x01) | (0x01<<14) | (0x01<<3) | (49<<6);wait_event_interruptible(s3c_adc_dev.wait, s3c_adc_dev.flag); //等待ADC转换完成s3c_adc_dev.flag = 0; err = copy_to_user(buf,(char*)&s3c_adc_dev.data,sizeof(s3c_adc_dev.data)); return err? -EFAULT:sizeof(s3c_adc_dev.data);
}/*字符设备的相关操作实现*/
static struct file_operations lm393_drv_fops = {.owner = THIS_MODULE, .open = lm393_drv_open, .read = lm393_drv_read,
};static int __init lm393_drv_init(void)
{int retval = 0;retval = register_chrdev(0, "lm393_drv", &lm393_drv_fops);if (retval < 0){DEB_PRINTk(" can't register major number\n");return retval;}lm393_class = class_create(THIS_MODULE, "lm393_drv");device_create(lm393_class, NULL, MKDEV(LM393_MAJOR, 0), NULL, "lm393"); // /dev/lm393s3c_adc_regs = ioremap(0x58000000, sizeof(struct s3c_adc_regs)); //地址映射clock = clk_get(NULL, "adc"); //获取ADC 时钟并启动操作if (!clock) {DEB_PRINTk(KERN_ERR "failed to get adc clock source\n"); return -ENOENT; } clk_enable(clock);retval = request_irq(IRQ_ADC, adc_irq, IRQF_SAMPLE_RANDOM, "adc", NULL); //申请ADC中断服务if (retval) {DEB_PRINTk("Error requesting IRQ_ADC\n");return -1;}DEB_PRINTk("Register success!\n");return 0;
}static void __exit lm393_drv_exit(void)
{iounmap(s3c_adc_regs);unregister_chrdev(LM393_MAJOR, "lm393_drv"); // 卸载device_destroy(lm393_class, MKDEV(LM393_MAJOR, 0));class_destroy(lm393_class);DEB_PRINTk("Unregister success!\n");
}module_init(lm393_drv_init);
module_exit(lm393_drv_exit);MODULE_LICENSE("GPL v2");
验证测试
## 测试程序#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#define DEB_PRINTF printf//#define DEB_PRINTF(...)int main(int argc, char **argv){int i, ret, fd, adc_data;char result[4];DEB_PRINTF("will open fd... \n");if((fd = open("/dev/lm393",O_RDONLY)) < 0 ){DEB_PRINTF("open device lm393 fail.\n");return -1;}else{DEB_PRINTF("Open Device lm393 Successful!!\n");}ret = read(fd, result, sizeof(result));if(ret != sizeof(result)){DEB_PRINTF("read wrong\n");DEB_PRINTF("ret = %d\n", ret);return -1;}else {DEB_PRINTF("read success !\n");}for (i = 0; i < ret; i++){adc_data = result[0] + (int)(result[1]<<8); DEB_PRINTF("adc value = %d (%.2f V) \n",adc_data, adc_data/1024.0*3.3); }close(fd);return 0;}
测试结果如图
S3C2440 ADC采样光敏电阻传感器驱动相关推荐
- adc采样的值跳动_嵌入式er必知:模数采样知多少(最全总结)
[导读] 生活环境周围信号万万千,对于一个嵌入式er.我们利用技术去了解世界.改变世界.而一个产品要与外界物理环境打交道,一个至关重要的触角就是采样真实模拟世界的信号,翻译成芯片可理解的数字信号,进 ...
- 【 FPGA 】使用状态机设计一个ADC采样控制电路
以ADC0809为例,设计一个ADC采样控制电路,采用有限状态机的方式. 传统的ADC采样控制的方法是用单片机控制,单片机控制ADC采样具有编程简单,控制灵活的优点,但是采样速度慢,CPU控制的低速极 ...
- 解读ADC采样芯片(EV10AQ190A)的工作模式(单通道模式)
有了上两篇博文的铺垫,双通道模式以及四通道模式,单通道模式也就很容易理解了,并且我已经想好了下一篇博文要写什么了. 直接看框架图吧: 直接说重点,任意一个输入端口输入的模拟信号同时进入ADC芯片的四个 ...
- 解读ADC采样芯片(EV10AQ190A)的工作模式(四通道模式)
上篇博文讲了EV10AQ190A这种ADC芯片的工作模式:双通道模式 我十分重视这些内容,因为这是我认识硬件工作模式的起点,当然这也只是理论上的内容,实际采样过程中也许会遇到这样那样的问题,那就需要自 ...
- 解读ADC采样芯片(EV10AQ190A)的采样(工作)模式(双通道模式)
工作模式有三种:分别为四通道模式.双通道模式以及单通道模式,这里先简单讲述双通道模式(由于工程中用过双通道模式): 双通道模式组态: 从这张图中可以得到的信息是什么呢? 首先有两个模拟输入,分别为AA ...
- 基于android7.1+msm8937读取ADC采样值
基于android7.1+msm8937读取ADC采样值 读取给设备供电的电压,比如16V,通过监控ADC(Analog-to-Digital Conversion)值来知道电源波动情况和实际给设备供 ...
- STM32的ADC采样与多通道ADC采样
一 单通道采样 参考资料: <STM32库开发实战指南> 刘火良,杨森著 原理性质的东西还是少讲,因为上面那本书里面讲解的很详细了,直接来看硬件电路图 这里使用的是3362电位器(10K ...
- matlab 信号去直流,基于FIR滤波的ADC采样信号中直流信号的消除方法与流程
本发明属于卫星导航领域,介绍了ADC采样信号中的直流偏置消除方法. 背景技术: 卫星导航系统在军事和民用领域应用越来越广泛.以GPS卫星导航系统为例,其到地面的信号功率仅为-130dBm,这么微弱的信 ...
- STM32 ADC采样使用内部参考电压
整理也能进步!写得清楚才能理解更深. [问题背景] 在使用ADC时,通常的用法是Vref+接电源VDD3.3V,然后计算时直接用3.3V做参考电压,但是这种方法忽略了一些情况如供电电压有可能随外部一些 ...
- STM32F103单片机使用DMA功能读取ADC采样数据
使用DMA功能操作外设时,可以极大的简化代码,提高程序的执行效率.特别是在需要频繁操作的外设上.比如现在要采集单片机16个ADC通道的电压值,就可以使用DMA功能,直接将ADC通道转换好的值,传输 ...
最新文章
- PostgreSQL数据库服务端监听设置及客户端连接方法教程
- 50个Android开发人员必备UI效果源码[转载]
- js动态载入css文件,原生JS动态加载JS、CSS文件及代码脚本(示例代码)
- Git学习——提交BUG
- vue项目中axios的封装
- 小米9android q测试版,基于Android Q的MIUI来了 小米9尝鲜
- 超级仿制药行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
- java 数据字典使用_java中数据字典怎么用?图文详解
- 在Ubuntu中下载github上的文件
- 操作系统原理(一)操作系统的认识
- 自动驾驶路径规划——A*(Astar)算法
- 如何识别服务器连接的偶发故障?
- 残疾人竞赛计算机程序,第五届全国残疾人职业技能竞赛竞赛标准计算机程序.doc...
- [论文笔记]CAB:CAching in Buckets CAB-ACME
- libxml主要函数说明
- 联想拯救者2020R7000双系统装机记录_自用
- Pandas含中文表格对齐输出
- 大学计算机思维导论第一讲测验答案,第一讲导论习题.doc
- 写一个WFP驱动,拦截网络
- Unity: How to build and debug external DLLs