普中51开发板,用XPT2046芯片实现AD数模转换。protues仿真用ADC0808实现AD数模转化 您所在的位置:网站首页 51单片机adc采集电压程序 普中51开发板,用XPT2046芯片实现AD数模转换。protues仿真用ADC0808实现AD数模转化

普中51开发板,用XPT2046芯片实现AD数模转换。protues仿真用ADC0808实现AD数模转化

2024-06-26 21:49| 来源: 网络整理| 查看: 265

普中51开发板,用XPT2046芯片实现AD数模转换。protues仿真用ADC0808实现AD数模转化

实验做完了,总结一下,这些都是做实验的时候自己收集整理总结的资料,下面分享一下

XPT2046芯片: XPT2046的功能很多,这里只介绍怎么用该芯片来完成AD数模转换的实验。 XPT2046 是一种典型的逐次逼近型模数转换器(SAR ADC),包含了采样/保持、模数转换、串口数据输出等功能,因此我们可以用这个芯片来完成本次实验AD转换的内容。 本次实验使用的是XPT芯片的电压模式,首先看下面这个图,了解芯片的引脚和功能,我们要操作的引脚有DCLK 、CS非、DIN 、DOUT: 在这里插入图片描述附上开发板ADC模块的原理图: 在这里插入图片描述 我们主要了解和使用红色圈圈的几个引脚: 在这里插入图片描述 了解完引脚之后,就要看怎么去使用和控制这些引脚来达成目标, 所以接下来要看的就是时序工作图,要了解芯片是如何工作,如何完成采样 保持 量化 编码这几个步骤的.。 一次完整的转换需要 24 个串行同步时钟(DCLK)来完成。(看DCLK时序那,一共出现了3次8, 3*8=24) 在这里插入图片描述 要想启动选中该芯片,首先得给CS和CLK置0 (因为单片机默认引脚输出1) ,然后开始写入数据

处理器和转换器之间的的通信需要 8 个时钟周期,可采用 SPI、SSI 和Microwire 等同步串行接口。前面8个时钟就在进行通信。

前8个时钟就是用来通过DIN引脚输入控制字节。

先看DIN的时序(图中有几个英文单词,Idle的意思是闲置的意思,aquire是获取的意思,conversion是转换的意思,个人理解是图中把DIN在24个时钟周期内的变化,分成了几个段,闲置段,获取段,转换段)DIN的控制位有8位,下面开始从最高位开始介绍:

控制字的首位必须是 1,即 S=1。在 XPT2046 的 DIN 引脚检测到起始位前,所有的输入将被忽略。

A2-A0的选择,由于我选择的是工作在单端模式,则要选中XP输入(至于为什么是XP输入下面解释),所以A2-A0是选择001或者011都可以(二者都能选中XP输入)。如下图: 在这里插入图片描述 我们可以看一下在单端模式下的原理图:(XP是接IN+输入的,所以我们要选中XP输入工作) 在这里插入图片描述 MODE:模式选择位,用于设置 ADC 的分辨率。MODE=0,下一次的转换将是 12 位模式;MODE=1,下一次的转换将是 8 位模式。我选择的是8位

SER/ DFR非 :控制参考源模式,选择单端模式(SER/ DFR非 =1),或者差分模式。在单端模式下,转换器的参考电压固定为VREF相对于GND引脚的电压

PD0和PD1:控制掉电和内部参考电压配置的关系。我选择PD1和PD0都为0(为低功率模式)如下图: 在这里插入图片描述 当DIN的控制字节处理完成之后,转换器进入转换状态,输入采样-保持器进入保持状态,触摸面板驱动器停止工作(单端工作模式)接着的 12 个时钟周期将完成真正的模数转换。

这个芯片的AD是逐次逼近式AD,逐次逼近式AD转换器中有一个逐次逼近寄存器SAR,其数字量是由它产生的。 附上图片: 在这里插入图片描述SAR使用对分搜索法产生数字量,以8位数字量为例,SAR首先产生8位数字量的一半,即b=1000000,试探模拟量Vi的大小。若Vo>Vi,清楚最高度位;反之,则保留最高位。在最高位确认后,SAR又以对分搜索法确定次高位,即以7位数字量的一半1000000(y由前面的过程已确回认)试探模拟量Vi的大小。依此类推,直到确定了bit0为止,转换结束。 在这里插入图片描述 上面的解释可能不是很形象,那就举个具体的例子:模拟量经过内部的DA转换得到一个数字量108 二进制转换就是01101100(暂时称为A),首先先用10000000与A相比,A小于10000000,则第一位为0,保留,开始比较次高位,A大于01000000,则次高位保留1;下一位继续比较,A大于01100000,次次高位保留1,继续比较下一位,A小于01110000,则第4位(从左往右数)保留为0,继续比较,以此类推,一直比较到最后一位。

下面介绍一下ADC0808/0809

