mini6410 实现 linux adc驱动详解

在嵌入式学习中嵌入式linux驱动占据着十分重要的地位,它不仅牵扯到操作系统、linux内核知识,同时作为开发者你必须了解面对的硬件体系结构和工作原理。在这本人muge0913对linux ad开发做了详细的介绍。

http://blog.csdn.net/muge0913/article/details/7059241

一、ad转换器介绍

在这里我们先从adc的工作原理出发,由浅入深的学习,对于已经掌握adc硬件知识的阅读者可跳过此部分。

adc的基础知识我们可直接参考郭天祥老师的教材,免积分下载地址:

http://download.csdn.net/detail/muge0913/3903535

二、ARM中ad转换器介绍

这里我们以arm11为例:

①简介:

.

10-bit/12-bit的CMOSADC(模数转换器)是一个8通道模拟输入的回收型设备。5MHz的A / D转换时钟,最高转换率的1MSPS转换到10-bit/12-bit二进制数字编码的模拟输入信号。A / D转换片上采样和保持功能。支持省电模式。②特性:③配置:如果简单的驱动ad,只配置ADCCON寄存器即可,如要实现触摸屏的工能则要其他寄存器注:在下面代码中我们由此部分的注释三、linux中的adc驱动程序及注释

#include <linux/kernel.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/input.h>#include <linux/init.h>#include <linux/errno.h>#include <linux/serio.h>#include <linux/delay.h>#include <linux/clk.h>#include <linux/sched.h>#include <linux/cdev.h>#include <linux/miscdevice.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <mach/map.h>#include <mach/regs-clock.h>#include <mach/regs-gpio.h>#include <plat/regs-adc.h>static void __iomem * base_addr;static struct clk *adc_clock;#define __ADCREG(name)(*(volatile unsigned long *)(base_addr + name))#define ADCCON__ADCREG(S3C_ADCCON)// ADC control#define ADCTSC__ADCREG(S3C_ADCTSC)// ADC touch screen control#define ADCDLY__ADCREG(S3C_ADCDLY)// ADC start or Interval Delay#define ADCDAT0__ADCREG(S3C_ADCDAT0)// ADC conversion data 0#define ADCDAT1__ADCREG(S3C_ADCDAT1)// ADC conversion data 1#define ADCUPDN__ADCREG(S3C_ADCUPDN)// Stylus Up/Down interrupt status#define PRESCALE_DIS(0 << 14)#define PRESCALE_EN(1 << 14)#define PRSCVL(x)((x) << 6)#define ADC_INPUT(x)((x) << 3)#define ADC_START(1 << 0)#define ADC_ENDCVT(1 << 15)#define DEVICE_NAME "adc_dev"static int adc_init(){unsigned int preScaler = 0XFF;ADCCON = (1<<14)|(preScaler<<6)|(0<<3)|(0<<2);ADCCON |= ADC_START; return 0;}static int adc_open(struct inode *inode ,struct file *filp){adc_init();return 0;}static int adc_release(struct inode *inode,struct file *filp){return 0;}static ssize_t adc_read(struct file *filp,char __user *buff,size_t size,loff_t *ppos){ADCCON |= ADC_START; while(ADCCON & 0x01);//check if Enable_start is lowwhile(!(ADCCON &0x8000));/*检查转换是否结束*/return (ADCDAT0 & 0x3ff);}static struct file_operations dev_fops ={.owner = THIS_MODULE,.open = adc_open,.release = adc_release,.read = adc_read,};static struct miscdevice misc ={.minor = MISC_DYNAMIC_MINOR,.name = DEVICE_NAME,.fops = &dev_fops,};static int __init dev_init(){int ret;base_addr =ioremap(SAMSUNG_PA_ADC,0X20);//地址映射if(base_addr == NULL){printk(KERN_ERR"failed to remap\n");return -ENOMEM;}adc_clock = clk_get(NULL,"adc");//激活adc时钟模块if(!adc_clock){printk(KERN_ERR"failed to get adc clock\n");return -ENOENT;}clk_enable(adc_clock);ret = misc_register(&misc);//混杂设备注册printk("dev_init return ret:%d\n",ret);return ret;}static void __exit dev_exit(){iounmap(base_addr);//取消映射if(adc_clock)//disable adc clock取消adc时钟{clk_disable(adc_clock);clk_put(adc_clock);adc_clock =NULL;}misc_deregister(&misc);//注销混杂设备}module_init(dev_init);module_exit(dev_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("MUGE0913");

四、测试程序

#include <stdio.h>#include <fcntl.h>#include <unistd.h>int main(){int fp,adc_data,i;fp = open("/dev/adc_dev",O_RDWR);for(i=0;i<100;i++){adc_data = read(fp,NULL,0);printf("%d\n",adc_data);sleep(1);}close(fp);return 0;}

五、运行效果

在旅途中,我遇见了你,你我相识是缘分!看着你手中的戒指,

mini6410 实现 linux adc驱动详解

相关文章:

你感兴趣的文章:

标签云: