分享

linux设备驱动学习笔记6

 XeonGate 2015-08-18

AD转换学习-模拟spi时序

http://bbs./BLOG_ARTICLE_296114.HTM

设备驱动学习记录:

http://bbs./blog_index.jspa?blog_id=337002&entry_month=&viewall=true&curr_page=1&sort=0

AD的分类:


时间/数字、电压/数字、机械变量/数字


在嵌入式系统中用的最多的是电压/数字转换器


电压/数字转换器可以分为多种类型:


转换方式:直接转换和间接转换


输出方式:串行、并行、串并行


转换原理:计数式、比较式


转换速度:低速、中速、高速


转换精度:3位、4位、8位、10位、12位、14位、16位等


 


计数式AD


这里以8位计数式AD为例


点击看大图


计数式AD的转换过程:


1),CLR有效(高电平变成低电平),使计数器输出数字信号为00000000,这个00000000的输出送到8D/A转换器,8D/A转换器的输出也是0V


2),当CLR恢复为高电平时,计数器准备计数,此时,在计数器输入端上待转换的模拟输入电压为Vi大于Vo,比较器输出电压c1,这样计数器开始计数


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与s3C2410硬件接口电路


3C2410与ADS7844的~种硬件连接图。其中用GPDl3产生片选信号,GPEl3产生时钟信号,GPG2用来接信号引脚GPEl2GPEll分别与ADS7844DINDOUT连接。由于使用的$3C2410的标准SPI接口,所有软件上有2种方法进行处理,一种是使用标准的SPI协议进行数据转换,另一种是使用I0模拟SPI协议的方式进行数据转换。为了软件简便,使用第2种数据转换方式


点击看大图


驱动程序(基于Linux26内核)的整体框架:


 


#include<linuxinith> //模块加载和卸载相关


#include<linuxmaduleh> //MODULE_LICENSE()


#include<linuxkemelh> //printk()函数


#include<asmarchregs_gpioh> //$3C2410内部寄存器宏定义


#include<asmhardwareh> //s3c2410_gpio_cfgpin()等函数


 


//ADS7844字符设备结构体定义


struct ads7844_dev


{


struct cdev cdev


unsigned int channel;//通道号


unsigned int adc[8];//8路采集值


}


 


ADS7844设备注册和卸载


int ads7844_init(void)


{


int resulti


dev_t devno="MKDEV"(ads7844_major0)


if(ads7844_major)


result=register_chrdev_region(devno1DEVICE_NAME)


//指定设备号


else


{


result=alloc_chrdev_region(&devno0,1DEVICE_NAME)//动态生成设备号


ads7844_major=MAJOR(devno)


}


if(result<0)return result


ads7844_setup_cdev(ads7844_devp0);//初始化字符设备


.


.


.


}


void ads7844_exit(void)


{


cdev_del(&ads7844_devp->cdev);//移除字符设备


.


.


.


unregister_chrdev_region(MKDEV(ads7844_major0)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_write2个函数。了解整个驱动设计的框架后,读写函数的实现就比较简单


 


读操作中数据移出的过程


.


.


.


for(i=0i<16i++)


{


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;//移出低位多余的40”

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多