config.h
extern void display(); //LED显示函数
extern void delay(unsigned int i);
extern void read();
extern void displaysj(); //led显示刷新时间
extern void readsj(); //读刷新时间
extern void speak(void); //蜂鸣器响
typedef unsigned long Ulong;
extern float jishu; //四字节
extern float jishulv;
extern unsigned int timer_1; //刷新时间的初值
extern unsigned int t0num; //用来记录TO计数溢出次数
extern unsigned int shu[6]; //6位数
extern unsigned int shu1[2];
extern unsigned int panduan; //一个判断值
extern unsigned int panduan1;
extern unsigned int tm,tt;
extern unsigned int uu;
extern unsigned int biaozhi;//用于判断是显示刷新时间还是启动计数,为0表示显示刷新时间,为1表示开始计数,显示计数
extern unsigned int bz; //外中断0中断产生标志
extern unsigned char code dispcode[]; //字符码显示,共阳极
extern unsigned char code dispcode1[]; //带小数点的字符码显示
extern unsigned char dispbitcode[]; //P2口作为选通口的值 Y0-Y5
main.c
#include "reg52.h"
#include "intrins.h"
#include "config.h"
unsigned int tm,tt;
unsigned int t0num=0; //用来记录TO计数溢出次数
unsigned int biaozhi=0;//用于判断是显示刷新时间还是启动计数,为0表示显示刷新时间,为1表示开始计数,显示计数
unsigned int bz; //外中断0中断产生标志
unsigned int uu=0;
unsigned int shu[6]={0,0,0,0,0,0}; //6位数
unsigned int shu1[2]={0,0};
unsigned int panduan=0; //一个判断值
unsigned int panduan1=0;
float jishu; //四字节
float jishulv;
unsigned int timer_1=5; //刷新时间的初值
sbit P12=P1^2;
sbit P13=P1^3;
unsigned int ii=0;
void main(void)
{
tm=tt=1000; //初值为5S,由于中断一次是5MS,所以要循环中断1000次
TMOD=0x15; //定时器0采用计数(C/T=1),方式1;定时器1采用定时,方式1
SP=0x60; //设置堆栈的初始地址
TH0=0x00; ;
TL0=0x00; //定时器0初始化
TH1=0xee;
TL1=0x00; //定时器1初始化 定时5ms
TCON
IT0=1; //设置外部中断0为下降沿触发
IE
IP=0x0d;
EA=1; //开总允许位
EX0=1; //外部中断0允许位
ET0=1; //定时器0中断允许位
ET1=1; //定时器1中断允许位
ET2=1; //定时器2中断允许位
P3=0x3c; //设置P3的第二功能
readsj(); //按一次就更新一次数据
while(1) //等待中断产生
{
if(biaozhi==0) //显示刷新时间
{
TR0=TR1=0;
t0num=TH0=TL0=0;
TH1=0xee; //ec,78
TL1=0x00;
if(bz==1) //外中断0产生了
{
readsj(); //按一次就更新一次数据
}
displaysj();
// P0=dispcode[10];
panduan1=0;
}
if(biaozhi==1) //计数
{
TR0=1; //启动定时器0(TR0)
TR1=1; //启动定时器1
if(uu==1) //设置的刷新时间到了
{
read();
uu=0;
t0num=0;
TH0=0x00;
TL0=0x00;
TH1=0xee;
TL1=0x00;
}
display();
// P0=dispcode[10];
panduan=0;
}
}
}
key.c
#include "reg52.h"
#include "intrins.h"
#include "config.h"
sbit P12=P1^2;
sbit P13=P1^3;
void int0_int(void) interrupt 0 using 1 //外部中断0
{
delay(2); //延时10MS ,消抖
if(P13==0)
{
biaozhi=0;
timer_1+=5;
if(timer_1>30) //5,15,20,25,30
{
timer_1=5; //刷新时间为0-60S,每次间隔10S
}
tm=timer_1*200; //为了转化为秒
tt=tm;
bz=1; //表明外中断0产生了
t0num=0;
TH0=0x00;
TL0=0x00;
}
if(P12==0)
{
t0num=0;
TH0=0x00; ;
TL0=0x00; //定时器0初始化
bz=0;
biaozhi=1; //表明外中断1产生了
}
delay(2); //延时10MS ,消抖
}
speak.c
#include "reg52.h"
#include "intrins.h"
#include "config.h"
sbit P17=P1^7;
void speak(void)
{
unsigned char voice;
unsigned int delay;
for(voice=0;voice<2;voice++)
{
for(delay=0;delay<10000;delay++)
P17=0;
for(delay=0;delay<6000;delay++)
P17=1;
}
}
time0-int.c
void timer0_int(void) interrupt 1 using 0 //定时器0中断
{
t0num+=1;
TH0=0x00; ;
TL0=0x00;
}
time1-int.c
void timer1_int(void) interrupt 3 using 2 //定时器1中断 中断一次5MS
{
TH1=0xee;
TL1=0x00; //定时器1初始化
tt--;
if(tt==0)
{
tt=tm; //重新赋值
uu=1; //返回显示的标志值
}
}
valuedisplay.c
//计数 数据显示/
#include "reg52.h"
#include "intrins.h"
#include "config.h"
unsigned char code dispcode[]={0x3F,0x06,0x5B,0x4F,
0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x00}; //字符码显示,共阴极
unsigned char code dispcode1[]={0xBF,0x86,0xDB,0xCF,0xE6,
0xED,0xFD,0x87,0xFF,0xEF}; //带小数点的字符码显示
unsigned char dispbitcode[]={0xDF,0xEF,0xF7,0xFB,
0xFD,0xFE};
//P2口作为选通口的值 Y0-Y5
void read()
{
int i=0;
int w=10;
long zhengshu=0;
jishu=t0num*65536+TH0*256+TL0; //脉冲个数
jishulv=jishu/timer_1; //将计数转换为计数率
if(jishulv>=2000) //超过这个值,蜂鸣器就响
{
speak(); //条件满足,蜂鸣器响
}
else
{
jishulv=jishulv*10;
zhengshu=jishulv;
for(i=0;i<=5;i++)
{
shu[i]=zhengshu%w; //shu[5]-shu[0]有效位,其中shu[0]实际上是小数位
zhengshu/=w;
}
}
//取小数点右边一位,这样,shu[5]...shu[1]shu[0]各数就计算出来了,下面需要对数进行处理
}
void display()
{
int p=0;
int k=0;
for(k=6;k>0;k--) //从高位开始扫描
{
if(panduan==0) //证明高位还没出现非零值
{
if(shu[k-1]==0) //如果高位等于0
{
if(k==2)
{
P0=dispcode1[0]; //是小数点位则正常显示
}
else if(k==1)
{
P0=dispcode[0];
}
else
{
P0=dispcode[10]; //则置空
}
}
else
{
panduan=1; //判断值置1
if(k==2)
{
P0=dispcode1[shu[k-1]];
}
else
{
P0=dispcode[shu[k-1]];
}
}
}
else if(panduan==1) //证明高位已经有非零值
{
if(k==2)
{
P0=dispcode1[shu[k-1]];
}
else
{
P0=dispcode[shu[k-1]];
}
}
P2=dispbitcode[k-1]; //选通
for(p=600;p>=0;p--);
P2=0xFF; //都不选通,先送段码,再送位选通码,再在每次显示
} //之后将所有的位都不选通,这样可以消掉拖影
}
delay5ms.c
void delay(unsigned int i)
{
TR2=1; //启动定时器2
while(i!=0)
{
TH2=0xee; //定时器2计数初值 定时5MS
TL2=0x00;
RCAP2H=0x4c;
RCAP2L=0x00;
while(TF2!=1);
TF2=0;
i--;
}
TR2=0; //停止定时器2
}
refreshtime.c
/读刷新时间/
void readsj()
{
shu1[1]=timer_1/10;
shu1[0]=timer_1%10;
}
//刷新时间显示//
void displaysj()
{
int d=0;
int m=0;
for(m=2;m>0;m--) //从高位开始扫描
{
if(panduan1==0) //证明高位还没出现非零值
{
if(shu1[m-1]==0) //如果高位等于0
{
P0=dispcode[10]; //则置空
}
else
{
panduan1=1; //判断值置1
P0=dispcode[shu1[m-1]];
}
}
else if(panduan1==1) //证明高位已经有非零值
{
P0=dispcode[shu1[m-1]];
}
P2=dispbitcode[m-1]; //选通
for(d=600;d>=0;d--);
P2=0xFF; //都不选通
}
}