ADC 模块



/*=========================================================================
  工程名称: 3_AD_driver 
  组成文件: voltage_driver.c
  功能描述: 测试0~3.3V间电压,练习AD采样应用编程
  硬件连接: 引出AIN0~3四个通道
=========================================================================*/


#include <linux/module.h>    /*module_init()*/
#include <linux/kernel.h> /* printk() */
#include <linux/init.h> /* __init __exit */
#include <linux/fs.h> /* file_operation */
#include <asm/uaccess.h> /* copy_to_user, copy_from_user */
#include <linux/device.h>  /*class ,class_create ,device_create 等*/
#include <linux/errno.h> /* Error number */
#include <linux/delay.h> /* mdelay ,ndelay*/
#include <asm/delay.h>     /* udelay */
#include <mach/regs-gpio.h>  /*S3C2410_GPGCON*/
#include <linux/pci.h> /*S3C24XX_VA_GPIO*/


#include <linux/irq.h> //set_irq_type ,IRQ_TYPE_EDGE_FALLING
#include <linux/interrupt.h> //request_irq , free_irq
#include <plat/regs-adc.h>   // S3C2410_ADCCON
#include <asm/io.h> //ioremap()
#include <linux/clk.h> //clk_get() , clk_enable()


#define DEBUG //open debug message


#ifdef DEBUG
#define PRINTK(fmt, arg...) printk(KERN_WARNING fmt, ##arg)
#else
#define PRINTK(fmt, arg...) printk(KERN_DEBUG fmt, ##arg)
#endif


#define DRIVER_NAME "volt_driver"


#define ADCCON   (*(volatile unsigned long *)(regs_adc + S3C2410_ADCCON)) //ADC control
#define ADCDLY   (*(volatile unsigned long *)(regs_adc + S3C2410_ADCDLY)) //ADC start or Interval Delay
#define ADCDAT0  (*(volatile unsigned long *)(regs_adc + S3C2410_ADCDAT0))


static void __iomem *regs_adc;


static int MAJOR_NR = 0; /* Driver Major Number */
static int MINOR_NR = 0; //次设备起始号
struct class *my_class;


static void initADIO(void)
{
unsigned char ch=0;

  ADCDLY = 100; //ADC转换延时
ADCCON =    (0 << 0)     | // ADC转换暂不启动
           (0 << 1)     |  // 使能通过读AD数据触发AD转换
           (0 << 2)     |  // StandBy模式选择
           (ch << 3)    |  // ADC通道选择 ch
           (49 << 6)    | // CLKDIV = Fpclk(50M) /49+1,即转换时钟为1MHz
           (1 << 14)   ; // 使能软件预设值


//ADCCON = (0<<0)|(0<<1)|(0<<2)|(ch<<3)|(49<<6)|(1<<14);
}


//=========================================================================
//名称:AD_ENABLE()
//功能:采用置位使能方式启动AD转换
//参数: 无
//返回值: 无
//=========================================================================
static int getad_enable(void) 
{
int i,j;
int val=0;
unsigned con;


for(i=0;i<16;i++)
{
ADCCON |= 0x1; //使能ADC 转换
while(ADCCON&0x1); //判断是否使能ADC转换
while(!ADCCON&0x8000); //判断ADC转换是否结束
val += (ADCDAT0 &0x03ff); //取出ADC转换值

for(j=0;j<500;j++);
}
val = val/16; //计算ADC平均转换值


return val;
}


//=========================================================================
//名称:AD_READ()
//功能:采用读控制器的方式启动AD转换
//参数: 无
//返回值: 无
//=========================================================================
static int  getad_read (void) 
{
int i,j;
int val;


ADCCON |= 0x2;             //ADC转换通过读操作来启动
val = ADCDAT0 &0x03ff; //启动ADC转换
val = 0;
 
for(i=0;i<16;i++)
{
while(!ADCCON&0x8000); //判断ADC转换是否结束
val += (ADCDAT0 &0x03ff);    //取出ADC转换值
for(j=0;j<500;j++);       
}
val = val/16;                   //计算ADC平均转换值
return val;
}


/* Driver Operation Functions */
static int myDriver_open(struct inode *inode, struct file *filp)
{
int err;
struct clk *adc_clk;

PRINTK("myDriver open called!\n");

adc_clk = clk_get(NULL, "adc");
    if(!adc_clk)
    {
        /*错误处理*/
        PRINTK("falied to find adc clock source\n");
clk_disable(adc_clk);
clk_put(adc_clk);
        return -ENOENT;
    }
    clk_enable(adc_clk);
//S3C2410_PA_ADC是ADC控制器的基地址0x58000000,
//定义在mach-s3c2410/include/mach/map.h中
//0x20是虚拟地址长度大小(总寄存器占地址空间长度)
regs_adc = ioremap(S3C2410_PA_ADC, 0x20); //得到虚地址偏移量
initADIO();
return 0;
}


static int myDriver_release(struct inode *inode, struct file *filp)
{
PRINTK("myDriver release called!\n");
/*释放虚拟地址映射空间*/
    iounmap(regs_adc);
return 0;
}


static ssize_t myDriver_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
int ret = 0;
volatile int value;
volatile int voltage;
volatile unsigned char temp[2];

//value = getad_read();
value = getad_enable();
voltage = 330*value/1024;//voltage/3.3 = value/1024=>voltage=(3.3*value)/1024)*100(为了方便计算放大100倍)

temp[0] = voltage&0xff;
temp[1] = (voltage>>8)&0xff;
ret = copy_to_user(buf, &temp, 2);


return ret;
}


/* Driver Operation structure */
static struct file_operations myDriver_fops = {
owner: THIS_MODULE,
read: myDriver_read,
open: myDriver_open,
release: myDriver_release,
};


static int __init myModule_init(void)
{
/* Module init code */
PRINTK("ADdriver_init\n");
/* Driver register */
MAJOR_NR = register_chrdev(MAJOR_NR, DRIVER_NAME, &myDriver_fops);
if(MAJOR_NR < 0)
{
PRINTK("register char device fail!\n");
return MAJOR_NR;
}
my_class=class_create(THIS_MODULE,"udev_AD");
device_create(my_class,NULL, MKDEV(MAJOR_NR, MINOR_NR), NULL,DRIVER_NAME);

PRINTK("register myDriver OK! Major = %d\n", MAJOR_NR);
return 0;
}


static void __exit myModule_exit(void)
{
/* Module exit code */
PRINTK("exit in\n");
/* Driver unregister */
if(MAJOR_NR > 0)
{
unregister_chrdev(MAJOR_NR, DRIVER_NAME);
device_destroy(my_class,MKDEV(MAJOR_NR, MINOR_NR));
class_destroy(my_class);
PRINTK("myModule_exit ok\n");
}
return;
}


module_init(myModule_init);
module_exit(myModule_exit);


MODULE_LICENSE("GPL");
MODULE_AUTHOR("xiuhai");



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值