ADC0808芯片介绍: 内部结构和外部引脚: ADC0808/0809的内部结构和外部引脚分别如图11.19和图11.20所示。内部各部分的作用和工作原理在内部结构图中已一目了然,在此就不再赘述,下面仅对各引脚定义分述如下: 在这里插入图片描述 图11.19 ADC0808/0809内部结构框图 在这里插入图片描述 图11.20 ADC0808/0809外部引脚图 (1) IN0~IN7——8路模拟输入,通过3根地址译码线ADDA、ADDB、ADDC来选通一路。 (2)D7~D0——A/D转换后的数据输出端,为三态可控输出,故可直接和微处理器数据线连接。8位排列顺序是D7为最高位,D0为最低位。 (3)ADDA、ADDB、ADDC——模拟通道选择地址信号,ADDA为低位,ADDC为高位。地址信号与选中通道对应关系如表11.3所示。 (4)VR(+)、VR(-)——正、负参考电压输入端,用于提供片内DAC电阻网络的基准电压。在单极性输入时,VR(+)=5V,VR(-)=0V;双极性输入时,VR(+)、VR(-)分别接正、负极性的参考电压。 (5)ALE——地址锁存允许信号,高电平有效。当此信号有效时,A、B、C三位地址信号被锁存,译码选通对应模拟通道。在使用时,该信号常和START信号连在一起,以便同时锁存通道地址和启动A/D转换。 (6)START——A/D转换启动信号,正脉冲有效。加于该端的脉冲的上升沿使逐次逼近寄存器清零,下降沿开始A/D转换。如正在进行转换时又接到新的启动脉冲,则原来的转换进程被中止,重新从头开始转换。 (7)EOC——转换结束信号,高电平有效。该信号在A/D转换过程中为低电平,其余时间为高电平。该信号可作为被CPU查询的状态信号,也可作为对CPU的中断请求信号。在需要对某个模拟量不断采样、转换的情况下,EOC也可作为启动信号反馈接到START端,但在刚加电时需由外电路第一次启动。 (8)OE——输出允许信号,高电平有效。当微处理器送出该信号时,ADC0808/0809的输出三态门被打开,使转换结果通过数据总线被读走。在中断工作方式下,该信号往往是CPU发出的中断请求响应信号。

ADC 0808/0809工作时序: 在这里插入图片描述 ADC 0808/0809的工作时序如图11.21所示。 当通道选择地址有效时,ALE信号一出现,地址便马上被锁存,这时转换启动信号紧随ALE之后(或与ALE同时)出现。START的上升沿将逐次逼近寄存器SAR复位,在该上升沿之后的2μs加8个时钟周期内(不定),EOC信号将变低电平,以指示转换操作正在进行中,直到转换完成后EOC再变高电平。微处理器收到变为高电平的EOC信号后,便立即送出OE信号,打开三态门,读取转换结果。

END

有什么地方不对的地方,欢迎指出。

开发板实验代码:

/****************************************************************** 功能: 数码管前2位显示AD字符,后三位电位器的数字量,最后三位显示对应电压值 实体机接线: 1,单片机-->AD/DAC模块 P34-->DI P35-->CS P36-->CL P37-->DO 2,单片机-->动态数码管模块 (P0端口)J22-->J6(动态数码管段选) P20-->J9(A) P21-->J9(B) P22-->J9(C) ******************************************************************/ #include "reg52.h" //单片机头文件 #include //含_nop_()函数 #define uchar unsigned char #define uint unsigned int sbit LSA=P2^0; sbit LSB=P2^1; sbit LSC=P2^2; sbit DIN=P3^4; //串口输入 sbit CS=P3^5; //片选 sbit CLK=P3^6; //时钟脉冲 sbit DOUT=P3^7; //串口输出 uchar disp[8]; //储存读取的数据的每个位数,由数码管输出 uchar code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void delay(uint i)//延时子程序,因为本程序的延时不需要到ms级别,所以没有用之前的用法 { while(i--); } void SPI_Write(uchar dat) //dat传输的是9C这个控制指令 { uchar i; CLK = 0; for(i=0;i uint i, dat=0; //dat用来存放读取的数据 CLK = 0; for(i=0; i uchar i; uint AD_Value; CLK = 0; //默认引脚输出1,这里要先软件置0 CS = 0; //置0选中,启动AD SPI_Write(cmd);//写入数据 for(i=6;i>0;i--); //延时等待转换结果 CLK=0; _nop_(); CLK = 1; //发送一个正脉冲,清除BUSY ,表示可以开始转换了 _nop_(); CLK = 0; _nop_(); _nop_(); AD_Value=SPI_Read(); //AD_Value存放数据 CS = 1; //CS拉高,读取完毕 return AD_Value; } void datapros() { uint temp,val; uchar i; if(i==50) { temp = Read_AD_Data(0x9c); /* 0x9c是给DIN输入控制字节,9c=10011100, 具体的每一位是什么作用可以看芯片手册 */ val=temp*100/51;//原来式子是(((temp*5*100)/255)),把temp先扩大100倍然后乘以5除以255得到电压值; } i++; disp[0]=0x77;//显示A disp[1]=0x5e;//显示D disp[2]=smgduan[temp/100];//百位 disp[3]=smgduan[temp/10%10];//十位 disp[4]=smgduan[temp%10];//个位 disp[5]=smgduan[val/100] |0x80; //与0x80相或来得到小数点 disp[6]=smgduan[val/10%10]; disp[7]=smgduan[val%10]; } void DigDisplay() { uchar i; for(i=0;i case(0): LSA=0;LSB=0;LSC=0; break;//显示第0位 case(1): LSA=1;LSB=0;LSC=0; break;//显示第1位 case(2): LSA=0;LSB=1;LSC=0; break;//显示第2位 case(3): LSA=1;LSB=1;LSC=0; break;//显示第3位 case(4): LSA=0;LSB=0;LSC=1; break;//显示第4位 case(5): LSA=1;LSB=0;LSC=1; break;//显示第5位 case(6): LSA=0;LSB=1;LSC=1; break;//显示第6位 case(7): LSA=1;LSB=1;LSC=1; break;//显示第7位 } P0=disp[i];//发送数据 delay(100); //间隔一段时间扫描 P0=0x00;//消隐 } } void main() { while(1) { datapros(); //数据处理函数 DigDisplay();//数码管显示函数 } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有