1. 程式人生 > >STC89C52RC數碼管秒錶程式編寫

STC89C52RC數碼管秒錶程式編寫

數碼管顯示秒錶,晶片STC89C52RC。

具體要求,採用動態掃描的方式讓,6個數碼管前三個顯示秒數,後兩個顯示毫秒。第四個不用。秒數精確到1%。

#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
//	  秒    毫秒
}
	
秒錶上毫秒一般都顯示兩位。實際上都知道毫秒~秒直接是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的倍數次掃描才行。

相關推薦

STC89C52RC數碼秒錶程式編寫

數碼管顯示秒錶,晶片STC89C52RC。具體要求,採用動態掃描的方式讓,6個數碼管前三個顯示秒數,後兩個顯示毫秒。第四個不用。秒數精確到1%。 #include <reg52.h> #define uint unsigned int #define uch

pd32組合語言 數碼拆字程式數字大於255

pd32實驗箱,微機原理實驗 多加熱爐爐溫檢測系統的設計,兩個0809通道地址分別為3DCH,3D8H,分別讀取A/D轉換後的資料儲存在4000H和4001H,將AD轉後的資料(0-255)再轉換成50-350之間的資料,再進行拆字 要顯示的資料儲存在4002H-4004H,和4008H-400

微控制器按鍵與數碼試驗程式 Proteus模擬

最近溫習一下微控制器,通過proteus 7.8模擬了一下,感覺效果不錯。 微控制器程式如下: /* 51微控制器 按鍵與數碼管實驗,用proteus 7.8模擬通過。 通過點按鍵, K1:數碼管數字加一,0~F,加上F後再從0開始。 K2:數碼管數字減一,F~0,

微信小程式 Canvas 自定義時間顯示器 數碼顯示

微信小程式自定義時間顯示器Demo 廢話不多話,還是依舊上圖再說,哈哈 怎麼樣,效果還是不錯的吧,因專案要求,要畫出類似於數碼管顯示的時間樣式,沒辦法,雖然不咋過好弄,但工作畢竟得做,於是乎,樓主,花了3個小時在那裡硬生生的算座標,差不多還是給擼出來,樓主寫成了一個外掛,方便大

KST-51微控制器:c語言程式設計實現數碼動態顯示秒錶的倒計時

/*60S倒計時*/ /*個位每1S變一次,從0~9*/ /*十位,個位為0的下一秒十位發生變化*/ #include<reg52.h> sbit ADDR0=P1^0; sbit ADDR1=P1^1; sbit ADDR2=P1^2; sbit ADDR3

51微控制器按鍵控制數碼加減和秒錶

#include<reg52.h> #define uchar unsigned char #define uint unsigned int sbit k1=P3^4; sbit k2=P3^5; sbit k3=P3^6; sbit k4=P3^7; sbit du=P

靜態數碼——小白的單片機筆記

bit 顯示 實驗 main char 兩個 調試 nbsp err 數碼管按照接線方式分為:共陰和共陽。 對於實驗板的數碼管器工作過程如下: 單片機通過接口(在此為P2^2,P2^3,P2^,4)與138譯碼器通訊,譯碼器Y0接口使最後一個LED數碼管工作。 P0口發送數

動態數碼——小白的單片機筆記

存儲 value *** 通訊 mqc com har sign logs 138譯碼器控制LED數碼管使能 138譯碼器的ABC接口接線: A=P2^2;B=P2^3;C=P2^4; 74H245與P0口通訊控制數碼管顯示內容。 ******************

數字數碼

開啟 png () 數碼 dst lean itl bit led 數字或字母可以用7位數碼管顯示(就是排列為8字形的7個數碼管) 對於大型燈管,為了節約使用,在切換數字的時候,如果該燈管的狀態沒有改變,則不需要對該燈管關了再開。 已知一個數字變化的系列,求7個數碼管開關

數碼按鍵加減一

int 參數 image spa pre log -- main 等於 //按鍵加一或減一 #include <reg51.h> #include <stdio.h> int duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6

單片機入門-矩陣鍵盤控制數碼顯示

矩陣 right 控制 入門 i/o num .cn mar oid 任務簡述:通過按下4X4矩陣鍵盤實現數碼管對應顯示數字 實現方式:通過行列分接法,可以節省使用單片機的I/O口,掃描矩陣鍵盤是否有按下,判斷P2端口得到的值。 protues 硬件系統 單片機晶振復位電

FPGA學習之數碼(封裝)顯示時間

rtu 環境 tro gb2312 配置 fpga 模塊 rtl 顯示時間 一、實驗目的:學習數碼管封裝以及顯示時間。二、實驗環境:FPGA開發板AX301,Quartus ii三、實驗介紹:將數碼管顯示模塊封裝起來,同時通過不斷讀取RTC時鐘的時分秒值,將之顯示在數碼管。

串口通訊 ADC0804 數碼

lag fin 數碼管 -a tab ins value return con #include<reg52.h> #include<stdio.h> #include<intrins.h> #define uchar unsigne

數碼顯示從1開始計數三位(51單片機)

數碼管 pla mod ++ time play ble -- == #include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charuc

數碼的動態掃描與驅動

fin 文件 芯片 組成 == test 關於 實現 沒有 數碼管的基本原理     關於數碼管,一個單個的數碼管可以看做是多個led燈的集合,如下圖所示 其中的8和。都是LED組成的,通過引腳上電即可點亮不同的LED然後組成不同的數字,這個過程在數碼管的設計中叫做段選。

Arduino 數碼LED屏驅動

art 溫度 git 技術 () article 時間 ack 計劃 今天測試數碼管LED屏驅動,用某產品的一個共陰極的LED屏,依據電路圖做數碼管LED屏的檢測。 代碼寫得有些冗長。有好幾種驅動的方法,這裏僅僅是當中一種最直接的方案。抽出時間要做個更有效率的調用

串口通信數碼顯示輸入數字

重載 輸入 十六進制 十六 main 終端 def config oid #include <reg52.h> sbit ADDR0=P1^0;sbit ADDR1=P1^1;sbit ADDR2=P1^2;sbit ADDR3=P1^3;sbit ENLED=

數碼倒計時

time ++ nbsp 記錄 加載 聲明 i++ 動態 bsp //全部數碼管計時 #include<reg52.h> /**聲明使能IO口 */ sbit ADDR0=P1^0; sbit ADDR1=P1^1; sbit ADDR2=P1^2; sbit

共陽極數碼三極驅動

數碼管 spa unsigned rup pan nbsp fin tab ble 1 #include<reg51.h> 2 3 4 #define unint unsigned int 5 #define unchar unsigned ch

數碼無限循環

oid 控制 fin show fine amp while k60 unsigned #include"STC15F2K60S2.H"#include"intrins.h"#define uint unsigned int#define uchar unsigned ch