#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
//===========================
//ADC0809相关引脚定义
//===========================
#define ADC_DATA P1
sbit ADC_EOC = P3^3;
sbit ADC_CLK = P3^4;
sbit ADC_START = P3^6;
sbit ADC_OE = P3^7;
//===========================
//4位共阳数码管相关
//===========================
uchar code seg[10]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90 }; //0~9 小数点不亮
uchar code seg_dot[10]={ 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10 }; //0~9 小数点亮
#define SEG_DATA P2 //数码管段选码,共阳数码管,低电平选通段选码
sbit SEG_SEL_0 = P0^3; //数码管位选:第0位,共阳数码管,高电平选通位选码
sbit SEG_SEL_1 = P0^2; //数码管位选:第1位
sbit SEG_SEL_2 = P0^1; //数码管位选:第2位
sbit SEG_SEL_3 = P0^0; //数码管位选:第3位
//===========================
//警报:LED与蜂鸣器引脚
//===========================
sbit LED = P0^5; //低电平亮
sbit BEEP = P0^4; //高电平响
#define LED_ON LED=0
#define LED_OFF LED=1
#define BEEP_ON BEEP=1
#define BEEP_OFF BEEP = 0
//===========================
//粗略延时函数 AT89C51 & 12MHz
//===========================
void delayms(unsigned int ms)
{
unsigned char a,b,c;
while(ms--)
{
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
/*
//===========================
//粗略延时函数 STC12C5A60S2 & 12MHz
//===========================
void delayms(unsigned int ms)
{
unsigned char a,b,c;
while(ms--)
{
for(c=1;c>0;c--)
for(b=222;b>0;b--)
for(a=12;a>0;a--);
}
}
*/
//===========================
//定时器初始化,配置ADC0809时钟
//===========================
void timer_init(void)
{
//配置定时器0
ET0 = 1;
TMOD &= 0xF0;
TMOD |= 0x02; //定时器0,模式2,自动重装定时器
TH0 = 200; //自动重装值
TL0 = 200;
TR0 = 1;
//配置定时器1
ET1 = 1;
TMOD &= 0x0F; //清除定时器1配置,不改动定时器0的配置
TMOD |= 0x10; //定时器1模式一,不改动定时器0的模式
TH1 = (65536 - 2000)/256;
TL1 = (65536 - 2000)%256;
TR1 = 1;
EA = 1;
}
//===========================
//定时器0中断,为ADC0809提供时钟信号
//===========================
void timer0() interrupt 1
{
ADC_CLK = ~ADC_CLK;
}
//============================
//ADC0809 转换函数
//============================
uchar ADC0809_GET(void)
{
ADC_START = 0;
ADC_OE = 0;
ADC_START = 1;
ADC_START = 0;
while(ADC_EOC == 0);
ADC_OE = 1;
return ADC_DATA;
}
//============================
//定时器1中断函数,用于刷新数码管
//============================
uchar t1_flag = 0; //用于标记显示第几位数码管
uchar seg0 = 0; //第0位数码管的值
uchar seg1 = 1; //第1位数码管的值
uchar seg2 = 2; //第2位数码管的值
uchar seg3 = 3; //第3位数码管的值
void timer1() interrupt 3
{
TH1 = (65536 - 2000)/256;
TL1 = (65536 - 2000)%256;
SEG_SEL_0 = 0;
SEG_SEL_1 = 0;
SEG_SEL_2 = 0;
SEG_SEL_3 = 0;
SEG_DATA = 0xff;
if(t1_flag == 0)
{
SEG_SEL_0 = 1; //选通第0位数码管
SEG_SEL_1 = 0;
SEG_SEL_2 = 0;
SEG_SEL_3 = 0;
SEG_DATA = seg_dot[seg0]; //显示带小数点的数
}
else if(t1_flag == 1)
{
SEG_DATA = seg[seg1];
SEG_SEL_0 = 0;
SEG_SEL_1 = 1; //选通第1位数码管
SEG_SEL_2 = 0;
SEG_SEL_3 = 0;
}
else if(t1_flag == 2)
{
SEG_DATA = seg[seg2];
SEG_SEL_0 = 0;
SEG_SEL_1 = 0;
SEG_SEL_2 = 1; //选通第2位数码管
SEG_SEL_3 = 0;
}
else if(t1_flag == 3)
{
SEG_DATA = seg[seg3];
SEG_SEL_0 = 0;
SEG_SEL_1 = 0;
SEG_SEL_2 = 0;
SEG_SEL_3 = 1; //选通第3位数码管
}
t1_flag++; //自加1
t1_flag = t1_flag%4; //让t1_flag 在0和3之间循环
}
//============================
//显示电压值,输入0~255,显示0.000~5.000
//============================
uint print_volt(uchar num)
{
uint volt = 0;
volt = num/255.0 * 5000 + 0.5; //除255.0和除255有很大区别,除255.0会自动转换为float型,小数才能保持,而volt/255=0,+0.5四舍五入。
seg0 = volt/1000%10;
seg1 = volt/100%10;
seg2 = volt/10%10;
seg3 = volt%10;
return volt;
}
//============================
//主函数
//============================
void main(void)
{
uchar adc_num = 0; //ADC采集到的值
uint volt = 0; //电压值 0~5000,代表(0~5)V
timer_init(); //定时器0、定时器1初始化。
LED_OFF;
BEEP_OFF;
while(1)
{
adc_num = ADC0809_GET();
volt = print_volt(adc_num); //在数码管上显示电压值,并返回一个0~5000的值,用于判断是否要报警。
if(volt > 2500)
{
LED_ON;
BEEP_ON;
}
else
{
LED_OFF;
BEEP_OFF;
}
delayms(100);
}
}
- 1
- 2
前往页