第一次接触模数转换,做了这么一个小仿真,测量0~25V的输入电压,以4位数(两位小数)的形式显示在一个四位共阳数码管上,测量误差不大于0.1V。
ADC0832只是一个对0~5V电压进行模拟转数字的器件,分辨率8位,即有从0到255个挡位,每一档约为(5/255)V,即0.02V,为了实现0~25V的转换,先将待测电压通过电位器(滑动电阻)缩小5倍,保证其始终处于0~5V内再输入ADC0832(ADC0832实际转换的模拟量在0~5V之内),然后再将ADC0832转换后的数值*5,即可获知待测电压的实际值。
但这种取巧的方式虽然能在不换器件的前提下实现量程的扩充,但缺陷是误差值也随之放大(因为先把电压通过电位器几乎零误差的缩小1/5,然后再把ADC0832的转换结果放大5倍),ADC0832的误差值大约0.02V,电压表实际测量的误差值大约0.1V
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
源码:
- #include<reg51.h>
- #include<intrins.h>
- sbit CS=P3^5;
- sbit CLK=P3^3;
- sbit DI=P3^4;
- sbit DO=P3^4;
- sbit dot=P0^5; //小数点
- unsigned char dat=0x00;
- unsigned char nums[]={0x00,0x00,0x00,0x00};
- unsigned char channel; //转换通道
- unsigned char LEDS[]={0xA0,0xBB,0x62,0x2A,0x39,0x2C,0x24,0xB8,0x20,0x28}; //共阳4位数码管段码,字符显示从'0'到'9'
- unsigned char ADC0832(unsigned char channel) //模数转换
- {
- unsigned char i;
- unsigned char x=0x00;
- unsigned char y=0x00;
- CLK=0; //初始化
- DI=1;
- _nop_();
- CS=0;
- _nop_();
- CLK=1;
- _nop_();
- if(channel==0x00) //通道选择
- { //通道0
- CLK=0;
- DI=1;
- _nop_();
- CLK=1;
- _nop_();
- CLK=0;
- DI=0;
- _nop_();
- CLK=1;
- _nop_();
- }
- else //通道1
- {
- CLK=0;
- DI=1;
- _nop_();
- CLK=1;
- _nop_();
- CLK=0;
- DI=1;
- _nop_();
- CLK=1;
- _nop_();
- }
- CLK=0;
- DI=1;
- for(i=0;i<8;i++) //读取ADC0832输出的前8位数据
- {
- x<<=1;
- _nop_();
- CLK=1;
- _nop_();
- CLK=0;
- if(DO==1)
- {
- x|=0x01;
- }
- else
- {
- x|=0x00;
- }
- }
- for(i=0;i<8;i++) //读取ADC0832输出的后8位数据
- {
- y>>=1;
- if(DO==1)
- {
- y|=0x80;
- }
- else
- {
- y|=0x00;
- }
- _nop_();
- CLK=1;
- _nop_();
- CLK=0;
- }
- if(x==y) //校验,比较前8位与后8位的值
- {
- dat=x;
- }
- _nop_();
- CS=1; //释放ADC0832
- DO=1;
- CLK=1;
- return dat;
- }
- void Convert(unsigned char dat0) //数据处理
- {
- unsigned int x;
- x=dat0*0.0196*100*5;
- nums[0]=x/1000;
- nums[1]=x%1000/100;
- nums[2]=x%1000%100/10;
- nums[3]=x%1000%100%10;
- }
- void Delay() //数码管显示
- {
- unsigned char i,j;
- for(i=0;i<1;i++)
- {
- for(j=0;j<121;j++);
- }
- }
- void Display()
- {
- P0=LEDS[nums[0]];
- P2=0xFE;
- Delay();
- P2=0xFF;
- P0=LEDS[nums[1]];
- dot=0;
- P2=0xFD;
- Delay();
- P2=0xFF;
- P0=LEDS[nums[2]];
- P2=0xFB;
- Delay();
- P2=0xFF;
- P0=LEDS[nums[3]];
- P2=0xF7;
- Delay();
- P2=0xFF;
- }
- void main()
- {
- while(1)
- {
- dat=ADC0832(channel);
- Convert(dat);
- Display();
- }
- }
复制代码
上图仿真工程文件和.c文件51hei附件下载:
ADC0832数字电压表(0~25V).zip
(43.82 KB, 下载次数: 176)
|