普中51开发板,用XPT2046芯片实现AD数模转换。protues仿真用ADC0808实现AD数模转化 | 您所在的位置:网站首页 › 51单片机adc采集电压程序 › 普中51开发板,用XPT2046芯片实现AD数模转换。protues仿真用ADC0808实现AD数模转化 |
普中51开发板,用XPT2046芯片实现AD数模转换。protues仿真用ADC0808实现AD数模转化
实验做完了,总结一下,这些都是做实验的时候自己收集整理总结的资料,下面分享一下 XPT2046芯片: XPT2046的功能很多,这里只介绍怎么用该芯片来完成AD数模转换的实验。 XPT2046 是一种典型的逐次逼近型模数转换器(SAR ADC),包含了采样/保持、模数转换、串口数据输出等功能,因此我们可以用这个芯片来完成本次实验AD转换的内容。 本次实验使用的是XPT芯片的电压模式,首先看下面这个图,了解芯片的引脚和功能,我们要操作的引脚有DCLK 、CS非、DIN 、DOUT: 处理器和转换器之间的的通信需要 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输入)。如下图: SER/ DFR非 :控制参考源模式,选择单端模式(SER/ DFR非 =1),或者差分模式。在单端模式下,转换器的参考电压固定为VREF相对于GND引脚的电压 PD0和PD1:控制掉电和内部参考电压配置的关系。我选择PD1和PD0都为0(为低功率模式)如下图: 这个芯片的AD是逐次逼近式AD,逐次逼近式AD转换器中有一个逐次逼近寄存器SAR,其数字量是由它产生的。 附上图片: 下面介绍一下ADC0808/0809 ADC0808芯片介绍: 内部结构和外部引脚: ADC0808/0809的内部结构和外部引脚分别如图11.19和图11.20所示。内部各部分的作用和工作原理在内部结构图中已一目了然,在此就不再赘述,下面仅对各引脚定义分述如下: ADC 0808/0809工作时序: 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 实验室设备网 版权所有 |