分享一個51單片機做的秒表,有錯誤 如圖:
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
單片機源程序如下:
- #include "reg51.h"
- //******************************************
- //開始定義各個數字的字模
- char code cDISP_NumMod[16] =
- {
- 0x3F,0x06,0x5B,0x4F, 0x66,0x6D,0x7D,0x07,
- 0x7F,0x6F,0x77,0x40, 0x39,0x00,0x79,0x71
- };
- //定義各個數字位的位控制模型
- char code cDISP_BitMode[4] =
- {0xEF,0xDF,0xBF,0x7F};
- //開始定義全局變量
- char vDISP_Index ; //當前在顯示哪一位?在中斷服務中改變和使用
- char vDISP_SegValue[4]; //當前顯示數字對應的字模,該變量在BitNum,Integer,Low,High等函數中進行設置 ,在中斷服務程序中進行使用
- //char vDISP_Blink[4]; //控制哪些位需要閃爍。1:閃爍 0:正常顯示。 是在SetBlink函數中進行設置,在中斷服務中使用。
- //unsigned char vDISP_BlinkCount; //閃爍所需要的計數,0~255。<128時隱藏,>128時顯示。是在中斷服務程序中改變,每次中斷+1。
- //******************************************
- //*******************************************
- //初始化函數,初始化全局變量
- //*******************************************
- void DISP_Init(void)
- {
- TH0 = 0x3C;
- TL0 = 0xBA;
- ET0 = 1;
- EA = 1;
- TR0 = 1;
- vDISP_Index = 0;
- vDISP_SegValue[0] = cDISP_NumMod[0];
- vDISP_SegValue[1] = cDISP_NumMod[0];
- vDISP_SegValue[2] = cDISP_NumMod[0];
- vDISP_SegValue[3] = cDISP_NumMod[0];
- //初始化定時器T0,中斷頻率位200Hz,初始化相關寄存器
- //初始化全局變量
- }
- //*******************************************
- //設置四位數碼管上分別需要顯示什么數字
- //D0 數碼0上需要顯示的數字,取值范圍0~F
- //D1 數碼0上需要顯示的數字,取值范圍0~F
- //D2 數碼0上需要顯示的數字,取值范圍0~F
- //D3 數碼0上需要顯示的數字,取值范圍0~F
- //*******************************************
- void DISP_BitNum(char D3,char D2,char D1,char D0,char dp) //分別改變四位
- {
- //根據入口參數D0的值,設定全局變量vDISP_SegValue[3]的值
- //如果D0>0x0F,則不改變當前顯示的數字
- //否則使用D0去訪問cDISP_NumMod常量,送入vDISP_SegValue[3] D0-> vDISP_SegValue[3]
- if(D0>0x0F)
- {}
- else
- vDISP_SegValue[3] = cDISP_NumMod[D0];
- //根據入口參數D1的值,設定全局變量vDISP_SegValue[2]的值 D1-> vDISP_SegValue[2]
- if(D1>0x0F)
- {}
- else
- vDISP_SegValue[2] = cDISP_NumMod[D1];
- //根據入口參數D2的值,設定全局變量vDISP_SegValue[1]的值 D2-> vDISP_SegValue[1]
- if(D2>0x0F)
- {}
- else
- vDISP_SegValue[1] = cDISP_NumMod[D2];
- //根據入口參數D3的值,設定全局變量vDISP_SegValue[0]的值 D3-> vDISP_SegValue[0]
- if(D3>0x0F)
- {}
- else
- vDISP_SegValue[0] = cDISP_NumMod[D3];
- switch (dp)
- {
- case 0: break;
- case 1: vDISP_SegValue[2] = vDISP_SegValue[2]|0x80;break;
- case 2: vDISP_SegValue[1] = vDISP_SegValue[1]|0x80;break;
- case 3: vDISP_SegValue[0] = vDISP_SegValue[0]|0x80;break;
- }
- }
- //*******************************************
- //設置4位數碼管上需要顯示的整數,同時設置4位
- //value 需要顯示的整數數值,取值范圍0~9999
- //*******************************************
- void DISP_Integer(long Value,char dp) // 同時改變四位
- {
- //如果Value<0,就讓其等于0。
- //提取Value的千位存入局部變量D0,提取Value的百位存入D1,提取Value的十位存入D2,提取Value的個位存入D3
- //調用BitNum函數。
- char D3, D2, D1, D0;
- if (Value < 0)
- Value = 0;
- if (Value > 9999)
- {
- D0 = Value / 1000000;
- Value %= 1000000;
- D1 = Value / 10000;
- Value %= 10000;
- D2 = Value / 100;
- D3 = Value % 100;
- }
- else
- {
- D0 = Value / 1000;
- Value %= 1000;
- D1 = Value / 100;
- Value %= 100;
- D2 = Value / 10;
- D3 = Value % 10;
- }
- DISP_BitNum(D0, D1, D2, D3,dp);
- }
- //*******************************************
- //定時器
- //*******************************************
- void DISP_T0_ISR(void) interrupt 1
- {
- //給T0重新載入計數初值
- TH0 = 0x3C;
- TL0 = 0xBA;
- //設置段的控制端口
- P3 = cDISP_BitMode[vDISP_Index];
- //輸出位的控制端口
- P2 = vDISP_SegValue[vDISP_Index]; //對這句話改變一下就可以實現閃爍
- //改變Index的值,并使其在0~3之間變化。
- vDISP_Index++;
- vDISP_Index &= 3;
-
-
- }
復制代碼
錯誤程序:
秒表.7z
(14.29 MB, 下載次數: 398)
|