单片机+ADC0832简易数字电压表
2019-10-30 来源:51hei
给大家分享一个用ADC0832模数转换芯片设计的电压表设计,内含protues电路图和带有注释的keil工程文件
ADC0832电压表仿真原理图如下
单片机电压表源程序如下:
#include #include #define uint unsigned int #define uchar unsigned char sbit CS =P3^4; //片选使能端 sbit DI =P1^1; //数据信号输入端,选择通道控制(SIG/DIF和ODD/EVEN) sbit DO =P1^1; //数据输出端 sbit CLK =P1^0; //时钟脉冲 sbit S_1 = P2^3; sbit S_2 = P2^4; sbit S_3 = P2^5; sbit S_4 = P2^6; unsigned char wd[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //不带小数点的段选码 unsigned char yd[]={0x40,0x79,0x024,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//带小数点的段选码 // ===========延时子程序================= void delay_ms(unsigned int x) { unsigned int i,j; for(i=0;i } /*=============读ADC0832函数=============*/ /*=============采集并返回=================*/ unsigned int Adc0832(unsigned char channel) //AD转换,返回结果 { uchar i=0; uchar j; uint dat=0; //正向输入数据 uchar ndat=0; //反向输入数据 //****************初始化操作************** if(channel==0)channel=2; //10B对应SGL/DIF=1,ODD/EVEN=0 if(channel==1)channel=3; //11B对应SGL/DIF=1,ODD/EVEN=1 //****************写操作,将通道数据写入ADC0832************** DI=1; _nop_();_nop_(); //发起始位,固定为1(1位) CS=0;_nop_();_nop_(); //拉低CS端,让ADC0832使能 CLK=1;_nop_();_nop_(); //拉高CLK端,DI端的数据移入ADC0832内部的多路移位寄存器 CLK=0;_nop_();_nop_(); //拉低CLK端,形成下降沿1,第一个周期开始 CLK=1; //拉高CLK端,在第一个时钟周期内,DI为高电平,表示启动位 //紧接着输入两位配置位进行通道选择 DI=channel&0x1;_nop_();_nop_(); //假设选取通道0,则10&01=0,即SGL/DIF=0,为差分输入(2位) CLK=0;_nop_();_nop_(); //拉低CLK端,形成下降沿2,第二个周期开始 CLK=1; //拉高CLK端 DI=(channel>>1)&0x1;_nop_();_nop_(); //假设选取通道0,则01&01=1,ODD/EVEN=1,表示通道0 CLK=0; //拉低CLK端,形成下降沿3 DI=1;_nop_();_nop_(); //控制命令结束 dat=0; //*************读操作,将AD转换的数从DO口输出**************** for(i=0;i<8;i++) //每一个CLK下降沿输出一位数,先输出高位 { dat|=DO; //收数据,“|”位或,如果2位中有一位为1,则结果为1,否则为0 CLK=1;_nop_();_nop_(); CLK=0;_nop_();_nop_(); //形成一次时钟脉冲 dat<<=1; if(i==7)dat|=DO; } for(i=0;i<8;i++) //每一个CLK下降沿输出一位数,先输出低位 { j=0; j=j|DO; //收数据 CLK=1;_nop_();_nop_(); CLK=0;_nop_();_nop_(); //形成一次时钟脉冲 j=j<<7; ndat=ndat|j; if(i<7)ndat>>=1; } //*********************结束AD转换,并返回转换的数*********************** CS=1; //拉低CS端 CLK=0; //拉低CLK端 DO=1; //拉高数据端,回到初始状态 dat<<=8; dat|=ndat; return(dat); //返回数据 } //============数码管显示函数========================== void display(uchar p) //数码管显示函数 { uchar S1,S2,S3; S1=p/51; //个位 S2=(p*10/51)%10; //十分位 S3=(p*100/51)%10; //百分位 //个位 S_1 = 1; //第一个数码管 S_2 = 0; S_3 = 0; S_4= 0; P0=yd[S1]; //选取带有小数点的段选码 delay_ms(5); //延时 S_1 = 0; //消隐 //十分位 S_1 = 0; S_2 = 1; //取第二个数码管 S_3= 0; S_4= 0; P0=wd[S2]; //选取不带有小数点的段选码 delay_ms(5); S_2 = 0; //消隐 //百分位 S_1 = 0; S_2 = 0; S_3= 1; //取第三个数码管 S_4= 0; P0=wd[S3]; //选取不带有小数点的段选码 delay_ms(5); S_3= 0; //消隐 } //===========主函数================ int main(void) { while(1) //无限循环 display(Adc0832(0));//数码管显示 //Adc0832(0):选择通道0,单端模式 //调用Adc0832(0),SIG/DIF=0,ODD/EVEN=1,表示工作在差分输入方式,且CH0为-,CH1为+ ……………………