STC89C52RC數碼管秒錶程式編寫
具體要求,採用動態掃描的方式讓,6個數碼管前三個顯示秒數,後兩個顯示毫秒。第四個不用。秒數精確到1%。
秒錶上毫秒一般都顯示兩位。實際上都知道毫秒~秒直接是1000級,三位。那為了只顯示兩位我們也只能取高位的顯示。以10毫秒為單位的話,就是0~99了。也就是說我們10ms要改變數碼管的顯示了。比如 111 87,這是111秒870毫秒(10ms為單位)。過10ms就要顯示111 88了。所以,題目要求後兩個數碼管顯示毫秒,只能這樣10ms為單位做了。#include <reg52.h> #define uint unsigned int #define uchar unsigned char #define N 2000 //定義中斷初值。2000 x 1/12MHz x 12 = 2ms uchar point; //中斷點,或計數點。比如point的值為5,那麼當經過5個N(2000)時會計數一次。 uchar code table[] = { //數碼管能顯示的數值0x0~0xf 0x3f,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]=3 uint 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,中斷數是3 TH0 = (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 // 秒 毫秒 }
時鐘頻率是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的倍數次掃描才行。