设计任务
利用单片机系统与模数转换芯片AD0809、显示模块等的结合构建数字电压表。由于单片机的发展已经成熟,利用单片机系统的软硬件结合,可以组装出许多的应用电路来。此方案的原理是模数(A/D)转换芯片的基准电压端,被测量电压输入端分别输入基准电压和被测电压。模数(A/D)转换芯片将被测量电压输入端所采集到的模拟电压信号转换成相应的数字信号,然后通过对单片机系统进行软件编程,使单片机系统能按规定的时序来采集这些数字信号,通过一定的算法计算出被测量电压的值。最后单片机系统将计算好了的被测电压值按一定的时序送入显示电路模块加以显示。
设计实物
资料打包
完整源程序
下面展示一些 内联代码片
。
/*******************************************************************************
* 文件名称:ADC0809数字电压表可切换量程
* 实验目的:1.
* 2.
* 程序说明:定制联系Q:2772272579;@: itworkstation@hotmail.com
* 日期版本:完整源代码,实物测试通过。
*******************************************************************************/
//-------------设计要求--------------------
//根据键盘的不同控制电压量程
// 1V 5V 10V 50V
//-----------------------------------------
//程序头函数
#include <reg52.h>
//宏定义
#define uint unsigned int
#define uchar unsigned char
#define Data_ADC0809 P1
//ADC0809
sbit ST=P3^2;
sbit EOC=P3^3;
sbit OE=P3^1;
sbit DIAN = P0^5; //小数点
sbit ADC0809_A=P3^0;
sbit ADC0809_B=P3^4;
sbit ADC0809_C=P3^5;
//按键检测
sbit Key_1V=P2^4;
sbit Key_5V=P2^5;
sbit Key_10V=P2^6;
sbit Key_50V=P2^7;
uchar flag_vol=4; //开机初始化量程为50V,防止待测电压过大烧坏小量程
//74HC138
sbit HC138_A=P2^3;
sbit HC138_B=P3^7;
//报警
bit flag_bell=0;
sbit SPK=P3^6;
/*******************************定义全局变量********************************/
unsigned char dis[3]; //显示数值
unsigned int temp=0;
unsigned int dat=0;
/*******************************共阴LED段码表*******************************/
unsigned char code tab[]={0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x47,0xDF,0xD7,0x5e/*字母U*/,0x8B/*字母F*/}; //gc.debfa
/****************************************************************************
函数功能:AD转换子程序
****************************************************************************/
//ADC0809读取信息
uchar ADC0809()
{
uchar temp_=0x00;
//初始化高阻太
OE=0;
//转化初始化
ST=0;
//开始转换
ST=1;
ST=0;
//外部中断等待AD转换结束
while(EOC==0)
//读取转换的AD值
OE=1;
temp_=Data_ADC0809;
OE=0;
return temp_;
}
/****************************************************************************
函数功能:延时子程序
入口参数:
出口参数:
****************************************************************************/
void delay(unsigned int x)
{
unsigned int i,j;
for(i=0;i<x;i++)
for(j=0;j<121;j++);
}
//=====================================================================================
//=====================================================================================
//=====================================================================================
/****************************************************************************
函数功能:将0-255级换算成0.00-5.00的电压数值
入口参数:i
出口参数:
****************************************************************************/
//void convdata_1V(unsigned char dat1)
//{
// unsigned int Vo;
// Vo=dat1*3.92; // 0.1V*1000/255
// dis[0] = Vo/100%10; //个位
// dis[1] = Vo/10%10; //小数点后第1位
// dis[2] = Vo%10; //小数点后第2位
//}
void convdata_1V(unsigned char dat1)
{
unsigned int Vo;
Vo=dat1*1.96; // 5V*100*10(电阻比)/255
dis[0] = Vo/100%10; //个位
dis[1] = Vo/10%10; //小数点后第1位
dis[2] = Vo%10; //小数点后第2位
}
void convdata_5V(unsigned char dat1)
{
unsigned int Vo;
Vo=dat1*1.96*2; // 5V*100*10(电阻比)/255
dis[0] = Vo/100%10; //个位
dis[1] = Vo/10%10; //小数点后第1位
dis[2] = Vo%10; //小数点后第2位
}
void convdata_10V(unsigned char dat1)
{
unsigned int Vo;
Vo=dat1*1.96*4; // 5V*100*10(电阻比)/255
dis[0] = Vo/100%10; //个位
dis[1] = Vo/10%10; //小数点后第1位
dis[2] = Vo%10; //小数点后第2位
}
void convdata_50V(unsigned char dat1)
{
unsigned int Vo;
Vo=dat1*1.96*20;
dis[0] = Vo/1000%10; //十位
dis[1] = Vo/100%10; //个位
dis[2] = Vo/10%10; //小数点后第1位
}
/****************************************************************************
函数功能:数码管显示子程序
入口参数:
出口参数:
****************************************************************************/
void display_5V(void)
{
P0=tab[dis[0]];
P2 &=0xFE; //1111 1110
DIAN=1;
delay(1);
P2 |=0x07;
P0=tab[dis[1]];
P2 &=0xFD; //1111 1101
delay(1);
P2 |=0x07;
P0=tab[dis[2]];
P2 &=0xFB; // 1111 1011
delay(1);
P2 |=0x07;
}
void display_50V(void)
{
P0=tab[dis[0]];
P2 &=0xFE; //1111 1110
delay(1);
P2 |=0x07;
P0=tab[dis[1]];
P2 &=0xFD; //1111 1101
DIAN=1;
delay(1);
P2 |=0x07;
P0=tab[dis[2]];
P2 &=0xFB; // 1111 1011
delay(1);
P2 |=0x07;
}
void display_waring(void)
{
P0=tab[11];
P2 &=0xFE; //1111 1110
delay(1);
P2 |=0x07;
P0=tab[11];
P2 &=0xFD; //1111 1101
delay(1);
P2 |=0x07;
P0=tab[11];
P2 &=0xFB; // 1111 1011
delay(1);
P2 |=0x07;
}
/****************************************************************************
函数功能:蜂鸣器开关
****************************************************************************/
void beep()
{
if(flag_bell)
SPK=0;
else
SPK=1;
}
/****************************************************************************
函数功能:按键检测
//按键检测
sbit Key_1V=P2^4;
sbit Key_5V=P2^5;
sbit Key_10V=P2^6;
sbit Key_50V=P2^7;
****************************************************************************/
void keyscan()
{
if(Key_1V==0) //设置
{
delay(10);
if(Key_1V==0)
{
ADC0809_A=0;
ADC0809_B=1;
ADC0809_C=0;
flag_vol=1;
}
while(!Key_1V);
}
if(Key_5V==0) //设置
{
delay(10);
if(Key_5V==0)
{
ADC0809_A=1;
ADC0809_B=0;
ADC0809_C=0;
flag_vol=2;
}
while(!Key_5V);
}
if(Key_10V==0) //设置
{
delay(10);
if(Key_10V==0)
{
ADC0809_A=0;
ADC0809_B=0;
ADC0809_C=0;
flag_vol=3;
}
while(!Key_10V);
}
if(Key_50V==0) //设置
{
delay(10);
if(Key_50V==0)
{
ADC0809_A=1;
ADC0809_B=1;
ADC0809_C=0;
flag_vol=4;
}
while(!Key_50V);
}
}
/****************************************************************************
函数功能:主程序
入口参数:
出口参数:
****************************************************************************/
void main(void)
{
ADC0809_A=1;
ADC0809_B=1;
ADC0809_C=0;
HC138_A=1;
HC138_B=1;
while(1) //主循环
{
keyscan();
dat=ADC0809();
switch(flag_vol)
{
case 1:
HC138_A=0;
HC138_B=0;
ADC0809_A=0;
ADC0809_B=1;
ADC0809_C=0;
dat=ADC0809();
if(dat>51)
{
flag_bell=1;
display_waring();
}
else
{
flag_bell=0;
convdata_1V(dat); //数据转换
display_5V(); //显示数值
}
break;
case 2:
HC138_A=1;
HC138_B=0;
ADC0809_A=1;
ADC0809_B=0;
ADC0809_C=0;
dat=ADC0809();
if(dat>128)
{
flag_bell=1;
display_waring();
}
else
{
flag_bell=0;
convdata_5V(dat); //数据转换
display_5V(); //显示数值
}
break;
case 3:
HC138_A=0;
HC138_B=1;
ADC0809_A=0;
ADC0809_B=0;
ADC0809_C=0;
dat=ADC0809();
if(dat>128)
{
flag_bell=1;
display_waring();
}
else
{
flag_bell=0;
convdata_10V(dat); //数据转换
display_5V(); //显示数值
}
break;
case 4:
HC138_A=1;
HC138_B=1;
ADC0809_A=1;
ADC0809_B=1;
ADC0809_C=0;
dat=ADC0809();
if(dat>128)
{
flag_bell=1;
display_waring();
}
else
{
flag_bell=0;
convdata_50V(dat); //数据转换
display_50V(); //显示数值
}
break;
default: break;
}
beep(); //检测是否超限
}
}