51秒表计数器+倒计时(数码管两位数)
一:简介
我们实践的效果是用数码管显示0~99并在按下“转换键”后,实现60秒倒计时,并用蜂鸣器报警提示,兼并计数器和倒计时两种功能。
主要内容包括:
1.认识数码管
2.进行按键扫描
3.利用计时器计算分秒,利用中断将计算结果显示在数码管上。
二.硬件介绍
- 数码管相当于多个发光二极管组合,设想用它拼成了一个“8”,使用类型分为共阴和共阳。
(共阳,即高电平接在一起,需要其他管脚输出相应低电平,即可点亮),共阴反之。
三.仿真电路图
功能介绍:
四,程序代码
#include "reg52.h"
#include "intrins.h"#define uint unsigned int
#define uchar unsigned charuchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};sbit L4=P2^3;
sbit L3=P2^2;sbit K1=P3^0;
sbit K2=P3^1;
sbit K3=P3^2;
sbit K4=P1^0;
sbit K5=P1^1;
sbit K6=P1^2;
sbit beep=P2^4;uchar num,mum,n=0,m=60,shi,ge,shiw,gew;void delay(uint xms) //延时子函数
{uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);
}void Init() //初始化子函数
{TMOD=0X01; //设定定时器0的工作方式为1TH0=(65536-50000)/256; //定时器装初值一个周期50msTL0=(65536-50000)%256;TH1=(65536-50000)/256; //定时器装初值一个周期50msTL1=(65536-50000)%256;EA=1; //开总中断
}
void scankey() //键盘检测子函数
{if(K1==0) //检测键是否被按下{ET0=1;TR0=1;}if(K2==0){ET0=0;TR0=0;}if(K3==0){ET0=0;TR0=0;n=0;num=0;ge=0;shi=0;P0=table[0]; }if(K5==0) //检测键是否被按下{ET1=1;TR1=1;}if(K6==0){ET1=0;TR1=0;}}void main()
{Init(); //初始化子函数调用 while(1)
{ scankey(); //不断键盘扫描 if(K4==1) //不断键盘扫描 { L4=1; //打开数码管个位位选 P0=table[ge]; //数码管个位赋值delay(1); //延时 送入数据的反应时间L4=0; //关闭数码管个位位选delay(1);L3=1; //打开数码管十位位选 P0=table[shi]; //送入数据delay(1); L3=0; //关闭数码管十位位选delay(1);}else{ L4=1; //打开数码管个位位选 P0=table[gew]; //数码管个位赋值delay(1); //延时 送入数据的反应时间L4=0; //关闭数码管个位位选delay(1);L3=1; //打开数码管十位位选 P0=table[shiw]; //送入数据delay(1); L3=0; //关闭数码管十位位选delay(1);}}}
void Timer0()interrupt 1
{TH0=(65536-50000)/256; //定时器重装初值TL0=(65536-50000)%256;num++;if(num==20) //定时器每进行一个周期num加1,运行20个周期即为1s{num=0; //到1秒,num清0重新开始n++; //倒计时1秒if(n==99)n=0;shi=n/10; //两位数分离赋给数码管十位显示ge=n%10; //两位数分离赋给数码管个位显示}
} void Timer1()interrupt 3
{TH1=(65536-50000)/256; //定时器重装初值TL1=(65536-50000)%256;mum++;if(mum==200) //之前的是20,运行不能实现,不过写200实测准确{mum=0; //到1秒,num清0重新开始m--; //倒计时1秒if(m==0){m=60;beep=0;delay(20);}shiw=m/10; //两位数分离赋给数码管十位显示gew=m%10; //两位数分离赋给数码管个位显示}
} 说明:1.代码并非最简,不过便于理解。
(详细工程已上传到下载中心,需要的可以自提)