您的位置:首页 > 运维架构

iTop4412之ADC驱动开发

2017-01-15 15:11 417 查看
adc.c
#include<linux/module.h>
#include<linux/init.h>
#include<linux/platform_device.h>
#include<linux/interrupt.h>
#include<linux/fs.h>
#include<linux/wait.h>
#include<linux/sched.h>
#include<linux/uaccess.h>
#include<linux/io.h>
#include<linux/cdev.h>
#include<linux/irq.h>
#define ADCCON 0x126c0000
#define ADCDAT 0x126c000c
#define ADCMUX 0x126c001c
#define ADCCLEAR 0x126c0018
struct cdev adccdev;
static wait_queue_head_t wq;
dev_t devid;
static int have_data;
static int adc;
unsigned int *adccon;
unsigned int *adcdat;
unsigned int *adcmux;
unsigned int *adcclear;
static irqreturn_t adc_interrupt(int irqno,void *dev)//中断处理函数
{
have_data=1;//转换完成标志位,
writel(0x12,adcclear);//清除中断标志位
wake_up_interruptible(&wq);//唤醒等待队列
return IRQ_HANDLED;
}
static int adcinit()
{
request_irq(IRQ_ADC,adc_interrupt,IRQF_DISABLED,"adc1",NULL);//申请中断
adccon=ioremap(ADCCON,4);//物理地址到虚拟地址映射
adcdat=ioremap(ADCDAT,4);
adcmux=ioremap(ADCMUX,4);
adcclear=ioremap(ADCCLEAR,4);
init_waitqueue_head(&wq);初始化等待队列
return 0;
}

static ssize_t adc_read(struct file *filep,char __user *buf,size_t len, loff_t *pos)
{
writel(0x3,ADCMUX);//选择转换通道
writel(1<<0|0x1<<16|0xff<<6,ADCCON);//启动12位AD转换
wait_event_interruptible(wq,have_data==1);//进入等待队列
adc=readl(adcdat)&0xfff;
if(copy_to_user(buf,&adc,sizeof(int)))
{
return -EFAULT;
}
have_data=0;
return len;
}
static int adc_release(struct inode *inode,struct file *file)
{
return 0;
}
static int adc_open(struct inode *inde,struct file *file)
{
return 0;
}
struct file_operations adcops={
.owner=THIS_MODULE,
.open=adc_open,
.read=adc_read,
.release=adc_release,
};
static void adc_init()
{
cdev_init(&adccdev,&adcops);
alloc_chrdev_region(&devid, 0 , 1 , "adc12");
cdev_add(&adccdev,devid,1);
adcinit();
}
static void adc_exit()
{
unregister_chrdev_region(&devid,1);
cdev_del(&adccdev);
}
MODULE_LICENSE("GPL");
module_init(adc_init);
module_exit(adc_exit);


insmod ADC.ko

mknod /dev/adc c 248 0

用户测试程序

APP_ADC.c
#include<linux/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
int main(int argc char **argv)
{
int fd,len;
int adc;
fd=open("dev/adc",O_RDWR);
if(fd<0)
{
perror("open fail\n");
return;
}
while(1){
read(fd,&adc,4);
printf("adc%0.2f V\n",(1.8*adc)/4096);
}
close(fd);
}


./APP_ADC

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  驱动开发 iTop4412 ADC