AD转换学习<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
AD的分类:
时间/数字、电压/数字、机械变量/数字
在嵌入式系统中用的最多的是电压/数字转换器
电压/数字转换器可以分为多种类型:
转换方式:直接转换和间接转换
输出方式:串行、并行、串并行
转换原理:计数式、比较式
转换速度:低速、中速、高速
转换精度:3位、4位、8位、10位、12位、14位、16位等
计数式AD
这里以8位计数式AD为例
计数式AD的转换过程:
(1),CLR有效(高电平变成低电平),使计数器输出数字信号为00000000,这个00000000的输出送到8位D/A转换器,8位D/A转换器的输出也是0V
(2),当CLR恢复为高电平时,计数器准备计数,此时,在计数器输入端上待转换的模拟输入电压为Vi大于Vo,比较器输出电压c位1,这样计数器开始计数
(3),计数器的输入不断增加,D/A转换器输出的模拟电压(Vo)也在不断的增加,当Vo小于Vi时,计数器不断的计数
(4),当Vo上升到某值时,出现Vo>Vi的情况,此时,比较器的输出电压为低电平,使计数器控制信号c=0,计数器停止计数,此时,数字量D0~D7就是模拟电压等效。计数器控制信号由高变为低的副跳变也是A/D转换的结束信号,表示完成一次A/D转换。
优缺点:结构简单,但是转换速度慢。
逐次逼近式A/D转换
逐次逼近式A/D转换的原理
A/D转换开始前,先将SAR寄存器清0,然后进行转换,时钟信号首先将寄存器的最高位置1,使输出为100….000,这个数字将被DA转换器转换成模拟电压Vo送到比较器与Vi进行比较
当Vo大于Vi的时候,这个位的2进制码将会被改为0,如果Vo小于Vi,那么之前位的1将被保留,一直到最低位为止。比较器的值就是所要求的数值输出。
接下来就以ADS7844位例,粗略的分析下linux下编写AD转换驱动
ADS7844的具体的工作原理网上很多,这里就不做介绍了。
ADS7844与s<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />3C2410硬件接口电路
3C2410与ADS7844的~种硬件连接图。其中用GPDl3产生片选信号,GPEl3产生时钟信号,GPG2用来接“忙”信号引脚GPEl2、GPEll分别与ADS7844的DIN和DOUT连接。由于使用的$3C2410的标准SPI接口,所有软件上有2种方法进行处理,一种是使用标准的SPI协议进行数据转换,另一种是使用I/0模拟SPI协议的方式进行数据转换。为了软件简便,使用第2种数据转换方式
驱动程序(基于Linux2.6内核)的整体框架:
#include<linux/init.h> //模块加载和卸载相关
#include<linux/madule.h> //MODULE_LICENSE()
#include<linux/kemel.h> //printk()函数
#include<asm/arch/regs_gpio.h> //$3C2410内部寄存器宏定义
#include<asm/hardware.h> //s3c2410_gpio_cfgpin()等函数
//ADS7844字符设备结构体定义
struct ads7844_dev
{
struct cdev cdev;
unsigned int channel;//通道号
unsigned int adc[8];//8路采集值
}
ADS7844设备注册和卸载
int ads7844_init(void)
{
int result,i;
dev_t devno="MKDEV"(ads7844_major,0);
if(ads7844_major)
result=register_chrdev_region(devno,1,DEVICE_NAME);
//指定设备号
else
{
result=alloc_chrdev_region(&devno,0,1,DEVICE_NAME);//动态生成设备号
ads7844_major=MAJOR(devno);
}
if(result<0)return result;
ads7844_setup_cdev(ads7844_devp,0);//初始化字符设备
.
.
.
}
void ads7844_exit(void)
{
cdev_del(&ads7844_devp->cdev);//移除字符设备
.
.
.
unregister_chrdev_region(MKDEV(ads7844_major,0),1);
//释放设备号
}
ADS7844设备具体操作设计与实现
在设备注册过程中,构建了ADS7844_fops结构指针。在file_operations结构中定义了一组函数指针。
static const struct file_operations ads7844_fops=
{
.owner=THIS_MODULE,
.open=ads7844_open,
.read=ads7844_read,
.write=ads7844-_write,
.release=ads7844_release,
};
系统就是通过这一组函数指针来实现ADS7844设备的操作的。具体说来,主要有2个方面的工作:
一是对ADS7844进行工作方式的设置和通道的选择;
二是从设备中获取采样数据的信息。它们分别对应ADS7844_read ADS7844_write这2个函数。了解整个驱动设计的框架后,读写函数的实现就比较简单
读操作中数据移出的过程
.
.
.
for(i=0;i<16;i++)
{
ads7844_result<<=1;//将刚读出的数据移到高位
s3c2410_gpio_setpin(ads7844_table[0],1);//设置时钟为高
udelay(100);
s3c2410_gpio_setpin(ads7844_table[0],0);//设置时钟为低
if(s3c2410_gpio_getpin(ads7844_table[2]))//下降沿读出一位数据
ads7844_resuh |=1;
udelay(100);
}
ads7844_result>>=4;//移出低位多余的4个”0”
.
.
.
用户367244 2011-6-23 11:01
用户367244 2011-6-23 10:59