刚学单片机 参考高人的闹钟程序 自己编的电子钟 请大家指点
/**八个数码管接在P0口,选通引脚通过38译码器接在P2口,都为低电平有效。KEY1,KEY2,KEY3, KEY4四个按键*/
/* 分别接在P3.0,P3.1,P3.2,P3.3 。P1.7接蜂鸣器*******************************************/
/**程序功能:本程序可模拟电子表在数码管上显示,并且有闹铃功能,在显示正常时间情况下按下KEY1即可进入闹铃设置*/
/*******界面设置好后再按KEY1又可回到正常显示时间,KEY2,KEY3,KEY4分别为调整时分秒按键****************************/
/*编写日期:2009年11月19日*/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar a[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//定义各个数字对应的引脚值
uchar b[]={0,1,2,3,4}; //显示闹铃设定时的引脚值
uchar table[]={0,1,2,3,4,5,6,7};//显示时间
void delay(uint cnt)
{
while(--cnt);
}
uchar num;
uint i=0;
uchar j=0;
uchar k=0; //全局变量
uchar s=0;//**************************************秒
uchar m=0;//**********************************分
uchar h=0;//********************************时
uchar sh=0;
uchar sl=0; //*******************秒高位,秒低位
uchar mh=0;
uchar ml=0; //*********************分高位,分低位
uchar hh=0;
uchar hl=0; //************************时高位,时低位
uchar hd=0;//*********************闹铃时uchar md=0;//**************************************************闹铃分uchar mdh=0;
uchar md=0;//闹铃分钟
uchar mdh=0;//闹铃分高位
uchar mdl=0;//*************************************闹铃分高位,分低位
uchar hdh=0;
uchar hdl=0;//*************************************闹铃时高位,时低位
sbit KEY1=P3^0; //用于切换显示
sbit KEY2=P3^1; //调整时
sbit KEY3=P3^2; //调整分
sbit KEY4=P3^3; //调整秒
sbit P17=P1^7; //蜂鸣器引脚
uint n;
bit d; //显示标志值
void main()
{
TMOD=0x22;//************************八位自动重装定时
TH0=0x06;
TL0=0x06;
TH1=0x06;
TL1=0x06;//************************定时250us
ET1=1;
ET0=1;
EA=1; //****************************开中断
TR0=1;
TR1=1; // 开始计时
P2=0;//扫描初值
while(1) //主循环
{
if(!KEY2) //调时
{
for(n=0;n<15000;n++);
h++;
if(h==24)
h=0;
// s=0;
}
if(!KEY3) //调分
{
for(n=0;n<15000;n++);
m++;
if(m==60)
m=0;
// s=0;
}
if(!KEY4) //调秒
{
for(n=0;n<15000;n++);
s++;
if(s==60)
s=0;
}
if(!KEY1) //检测按键1
{
for(n=0;n<1000;n++);
while(!KEY1);
for(n=0;n<1000;n++);
d=1;
while(1) //如果按下1键则进入闹铃调整循环
{
if(!KEY2) //调整时
{
for(n=0;n<15000;n++);
hd++;
if(hd==24) hd=0;
hdh=hd/10; //闹铃时高位
hdl=hd%10; //闹铃时低位
}
if(!KEY3) //调整分
{
for(n=0;n<15000;n++);
md++;
if(md==60) md=0;
mdh=md/10; //闹铃分高位
mdl=md%10; //闹铃分低位
}
if(!KEY1) //如果再按下1键则跳出闹铃调整循环
{
for(n=0;n<1000;n++);
while(!KEY1);
for(n=0;n<1000;n++);
d=0;
break; //跳出
}
}
}
if((hd==h)&&(m==md)) //如果时间与设定的闹铃相等 蜂鸣器响
{
for(n=0;n<200;n++) //方波的频率设置
{
delay(80);
P17=~P17;
}
}
else
P17=1;
delay(20000);
}
}
/*********************************************************************************************************/
// 计时中断函数
//功能描述:每到计时时间,更新一次秒,分,时的值,并更改对应的分秒时高地位的值。
/*********************************************************************************************************/
void times(void) interrupt 1 // 定时器0中断服务函数
{
if(++i==4000)
{i=0;s++;} //4000*250us=1s
while(s==60)
{++m;s=0;} // 秒更新
sh=s/10;
sl=s%10;
while(m==60) //分更新
{++h;m=0;}
mh=m/10;
ml=m%10;
while(h==24) //时更新
{h=0;}
hh=h/10;
hl=h%10;
}
/*********************************************************************************************************/
// 扫描中断函数
//功能描述:此中断函数由定时器1定时,每中断一次更换一次,选通值,并更换相应的显示数值。
//
//
/*********************************************************************************************************/
void dis(void) interrupt 3 //扫描中断函数用来显示
{
while(++j==10)
{
j=0;
if(d)//当显示标志为1时,进入闹铃调整界面
{
P2=b[k++];
if(k==5) //只让前五个数码管显示
k=0;
switch(P2)
{
case 0: P0=a[hdh];break;
case 1: P0=a[hdl];break;
case 2: P0=a[10];break;
case 3: P0=a[mdh];break;
case 4: P0=a[mdl];break; //对应位的显示数字
}
}
else //当显示标志为0时,进入正常时间显示
{
P2=table[num++]; //选通引脚循环右移
if(num==8)
num=0;
switch(P2)
{
case 0: P0=a[hh];break;
case 1: P0=a[hl];break;
case 2: P0=a[10];break;
case 3: P0=a[mh];break;
case 4: P0=a[ml];break;
case 5: P0=a[10];break;
case 6: P0=a[sh];break;
case 7: P0=a[sl];break; //对应位的显示数字
}
}
}
} |