89C51单片机最小系统设计Word下载.docx
《89C51单片机最小系统设计Word下载.docx》由会员分享,可在线阅读,更多相关《89C51单片机最小系统设计Word下载.docx(19页珍藏版)》请在冰点文库上搜索。
(5)由P2、0~P2、3接三极管,驱动共阳七段数码显示管
(6)ckey0,ckey1接P3、2与P3、3两个引脚,为两个外部中断
4.电路焊接实物图
(1)正面
(2)反面:
由于显影、腐蚀过程做得不好,导致电路板过度腐蚀,但就是经过修改之后,电路可以正常运行,并无大碍,只就是不美观。
(4)电路板工作时。
此时为显示时钟得秒
显示时钟
显示秒表
显示计数器
5、程序设计分析
(1)程序代码
#include〈Reg51、h〉
sbitkey0=P1^0;
sbit key1=P1^1;
//定义key0,key1接口
unsignedcharflag,con,mcount;
//flag为计数到一秒时给时钟发得信号
unsignedchar count= 0;
unsignedcharseccount=0;
//作为时钟得秒得计量单位
unsignedcharhour=0;
//时钟得时
unsignedcharmin=0;
//时钟得分
unsignedchar sec = 0;
//时钟得秒
unsignedchar keypress0,keypress1,mode,ms,s,ss,start;
unsigned char
Displaynum[]={0x14,0xd7,0x4c,0x45,0x87,0x25,0x24,0x57,0x04,0x05,0x10,0xd3,0x48,0x41,0x83,0x21,0x20,0x53,0x00,0x01,0xff,0xfb};
//数码管十六进制译码表
unsignedcharcontrolnum[]={0x08,0x04,0x02,0x01};
//控制四个数码管显示
unsignedchar DisplayBuff[]={0x00,0x00,0x00,0x00};
//每个数码管得值
void display_state();
//数码管显示子程序
voidkeyscan();
//键盘扫描子程序
voidtimer();
//秒表子程序
unsignedcharcount1,flag1,t_adjust=0,tm_adjust=0;
unsigned charbKey0Pressed=0, bKey1Pressed=0;
unsignedchar ucStatus=0;
void main()
{
TMOD=0x01;
//定时器0工作在模式1,GATE=0,C/t=0,16位模
TH0=(2^16-5000)/256;
//定时器0预存值,
TL0= (2^16—5000)%256;
TR0=1;
//定时器0启动
ET0=1;
//定时器中断0允许
EA=1;
//开中断
ﻩ IT0=1;
//外部中断0下降沿触发
IT1=1;
//外部中断1下降沿触发
EX0=1;
//外部中断0允许
EX1=1;
//外部中断1允许
PX1=1;
//外部中断1为高优先级中断
while
(1) //死循环,
{
if(flag==1) //时钟显示
{
ﻩflag =0;
sec++;
if(sec==60)
{sec=0;
min++;
if(min==60)
{min= 0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
display_state();
keyscan();
timer();
}
}
//////////////////////////////////ISR中断服务程序,每5ms产生一个定时器0中断
voidDisplay()interrupt1
{
TH0 =(2^16-5000)/256;
TL0=(2^16-5000)%256;
seccount++;
ﻩmcount ++;
ﻩkeypress0++;
ﻩ keypress1++;
P2=0x00;
//P2口先清零
ﻩ P0 =Displaynum[DisplayBuff[count]];
//P0口输出
P2=controlnum[count];
//P2口输出
count++;
if(count==4)
ﻩ count=0;
if(seccount==200)//200*5ms=1s
{seccount=0;
flag=1;
//每过1秒给时钟信号加一秒
}
}
///////////////////////////////////////////
voiddisplay_state()
{
if(mode==0)//时钟模式,显示时间
{
DisplayBuff[0]= hour/10;
DisplayBuff[1] =(hour%10)+10;
//“+10"
就是为了显示加点得数字
DisplayBuff[2]=min/10;
DisplayBuff[3]=min%10;
}
if(mode==1)//秒表模式,显示秒表
DisplayBuff[0]= ss +10;
//“+10"
DisplayBuff[1]= s/10;
DisplayBuff[2]=(s%10)+10;
DisplayBuff[3] =ms;
if(mode ==2)// 计数器模式,显示计数
{
DisplayBuff[0]=count1/1000;
//千位
DisplayBuff[1]= (count1-(count1/1000)*1000)/100;
//百位
DisplayBuff[2]=(count1—(count1/100)*100)/10;
//十位
DisplayBuff[3] =count1%10;
//个位
ﻩif(mode==3) //显示时钟得秒,
ﻩ{
DisplayBuff[0]=20;
//第一位不显示
DisplayBuff[1]=21;
//第二位显示一个点
DisplayBuff[2]= sec/10;
//显示秒得十位
DisplayBuff[3]= sec%10;
//显示秒得个位
}
//**************//
//键盘扫描子程序//
//**************//
void keyscan()
if(!
key0&&
bKey0Pressed ==0)//检测到key0按下
keypress0 =0;
ﻩbKey0Pressed =1;
//防止重入此判断
while(!
key0);
//如果没放开,就等下去
if(key0&&bKey0Pressed==1)//检测到key0放开
{
ﻩbKey0Pressed =0;
//防止重入此判断
ﻩif(keypress0<120)ﻩ//如果就是短按
ﻩ {
if(ucStatus==0x02)
ﻩ{
ﻩ ucStatus= 0x00;
ﻩmode=0;
//时钟模式
ﻩt_adjust=0;
elseif(ucStatus ==0x00)
ﻩ ﻩ{
ucStatus =0x01;
mode=1;
//秒表模式
}
ﻩﻩﻩelse if(ucStatus==0x01)
ﻩ{
ﻩ ﻩucStatus= 0x02;
mode=2;
//计数模式
}
ﻩelseif(keypress0〉200) //如果就是长按
mode=3;
//显示时钟得秒得模式
}
ﻩ////////////////////////////////
if(mode==0) //进入时钟模式后
{ﻩ
if(!
key1&
&
(bKey1Pressed==0))
ﻩ{keypress1 =0;
bKey1Pressed=1;
while(!
key1);
ﻩ}
if(key1&
&(bKey1Pressed==1))
{
ﻩ bKey1Pressed =0;
if(keypress1 >
=200) //如果就是长按
{
t_adjust++;
ﻩﻩif(t_adjust==3)
ﻩﻩt_adjust=0;
}
ﻩ else if(keypress1< 120) 如果就是短按
ﻩ switch (t_adjust)
ﻩﻩﻩ{
ﻩ case1:
{ //调整分
min++;
ﻩﻩ sec =0;
ﻩﻩﻩ if(min== 60)
ﻩﻩ min= 0;
ﻩ}
ﻩﻩﻩﻩbreak;
ﻩcase2:
{//调整时
ﻩ hour ++;
ﻩﻩ sec=0;
ﻩﻩif(hour==24)
ﻩﻩﻩ hour=0;
ﻩﻩﻩﻩ}
ﻩ break;
ﻩdefault:
break;
ﻩﻩ}
}
else if(mode ==1)//进入秒表模式
{
if(!
key1&&bKey1Pressed==0)
{
keypress1 =0;
ﻩbKey1Pressed= 1;
while(!
key1);
}
if(key1&
&bKey1Pressed==1)
ﻩbKey1Pressed=0;
if(keypress1 <
120)//短按
ﻩ if(flag1==0) {start=2;
flag1=1;
}//start=2代表秒表开始计时
ﻩﻩﻩelse{start=0;
flag1=0;
} //start=0,秒表停止计时
ﻩ }
ﻩelseif(keypress1>200) //长按
start=1;
//秒表清零
ﻩ}
}
}
voidtimer()//秒表子程序
{
if(mode==1)//进入秒表模式才执行
{
if(start==1)//清零
{
ms=0;
s =0;
ﻩss=0;
mcount=0;
ﻩ}
ﻩif(start==2) //秒表开始计时
if(mcount==20) //20*5ms=0、1s
{
mcount=0;
ms++;
ﻩ if(ms==10)//10*0、1s=1s,s++
ﻩ {ms= 0;
ﻩﻩ s++;
ﻩif(s==100) //100s
ﻩﻩ {s=0;
ss++;
ﻩﻩ if(ss==10)
ﻩﻩ{ss=0;
ﻩ s =0;
ﻩms=0;
ﻩ}
ﻩﻩﻩ}
ﻩﻩﻩ}
}
ﻩ}
if(start==0);
//秒表停止
}
//////////////////////
voidit0(void)interrupt0using 1//外部中断0 服务程序
if(mode==2) //只有在计数模式才执行
count1++;
//每响应一次,计数加一
if(count1==10000)//超出四位时,不能再加
count1=9999;
void it2(void) interrupt 2 using 2//外部中断0 服务程序
if(mode==2)//只有在计数模式才执行
if(count1!
=0)
{count1—-;
}//计数减一,不显示负数,当减到零时便不能再减