********************************/ void delay(uchar x) { uint b,c; for(b = x;b>0;b--) for(c = 110;c>0;c--); }
/********************************
函数名称: 定时器初始化函数time_init(void) 功 能: 定时器初始化 参 数: 无 返 回 值: 无
*********************************/ void time_init(void) { msec5=0; TMOD = 0x01; TH0 = (65536-9174)/256; TL0 = (65536-9174)%6; ET0 = 1; TR0 = 1; EA = }
/******************************** 函数名称: 显示函数display() 功 能: 数码管显示
参 数: uchar msec,uchar sec,uchar min 返 回 值: 无
*********************************/
void display(uchar msec,uchar sec,uchar min) { DUAN = table1[(msec)];// 0.01秒 5.64=64=0.04 WEI = 0x01; delay(2); WEI = 0x00; DUAN = table1[(msec/10)];// 0.1秒 5.64/10=56=0.6 WEI = 0x02; delay(2); WEI = 0x00; DUAN = table2[(sec)]; // 1秒 564=6 WEI = 0x04; delay(2); WEI = 0x00; DUAN = table1[(sec/10)]; // 10秒 564/10=56=6 WEI = 0x08; delay(2); WEI = 0x00; DUAN = table1[(min)]; // 1分 564/10=56=6 WEI = 0x10; delay(2); WEI = 0x00; DUAN = table1[(min/10)]; // 10分 564/10=56=6 WEI = 0x20; delay(2); WEI = 0x00; }
/******************************** 函数名称: 蜂鸣器函数 功 能: 蜂鸣器发声 参 数: 无 返 回 值: 无
*********************************/ void beep_led()
1;
- 10 -
{ beep = 0; delay(600); beep = 1; delay(600); led = 0; delay(600); led = 1; }
/******************************** 函数名称: 按键函数
功 能: 调试按键的函数 参 数: 无 返 回 值: 无
*********************************/ void keys() { if(keystart_stop==0) { delay(5); if(keystart_stop==0) TR0 = ~TR0; beep_led(); while(!keystart_stop); } if(keyrest==0) { delay(5); if(keyrest==0) TR0 = 0; msec5=0; msec10=0, second=0; minute=0; beep_led(); while(!keyrest); } }
/******************************** 函数名称: 主函数 功 能: 参 数: 无 返 回 值:
*********************************/ void main() {
uchar jishu=0; uchar flag=0;
uchar msec1=0,sec1=0,min1=0; uchar msec2=0,sec2=0,min2=0; time_init(); while(1) { keys(); // 键盘的扫描函数一定要放在while循环里边 msec=msec10; sec=second; min=minute; if(flag==1) { display(msec1,sec1,min1); } else if(flag==0) { display(msec,sec,min); } else {
- 11 -
display(msec2,sec2,min2); } if(keyrecord==0) { delay(5); if(keyrecord==0) { beep_led(); jishu++; if(jishu>2) { jishu=0; } else if(jishu==1) { msec1=msec10; sec1=second; min1=minute; } else if(jishu==2) { msec2=msec10; sec2=second; min2=minute; } } while(!keyrecord); } if(keydispaly==0) { delay(5); if(keydispaly==0) { beep_led() ; flag++; if(flag>2) flag=0; } while(!keydispaly); } } }
/********************************** 函数名称: 中断函数 功 能: 参 数: 无 返 回 值:
***********************************/ void timer0 () interrupt 1 {
TH0 = (65536-9174)/256; TL0 = (65536-9174)%6; msec10++; // msec10加一次等于 10ms if(msec10==100) // j=100 为1s { msec10 = 0; second++; if(second==60) // second=60 为1minute { second=0 ; minute++; if(minute==60) // minute=60 为1hour { minute=0 ; } } }
- 12 -
}
六、 仿真、实验验证过程及实现结果、现象
- 13 -
七、 结论
本设计的数字电子秒表系统采用89C52单片机为中心器件,利用其定时器/计数器定时和记数的原理,结合显示电路、LED数码管以及外部中断电路来设计计时器。将软、硬件有机地结合起来,使得系统能够实现八位LED显示,显示时间为0~59分59.59秒,计时精度为0.01秒,能正确地进行计时,同时能记录两次时间,并在计时后对上一次计时时间进行查询。其中软件系统采用C语言编写程序,包括显示程序,定时中断服务,延时程序,按键扫描程序等,并在keil4中调试运行,硬件系统利用PROTEUS强大的功能来实现,简单切易于观察,在仿真中就可以观察到实际的工作状态。
八、总结(体会)
开始做设计的时候总是会犯一些错误,只有经过不停的改错,不断地编译得到正确的程序,说明作为一名编程人员是不能粗心大意的,一个程序的质量的高低与你的细心与否有着很大的联系,在编程时,我充分地使用了结构化的思想,这样程序检查起来也比较方便,调试时也会方便很多。只要一个模块一个模块的进行调试就可以了,充分体现了结构化编程的优势。在设计中要求我要有耐心和毅力,细心是最重要的,稍有不慎,一个小小的错误就会导致结果的不正确,而对错误的检查要有足够的耐心,通过这次设计和设计中遇到的问题,我也积累了一定的经验。为了能完成这次
- 14 -
设计,我还复习了《数字电子技术》、《模拟电子技术》、《微机接口技术》、《单片机技术》、《C语言》。
通过这次单片机课程设计,我了解到自己在单片机方面还有很多不足,特别是单片机指令系统及stc89C52单片机各引脚的第二功能等等知识不够了解.因此我在设计中遇到不懂的东西就马上查资料或请教同学.这不仅加深了我对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。创新可以是在原有的基础上进行改进,使之功能不断完善,成为自己的东西。
- 15 -