AD转换器ADC0832程序
- 格式:doc
- 大小:19.50 KB
- 文档页数:3
1.ADC0832驱动子程序#include <REGX51.H>#include <intrins.h> //常用汇编指令引用。
unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x83,0xf8,0x80,0x98}; //共阳代码//接口电路sbit AD0832_CS = P3^5ﻩ; //片选信号sbit AD0832_CLK = P3^6; //时钟接口sbit AD0832_DI = P3^7; //数据接口void main( void){unsigned char i=0 , x =0 , y = 0 ;unsigned int temp=0;while(1){//时钟12Mhz, 整个转换时间为224us//使用芯片准备(参考PDF时序图)ﻩAD0832_CLK = 0 ; //时钟置低平ﻩ AD0832_DI = 1 ; //开始信号为高电平ﻩ AD0832_CS = 0;//片选信号置低,启动AD转换芯片//输入开始信号(构成一个正脉冲)_nop_();ﻩAD0832_CLK = 1 ; //时钟上升沿,输入开始信号_nop_();ﻩ AD0832_CLK = 0 ; //时钟下降沿//模拟信号输入模式选择(1:单模信号,0:双模差分信号)AD0832_DI = 1 ;ﻩ _nop_();ﻩ AD0832_CLK = 1 ; //时钟上升沿,输入开始信号ﻩ _nop_();AD0832_CLK = 0 ; //时钟下降沿//模拟信号输入通道选择(1:通道CH1,0:通道CH0)AD0832_DI = 0 ; //选择通道0_nop_();ﻩAD0832_CLK = 1 ; //时钟上升沿,输入开始信号_nop_();ﻩ AD0832_CLK = 0 ; //时钟下降沿///////////////////////////////////////////AD0832_DI = 1; //数据线置高,准备接收数据for(i = 0 ; i<8 ; i++)ﻩ //从高位移入数据{ﻩ AD0832_CLK = 1 ;_nop_();AD0832_CLK = 0 ; //时钟下降沿,AD0832输出数据,高位(MSB)先x = x<<1;ﻩﻩﻩ//数据左移位,补0if(AD0832_DI ==1)ﻩx = x | 0x01; //如果数据为“1”,移入1,} ﻩﻩﻩﻩ //如果数据为“0”,移入0,for(i = 0 ; i<8 ; i++)ﻩ //从低位移入数据ﻩ{y = y>>1; ﻩ//数据左移位,补0if(AD0832_DI==1)ﻩy =y| 0x80;ﻩ //如果数据为“1”,移入1,ﻩﻩﻩ//如果数据为“0”,移入0ﻩ AD0832_CLK = 1 ;_nop_();ﻩAD0832_CLK = 0 ; //时钟下降沿,AD0832输出数据,高位(MSB)先}//数据线置高,释放总线,完成一次转换AD0832_CLK = 1 ;ﻩ AD0832_DI = 1 ;AD0832_CS = 1 ;ﻩﻩ if(x==y) //输出{ﻩ temp = x *2 ; //(参考电压为5V,8位。
adc0832模块程序/* ADC0832差分00工作方式*/#include#include"adc0832.h"#include"1602.h"sbit ADC_CS =P2^0;sbit ADC_CLK=P2^1;sbit ADC_DO =P2^2;sbit ADC_DI =P2^3;unsigned char adval;unsigned char ReadADC(void) //把模拟电压值转换成8位二进制数并返回{unsigned char i,ch,bb,cc,dd;ch=0;ADC_CS=0;ADC_DO=0;//片选,DO为高阻态for(i=0;i<10;i++){;}ADC_CLK=0;delay(2);ADC_DI=1;ADC_CLK=1;delay(2); //第一个脉冲,起始位ADC_CLK=0;delay(2);ADC_DI=1;ADC_CLK=1;delay(2); //第二个脉冲,DI=1表示双通道单极性输入ADC_CLK=0;delay(2);ADC_DI=1;ADC_CLK=1;delay(2); //第三个脉冲,DI=1表示选择通道1(CH2)ADC_DI=0;ADC_DO=1;//DI转为高阻态,DO脱离高阻态为输出数据作准备ADC_CLK=1;delay(2);ADC_CLK=0;delay(2);//经实验,这里加一个脉冲AD便能正确读出数据,//不加的话读出的数据少一位(最低位d0读不出?for(i=0;i<8;i++){ADC_CLK=1;delay(2);ADC_CLK=0;delay(2);ch=(ch<<1)|ADC_DO;//在每个脉冲的下降沿DO输出一位数据,最终ch为8位二进制数}ADC_CS=1;//取消片选,一个转换周期结束adval=ch;returnadval;}。
51单片机驱动ADC0832模数转换程序-lcd1602显示/*这个芯应用不多*/#include ;#define uchar unsigned char#define uint unsigned intuchar Chan0Value,Chan1Value;sbit RS=P1^0; //1602各控制脚sbit RW=P1^1;sbit EN=P1^2;sbit Cs0832= P2^0;//0832各控制脚sbit Clk0832= P3^6;sbit Di0832= P3^7;sbit Do0832= P3^7;void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){int i,j;for(i=0;i;>;i;}for(i=0;i<8;i++)//从低到高取一次数{if(Do0832) Dat2|=0x01<<i;Clk0832=1; //下降沿有效Clk0832=0;}Cs0832=1;Di0832=1;Clk0832=1; //数据读取完成,释放所有数据线if(Dat1==Dat2)return Dat1; //校验两次数相等,输出}/*本程序与其他一般程序最大的不同就是要读两次一次从最高位到最低位,一次从最低位到最高位,两次所读值相等即为正常,可以输出*//******************************LCD1602*********** ***************************//*************************lcd1602程序**************************/void wr_com(unsigned char com)//写指令// { delay1ms(1);RS=0;RW=0;EN=0;P0=com;delay1ms(1);EN=1;delay1ms(1);EN=0;}void wr_dat(unsigned char dat)//写数据// { delay1ms(1);RS=1;RW=0;EN=0;P0=dat;delay1ms(1);EN=1;delay1ms(1);EN=0;}void lcd_init()//初始化设置//{delay1ms(15);wr_com(0x38);delay1ms(5);wr_com(0x80);delay1ms(5);wr_com(0x01);delay1ms(5);wr_com(0x06);delay1ms(5);wr_com(0x0c);delay1ms(5);}void writevalue(uchar add,uchar dat) {wr_com(0x80+add);wr_dat(dat);}void zifuchuan(uchar *ch){while(*ch!=0)wr_dat(*ch++);delay1ms(20);}void main(void){lcd_init();while(1){Chan0Value=GetValue0832(0);delay1ms(100);Chan1Value=GetValue0832(1);wr_com(0x80);zifuchuan("Chanal 0:");writevalue(10,Chan0Value/100+0x30);writevalue(11,Chan0Value%100/10+0x30);writevalue(12,Chan0Value%100%10+0x30);wr_com(0x80+0x40);zifuchuan("Chanal 1:");writevalue(0x40+10,Chan1Value/100+0x30);writevalue(0x40+11,Chan1Value%100/10+0x30); writevalue(0x40+12,Chan1Value%100%10+0x30); delay1ms(1000);}}/*此程序只为调通ADC0832,没有对电压值进行转换要想得到准确电压值,请把Chan0Value和Chan1Value 的值乘以5再除以255即可。
adc0832数字电压表(程序+仿真图)仿真图:/*********************************包含头文件********************************/#include <reg51.h>#include <intrins.h>/*********************************端口定义**********************************/sbit CS = P3^5;sbit Clk = P3^3;sbit DATI = P3^4;sbit DATO = P3^4;sbit P20=P2^0 ;/*******************************定义全局变量********************************/unsigned char dat = 0x00; //AD值unsigned char count = 0x00; //定时器计数unsigned char CH; //通道变量unsigned char dis[] = {0x00, 0x00, 0x00}; //显示数值/*******************************共阳LED 段码表*******************************/unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90};char code tablewe[]={ 0xfd,0xfb,0xf7,0xef,0xdf,0xfe };/**************************************** ************************************函数功能:AD转换子程序入口参数:CH出口参数:dat***************************************** ***********************************/unsigned char adc0832(unsigned char CH){unsigned char i,test,adval;adval = 0x00;test = 0x00;Clk = 0; //初始化DATI = 1;_nop_();CS = 0;_nop_();Clk = 1;_nop_();if ( CH == 0x00 ) //通道选择{Clk = 0;DATI = 1; //通道0的第一位_nop_();Clk = 1;_nop_();Clk = 0;DATI = 0; //通道0的第二位_nop_();Clk = 1;_nop_();}else{Clk = 0;DATI = 1; //通道1的第一位_nop_();Clk = 1;_nop_();Clk = 0;DATI = 1; //通道1的第二位_nop_();Clk = 1;_nop_();}Clk = 0;DATI = 1;for( i = 0;i < 8;i++ ) //读取前8位的值{_nop_();adval <<= 1;Clk = 1;_nop_();Clk = 0;if (DATO)adval |= 0x01;elseadval |= 0x00;}for (i = 0; i < 8; i++) //读取后8位的值{test >>= 1;if (DATO)test |= 0x80;elsetest |= 0x00;_nop_();Clk = 1;_nop_();Clk = 0;}if (adval == test) //比较前8位与后8位的值,如果不相同舍去。
第九章A/D和D/A转换器接口9.1 MCS-51单片机与D/A转换器的接口和应用9.1.1 典型D/A转换器芯片DAC0832DAC0832是一个8位D/A转换器芯片,单电源供电,从+5V~+15V均可正常工作,基准电压的范围为±10V,电流建立时间为1µs,CMOS工艺,低功耗20mm。
其内部结构如图9.1所示,它由1个8位输入寄存器、1个8位DAC寄存器和1个8位D/A转换器组成和引脚排列如图9.2所示。
(7)Iout2——电流输出“1”。
当数据为全“1”时,输出电流最大;为全“0”时输出电流最小。
(8)Iout2——电流输出“2”。
DAC转换器的特性之一是:Iout1+Iout2=常数。
(9)Rfb——反馈电阻端既运算放大器的反馈电阻端,电阻(15KΩ)已固化在芯片中。
因为DAC0832是电流输出型D/A转换器,为得到电压的转换输出,使用时需在两个电流输出端接运算放大器,Rfb 即为运算放大器的反馈电阻,运算放大器的接法如图9.3所示。
(10)Vref——基准电压,是外加高精度电压源,与芯片内的电阻网络相连接,该电压可正可负,范围为-10V~+10V.(11)DGND——数字地(12)AGND——模拟地7 0P0.7 P0.0(2)可通过循环程序段的机器周期数,计算出锯齿波的周期。
并可根据需要,通过延时的方法来改变波形周期。
若要改变锯齿波的频率,可在AJMP MM指令前加入延迟程序即可。
延时较短时可用NOP指令实现(本程序就是如此),需要延时较长时,可以使用一个延长子程序。
延迟时间不同,波形周期不同,锯齿波的斜率就不同。
(3)通过A加1,可得到正向的锯齿波,反之A减1可得到负向的锯齿波。
(4)程序中A的变化范围是0~255,因此得到的锯齿波是满幅度的。
如要求得到非满幅锯齿波,可通过计算求的数字量的处置和终值,然后在程序中通过置初值和终值的方法实现。
几点说明:(1)以上程序产生的是矩形波,其低点平的宽度由延时子程序DELAYL所延时的时间来决定,高电平的宽度则由DELAYH所延时的时间决定。
实验报告十实验名称:ADC0832数模转换的显示目的:ADC0832是8脚双列直插式双通道A/D转换器,能分别对两路模拟信号实现模—数转换,可以用在单端输入方式和差分方式下工作。
ADC0832采用串行通信方式,通过DI 数据输入端进行通道选择、数据采集及数据传送。
8位的分辨率(最高分辨可达256级),可以适应一般的模拟量转换要求。
其内部电源输入与参考电压的复用,使得芯片的模拟电压输入在0~5V之间。
具有双数据输出可作为数据校验,以减少数据误差,转换速度快且稳定性能强。
独立的芯片使能输入,使多器件挂接和处理器控制变的更加方便。
ADC0832的工作原理:正常情况下ADC0832 与单片机的接口应为4条数据线,分别是CS、CLK、DO、DI。
但由于DO端与DI端在通信时并未同时使用并与单片机的接口是双向的,所以在I/O口资源紧张时可以将DO和DI并联在一根数据线上使用。
当ADC0832未工作时其CS输入端应为高电平,此时芯片禁用,CLK 和DO/DI 的电平可任意。
当要进行A/D转换时,须先将CS使能端置于低电平并且保持低电平直到转换完全结束。
此时芯片开始转换工作,同时由处理器向芯片时钟(CLK)输入端输入时钟脉冲,DO/DI端则使用DI端输入通道功能选择的数据信号。
在第一个时钟脉冲的下沉之前DI端必须是高电平,表示启始信号。
在第二、三个脉冲下沉之前DI端应输入两位数据用于选择通道功能。
通道地址通道工作方式说明SGL/DIF ODD/SIGN 0 10 0 + -差分方式0 1 - +1 0 +单端输入方式1 1 +表1:通道地址设置表如表1所示,当此两位数据为“1”、“0”时,只对CH0 进行单通道转换。
当2位数据为“1”、“1”时,只对CH1进行单通道转换。
当两位数据为“0”、“0”时,将CH0作为正输入端IN+,CH1作为负输入端IN-进行输入。
当两位数据为“0”、“1”时,将CH0作为负输入端IN-,CH1 作为正输入端IN+进行输入。
ADC0832程序完整版源码+Proteus仿真来源:互联网作者:后都出现了一些奇怪的问题,有的根本没法读取数据,有的数据有错误。
当参考电压为5V时,如果把输入电压从0一直调到5V,读取的数据应该是从0到255,2.5V 时应该是128。
但是我发现一些源码在输入0~2.5V时读取出来的是0~255,到2.5V时读取的数据为0,从2.5到5V,读出的值又从0增加到255,始终不正确。
今天下午特地查阅的ADC0832英文原版的DataSheet,又参考了一篇中文文档,终于写出了其完整的程序,并且先后读取了MSB FIRST DATA和LSB FIRST DATA,进行比较,如果两个数据相等,返回读取的数据,否则返回0,这样可以避免读取发生错误,更稳定可靠。
并通过了Proteus仿真。
下图是ADC0832的时序图:其中T-SetUp为250ns,由于使用的是51单片机,晶振11.0592MHz,机器周期比这个值大,可以不考虑,但为了防止出现异常,还是延时了两个机器周期。
注意在第11个时钟下降沿之后,DO上的电平既是MSB FIRST输出的最后一位,又是LSB FIRST输出的第一位。
以下是读取ADC0832的代码。
[cpp] view plaincopysbit CS_0832 = P1^0;sbit CLK_0832 = P1^1;sbit DO_0832 = P1^2; // DI、DO不同时有效,可共用一个接口sbit DI_0832 = P1^2;extern void _nop_ ( void );#define pulse0832() _nop_();_nop_();CLK_0832=1;_nop_();_nop_();CLK_0832=0 //把模拟电压值转换成8位二进制数并返回unsigned char read0832(){unsigned char i, ch = 0, ch1 = 0;CS_0832=0; // 片选,DO为高阻态DI_0832=1;// 此处暂停T-SetUp: 250ns (由pulse0832完成)pulse0832(); // 第一个脉冲,起始位,DI置高DI_0832=1;pulse0832(); // 第二个脉冲,DI=1表示双通道单极性输入DI_0832=1;pulse0832(); // 第三个脉冲,DI=1表示选择通道1(CH2)// 51单片机为准双向IO口:应先写入1再读取DI_0832=1;// MSB FIRST DATAfor(i = 0; i < 8; ++i) {pulse0832();ch <<= 1;if(DO_0832==1)ch |= 0x01;}// MSB FIRST输出的最后一位与LSB FIRST输出的第一位是在// 同一个时钟下降沿之后,故此处先执行读取,后执行pulse// LSB FIRST DATAfor(i = 0; i < 8; ++i) {ch1 >>= 1;if(DO_0832==1)ch1 |= 0x80;pulse0832();}CS_0832=1; // 取消片选,一个转换周期结束return (ch==ch1) ? ch : 0; // 返回转换结果}。
串行AD转换器ADC0832的使用串行AD转换器ADC0832的使用单片机控制系统中通常要用到AD转换,根据输出格式,常用的AD转换方式可分为并行AD和串行AD。
并行方式一般在转换后可直接接收,但芯片的引脚比较多;串行方式所用芯片引脚少,封装小,但需要软件处理才能得到所需要的数据。
可是单片机I/O引脚本来就不多,使用串行器件可以节省I/O资源。
ADC0832是8位逐次逼近模数转换器,可支持两个单端输入通道和一个差分输入通道。
相同功能的器件还有ADC0834,ADC0838,ADC0831。
所不同的是它们的输入通道数量不同。
它们的通道选择和配置都是通过软件设置。
AD0832的主要特点如下:● 易于和微处理器接口或独立使用;● 可满量程工作;● 可用地址逻辑多路器选通各输入通道;● 单5V供电,输入范围为0~5V;● 输入和输出与TTL、CMOS电平兼容;ADC0832通过内部多路器来控制选择通道,处理器的控制命令通过DI引脚输入。
引脚图如右图所示,通道配置命令和通道选择命令如下:输入配置可在多路器寻址时序中进行。
多路器地址可通过DI端移入转换器。
多路器地址选择模拟输入通道可决定输入是单端输入还是差分输入。
当输入是差分时,应分配输入通道的极性,并应将差分输入分配到相邻的输入通道对中。
例如通道0和通道1可被选为一对差分输入。
另外,在选择差分输入方式时,极性也可以选择。
一对输入通道的两个输入端的任何一个都可以作为正极或负极。
通常ADC0832在输出以最高位(MSB)开头的数据流后,会以最低位(LSB)开头重输出一遍(前面的数据流)。
(因此,编程时要发两轮脉冲,第一次取数据,第二次若不要从低到高的数据,也要发一轮8 个脉冲将0832中寄存器的数据移出。
是的,)其工作时序如下所示:ADC0832有8只引脚,CH0和CH1为模拟输入端,CS为片选引脚,只有CS置低才能对ADC0832进行配置和启动转换。
CLK为ADC0832的时钟输入端。