STC89C52RC数码管秒表程序编写

来源:互联网 发布:数据的预处理包括哪些 编辑:程序博客网 时间:2024/05/22 04:48
数码管显示秒表,芯片STC89C52RC。

具体要求,采用动态扫描的方式让,6个数码管前三个显示秒数,后两个显示毫秒。第四个不用。秒数精确到1%。


#include <reg52.h>#define uint unsigned int#define uchar unsigned char#define N2000//定义中断初值。2000 x 1/12MHz x 12 = 2msuchar point;//中断点,或计数点。比如point的值为5,那么当经过5个N(2000)时会计数一次。uchar code table[] = { //数码管能显示的数值0x0~0xf0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};sbit dula = P2^6;//数码管段选引脚定义sbit wela = P2^7;//数码管位选引脚定义int wenum;//控制显示哪个数码管uchar code wetable[] = { //用到的数码管位选开关0xfe,0xfd,0xfb,0xef,0xdf};int fre = 0; //作为发生时钟计数次数的计数。时钟计数5次为10ms(5 x 2ms)。uint s,ms;//秒,毫秒uint numBuffer[3] = {0};//用于存取s,ms每一位的存储。比如s=123秒。那么numBuffer[0]=1;numBuffer[1]=2;numBuffer[2]=3uint timebuffer[5] = {0}; //因为毫秒的显示只有两位计数0~99.秒的计数三位0~999。所以共5个存储空间即可。void divNumber(uint ); //分离整数。把整数的百、十、个三位的数值分离开。存到numBuffer中。void SavTime(uint ,uint ); //把时间保存到timebuffer中。//如51秒350毫秒,数组中依次为05135。毫秒只显示两位即可,以10毫秒为单位。//如678秒290毫秒,数组中依次为67829。void main(){point = 0;  wenum = 4;ms = s = 0;//s = 995; //这个可以打开。那么时间就会从995s开始显示,到999秒会从0开始。TMOD = 0x01;  //打开mod1.TH0 = (65536 - N) / 256; //高位附初值TL0 = (65536 - N) % 256; //低位附初值EA = ET0 = TR0 = 1; //EA 总中断;ET0 时钟中断;TR0启动计数器。while(1);}void timer0() interrupt 1{ //时钟0,中断数是1;时钟1,中断数是3TH0 = (65536 - N) / 256;TL0 = (65536 - N) % 256;point++;if(point == 1){wenum--;if(wenum < 0)wenum = 4;wela = 1;P0 = wetable[wenum];//从右到左显示wela = 0;dula = 1;P0 = table[timebuffer[wenum]];dula = 0;fre++;if(fre == 5){ //为什么要5次计数毫秒才++?程序尾解释。ms++;if(ms == 100){ms = 0;s++;if(s == 1000)s = 0;}SavTime(s,ms);point = 0;fre = 0;}point = 0;}}void divNumber(uint num){for(int b=2;!(b < 0);b--,num/=10)numBuffer[b] = num %10;//b的初值是2,原因是num的最大值是3位数。那么数组的大小刚好够用。}void SavTime(uint STs,uint STms){  //把秒和毫秒都存到数组中。divNumber(STms);timebuffer[4] = numBuffer[2];timebuffer[3] = numBuffer[1];divNumber(STs);timebuffer[2] = numBuffer[2];timebuffer[1] = numBuffer[1];timebuffer[0] = numBuffer[0];//  0 0 0   0 0//  秒    毫秒}
秒表上毫秒一般都显示两位。实际上都知道毫秒~秒直接是1000级,三位。那为了只显示两位我们也只能取高位的显示。以10毫秒为单位的话,就是0~99了。也就是说我们10ms要改变数码管的显示了。比如 111 87,这是111秒870毫秒(10ms为单位)。过10ms就要显示111 88了。所以,题目要求后两个数码管显示毫秒,只能这样10ms为单位做了。
时钟频率是11~12MHz,这里假设是12M.
如果你想得到精确的时间,那么2ms = 2000 * (12 / 时钟频率)。那么这里就假设是12MHz。这么算下来2ms =2000 * 1/12MHz * 12(时钟周期)。
这个2ms代表了什么?就是代表程序里面设置的时钟2ms会加1一次。也就是说10ms的时间我需要加5次2ms才可以。


那干嘛不把初值N设置为10000,直接算出来的就是10ms了(10000 * 1/12MHz * 12 = 10ms)
那是因为这个动态数码管显示的原因。它每个计数加1一次要显示一个数码管的。一共5个数码管要显示,那么就得在10毫秒内进行至少5次的扫描。对于人眼来说,已经分辨不出跳变了。10ms内必须有5的倍数次扫描才行。

0 0
原创粉丝点击