#include<reg2051.h>
#define uint unsigned int
#define uchar unsigned char
uchar bdata m_key,key;//定义键沿有效寄存器和电平有效寄存器(bdata是可位寻址片内RAM)
sbit wx1=P3^0;//位选
sbit wx2=P3^1;
sbit wx3=P3^2;
sbit wx4=P3^3;
sbit k1=m_key^0;
sbit k2=m_key^1;
sbit k3=m_key^2;
sbit k4=m_key^3;//按键键沿标志
sbit buz=P3^7;
bit shan;//闪烁标志位
sbit s=P1^7;//秒控制位
bit nao; //闹钟标志
uchar code sm_tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83};
uchar code sszymmh[]={ 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,
6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,
6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,
5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,
2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0
};//世上只有妈妈好
// 音节频率 高八位
uchar code FREQH[]={ 0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,
0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i
0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,
0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,
} ;
// 音节频率 低八位
uchar code FREQL[]={ 0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,
0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i
0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,
0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,
};
uchar k,i,sm_sz,mkcnt,tz,scnt,shancnt,s_cnt,
timer0h,timer0l,time,ncnt,sz0,sz1,sz2,sz3,sz4;
uchar xs,fz;//小时和分钟变量
uchar nxs,nfz;//闹钟小时和分钟变量
void init();//闪烁
void pdnz(void); //判断闹钟
void sjtz(void); //调整时钟
void nzsj(void); //闹钟设置
void nzx(void); //闹钟歌曲
void disp(); //数显
void MKYscan(void); //按键扫描
void main()
{
init();
while(1)
{
while(!TF0); //判断5ms是否到了?
TF0=0;
TH0=0XEC;//初始化赋值5mS
TL0=0X78;
MKYscan();
disp();
scnt++;
if(scnt>=100)
{
s=~s;//秒控制位取反 ,500ms一次
scnt=0;
s_cnt++; //秒计数
}
if(s_cnt>=120) //120*500=60000为60秒,分钟加一
{
s_cnt=0;
fz++;
if(fz>=60)
{
fz=0;
xs++;
if(xs>=24)
xs=0;
}
}
sz0=fz%10;
sz1=fz/10;
sz2=xs%10;
sz3=xs/10;
if(k1)
{
tz++;
if(tz>=3)
tz=0;
}
switch(tz) //散转
{
case 0:pdnz();break;//闹钟判断
case 1:sjtz();break;//时间调整
case 2:nzsj();break; //闹钟时间设定
case 3:nzx(); break; //闹钟响
default:break;
}
}
}
void MKYscan(void)//矩阵键盘扫描
{
uchar r1,r2,zs;
zs=P3;
P3=0xff;
P3=0xdf;//扫键
r1=P3;
P3=0xff;
r1=r1^0xff;
r1>>=1;
if(r1)//有键?
{
mkcnt++;
if(mkcnt>=4)//20ms
{
mkcnt=0;
m_key=r1;
}
else
m_key=key;
}
else
{
m_key=0;
mkcnt=0;
}
r2=m_key;
m_key=m_key&(key^m_key);//沿提取
key=r2;
P3=zs|0x0f;
}
void init()
{
TMOD=0x11;//中断定时/计数
TH0=0XEC; //定时5ms
TL0=0X78;
EA=1;
TR0=1;
TF0=0;
i=0;
s=0;
mkcnt=0;
key=0;
shancnt=0;//数码管闪烁计数
tz=0;
shan=0;
s_cnt=0;
nao=0;
}
void sjtz(void)
{
shancnt++;
if(shancnt>=100)
{shan=~shan;shancnt=0;} //500取反
//s=1;
if(k2)
{
xs++;
if(xs>=24)
xs=0;
}
if(k3)
{
fz++;
if(fz>=60)
fz=0;
}
}
void disp()//扫描数码管
{ if(!shan)
{
wx1=1;//位选关
wx2=1;
wx3=1;
wx4=1;
sm_sz++; //数码散转
if(sm_sz>=4)
{
sm_sz=0;
}
switch(sm_sz)
{
case 0:wx4=0; //选数码管一
P1=0xff;//取反,低电平
P1=sm_tab[sz0]; //分钟低
break;
case 1:wx3=0;
P1=0XFF;
P1=sm_tab[sz1]; //分钟高
break;
case 2: wx2=0;
P1=0xff;
P1=sm_tab[sz2]; //小时低
break;
case 3: wx1=0;
P1=0XFF;
P1=sm_tab[sz3]; //小时高
break;
}
}
else
{wx1=1;wx2=1;wx3=1;wx4=1;}
}
void nzsj(void) //闹钟时间
{
s=0;//秒控制标志位
shan=0;//闪烁标志位
if(k2)
{
nao=1;
nxs++;
if(nxs>=24)
nxs=0;
}
sz3=nxs/10;
sz2=nxs%10;
if(k3)
{
nao=1;
nfz++;
if(nfz>=60)
nfz=0;
}
sz0=nfz%10;
sz1=nfz/10;
}
void nzx(void)
{
ET1=1;
if(k4)
{nao=0;tz=0;}//按键按下闹钟标志位为零停止中断
if(!ncnt)
{
TR1=0;
k=sszymmh[i]+7*sszymmh[i+1]-1;//去音符振荡频率所需数据
TH1=FREQH[k];
TL1=FREQL[k];
time=sszymmh[i+2];
i=i+3;
ncnt=time*30;
TR1=1;
}
ncnt--;
if(i>=100)
{i=0;nao=0;tz=0;}
}
void TIM1_ISR() interrupt 3
{
TR1=0;
buz=~buz;//取反
TH1=FREQH[k];
TL1=FREQL[k];
TR1=1;
}
void pdnz(void) //判断闹钟模块
{
buz=1;
ET1=0;
if(xs==nxs&&fz==nfz&&nao==1) //闹钟时间到
{
tz=3;
if(k4)
{nxs=0;nfz=0;}
}
}
-
一周热门 更多>