利用单片机的定时器/计数器定时和记数的原理,结合集成电路芯片8051、LED数码管以及实验板上的按键来设计计时器。将软、硬件有机地结合起来,使得系统能够正确地进行计时,数码管能够正确地显示时间。其中本实验设计了四个开关按键:其中key2按键按下去时开始计时,即秒表开始键(同时也用作暂停键),key1按键按下去时数码管清零,复位为“00.0”,key3按键按下去时数码管复位为“60.0”(用于倒计时),key4按键按下去则是数码管开始“逐渐自减”倒计时。
51单片机程序设计:[10]51单片机00.0~59.9秒表――工具/原料51单片机开发板Keil C IDE开发环境51单片机程序设计:[10]51单片机00.0~59.9秒表――方法/步骤
51单片机程序设计:[10]51单片机00.0~59.9秒表 1、
进行计时并在数码管上显示时间,则可利用MCS-51系列单片机的芯片AT89C52的P3.4,P3.5,P3.6,P3.7作为按键的入口;定时器T0作为每0.1秒减一的定时器;定时器T1作为每0.1秒加一的定时器。其中“开始”按键当开关由上向下拨时开始计时,此时若再拨“开始”按键则数码管暂停;“清零”按键当开关由上向下拨时数码管清零,此时若再拨“开始”按键则又可重新开始计时。
硬件电路图如下图:
51单片机程序设计:[10]51单片机00.0~59.9秒表 2、
首先要有初始化程序,通过初始化程序,将对主程序所用到的变量、常量以及各个参数和所调用的子函数定义。其次还有显示程序、按键扫描及处理程序、时钟程序和倒计时程序,系统软件流程图图如图,具体代码:
51单片机程序设计:[10]51单片机00.0~59.9秒表_单片机秒表课程设计
51单片机程序设计:[10]51单片机00.0~59.9秒表_单片机秒表课程设计
51单片机程序设计:[10]51单片机00.0~59.9秒表 3、
#include<reg52.h> //52系列单片机头文件#define uchar unsigned char //宏定义#define uint unsigned intsbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端sbit key1=P3^2; //申明四个按键的锁存端sbit key2=P3^4;sbit key3=P3^6;sbit key4=P3^7;uchar code table[]={ //含有0~9的数字数组0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};void delayms(uint); //声明延时函数void display(uchar,uchar,uchar); //声明显示函数void keyscan(); //声明按键函数uchar num1,num2,bai,shi,ge; //变量声明uint num;void main() //主函数入口{TMOD=0x11; //设置TO,T1定时器TH0=(65536-45872)/256; //装初值11.05992M晶振定时50ms数为45872TL0=(65536-45872)%256;TH1=(65536-45872)/256;TL1=(65536-45872)%256;EA=1; //开总中断ET0=1; //开启定时器T0中断ET1=1; //开启定时器T1中断
while(1) //程序停在这里等待中断的发生,这个大循环也是实现数据显示的主体{keyscan();
//三个数码管要选送的数据bai=num/100; //百位 shi=(num-100*bai)/10; //十位ge=num-100*bai-shi*10; //个位
//直接把第二只数码管的小数点烧出来
P0=0x80; //送段选数据dula=1; //关闭断选dula=0; //打开段选P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位锁存端造成混乱
P0=0xfd; //送位选数据wela=1; //打开位选wela=0; //关闭位选delayms(5); //延时
display(bai,shi,ge); }}void display(uchar bai, uchar shi,uchar ge){
P0=table[bai]; //送段选数据dula=1; //打开段选dula=0; //关闭断选P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位锁存端造成混乱
P0=0xfe; //送位选数据wela=1; //打开位选wela=0; //关闭位选delayms(5); //延时
P0=table[shi]; //送段选数据dula=1; //打开段选dula=0; //关闭断选P0=0xff;//送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位锁存端造成混乱
P0=0xfd; //送位选数据wela=1; //打开位选wela=0; //关闭位选delayms(5); //延时
P0=table[ge]; //送段选数据dula=1; //打开段选dula=0; //关闭断选P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位锁存端造成混乱
P0=0xfb; //送位选数据wela=1; //打开位选wela=0; //关闭位选delayms(5); //延时}void delayms(uint xms) //延时子函数{uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--);}void keyscan(){if(key1==0) //清零 { delayms(10); //延时去抖 if(key1==0) { while(!key1) //等待按下 { TR0=0; //定时器TR0关闭 TR1=1; //定时器TR1打开 num=0; //送数据num=0 TR1=0; //定时器TR1关闭 }}}if(key2==0) //暂停和开始 { delayms(10); if(key2==0) { while(!key2); TR0=0;TR1=~TR1; //每次按下,TR1的状态时相反的 } }if(key3==0) //使计数器显示为60.0 { delayms(10); if(key3==0) { while(!key3); TR0=0; TR1=1; num=600; TR1=0; } }if(key4==0) //实现计数器的倒数功能 { delayms(10); if(key4==0) { while(!key4); TR1=0; TR0=1; } }}
void T0_time()interrupt 1{ TH0=(65536-45872)/256; //重装初值 TL0=(65536-45872)%256; num2++; if(num2==2) //如果到了2次,说明0.1秒的时间到 { num2=0; //然后把num2清零重新再计2次 num1++; if(num1==10) num1=0; if(num==0) //当num自减为0时,重新为60.0,再开始倒计时 num=600; num--; //num逐渐自减}
}
void T1_time()interrupt 3{ TH1=(65536-45872)/256; //重装初值 TL1=(65536-45872)%256; num2++; if(num2==2) //如果到了2次,说明0.1秒的时间到 { num2=0; //然后把num2清零重新再计2次 num1++; if(num1==10) num1=0; num++; //num逐渐自加 if(num==600) //这个数十用来送给数码管显示的,到了60.0后归零 num=0; } }
51单片机程序设计:[10]51单片机00.0~59.9秒表 4、
效果图: