|
基于51單片機精確到0.1秒可回看記錄的秒表程序
可回看計時記錄
下載:
miaobiao5.rar
(20.28 KB, 下載次數: 21)
2016-12-20 20:04 上傳
點擊文件名下載附件
- #include <reg51.h>
- unsigned char code leddata[]= { 0x3F, 0x06, 0x5B, 0x4F, //0 1 2 3
- 0x66, 0x6D, 0x7D, 0x07, //4 5 6 7
- 0x7F, 0x6F, 0x77, 0x7C, //8 9 A b
- 0x39, 0x5E, 0x79, 0x71, //c d E F
- 0x76, 0x38, 0x37, 0x3E, //H L n u
- 0x73, 0x5C, 0x40, 0x00, //P o - 清屏
- };
- #define digitData P0 //數碼管數據
- #define startBtn 0 //按鍵值
- #define resetBtn 1
- #define counterBtn 2
- sbit DX = P2^6;//段選
- sbit WX = P2^7;//位選
- sbit kaiShi = P3^4;//開始、暫停按鍵
- sbit chongZhi = P3^5;//重置按鍵
- sbit jiCi = P3^6;//計次、記錄查看按鍵
- unsigned int recode[8] = {0};//記錄數據
- unsigned char recodeNum = 0;//記錄數據值位置
- unsigned char showRe = 0; //查看哪項記錄值
- unsigned int times = 0; //當前計時時間
- unsigned int saveTimes = 0;//暫停查看記錄時保存時間數據
- unsigned char counter = 0;//定時器次數,構成100ms
- unsigned char shuanXi = 0,sXW = 1;//刷新數碼管
- unsigned char runState = 0;//0表示停止,1表示運行
- unsigned char keyTemp[3]= {0}; //按鍵按下狀態持續時間
- //六位數碼管顯示 dat:顯示內容下標 wei:哪一個數碼管
- void display(unsigned char dat,unsigned char wei)//wei 1-6
- {
- digitData = 0xff; //關掉顯示 消除重影
- WX = 1;
- WX = 0;
- //如果不先關閉顯示,不論先段選還位選(位選前關閉都不行),而且必須先送段選,再送位選,
- //先位選則當前位置會顯示上次殘留段選數據 導致重影
- digitData = leddata[dat];//段選
- DX = 1;
- DX = 0;
- digitData = ~(1<<(wei-1));//位選
- WX = 1;
- WX = 0;
- }
- //判斷當前按鍵
- unsigned char scanKey()
- {
- P3 = 0x70;//k1 k2 k3給高
- if(kaiShi==0)//開始鍵按下
- {
- if(keyTemp[0] == 0) keyTemp[0]=1 ;//按鍵按下 開始記延時
- }
- else
- {
- keyTemp[0] = 0; //有抖動重新延時
- }
- if(chongZhi==0)
- {
- if(keyTemp[1] == 0) keyTemp[1]=1 ;
- }
- else
- {
- keyTemp[1] = 0;
- }
- if(jiCi==0)
- {
- if(keyTemp[2] == 0) keyTemp[2]=1 ;
- }
- else
- {
- keyTemp[2] = 0;
- }
- if(keyTemp[0]>5) return startBtn; //5次 5*2ms 超過10ms 消抖
- if(keyTemp[1]>5) return resetBtn;
- if(keyTemp[2]>5) return counterBtn;
- return 0xFF; //沒有按鍵
- }
- void Timer0Init(void) //2毫秒@11.0592MHz
- {
- //AUXR &= 0x7F; //定時器時鐘12T模式
- TMOD &= 0xF0; //設置定時器模式
- TMOD |= 0x01; //設置定時器模式
- TL0 = 0xCF; //設置定時初值
- TH0 = 0xF8; //設置定時初值
- TF0 = 0; //清除TF0標志
- TR0 = 1; //定時器0開始計時
- ET0 = 1; //運行定時器0中斷
- EA = 1; //開全局中斷
- }
- void main()
- {
- unsigned char keyValue = 0xFF,keyT = 0xFF;//按鍵值
- unsigned char weiXian[6] = {0,22,0,0,22,0};
- Timer0Init();
- while(1)
- {
- if(shuanXi)//刷新sXW位置的數碼管中
- {
- if(times>=6000) //十分鐘
- {
- times = 0;
- }
- weiXian[0] = times/600;//分鐘
- weiXian[2] = times/10%60/10;
- weiXian[3] = times/10%60%10;
- weiXian[5] = times%10;
- display(weiXian[sXW-1],sXW);
- shuanXi = 0;
- }
- keyT = scanKey();//當前按鍵值
- if(keyT!=keyValue)//當前按鍵值與上次按鍵值不同,則表示按鍵狀態改變。需要做按鍵處理
- {
- keyValue = keyT;
- //P1 = keyValue;
- switch(keyValue)//按鍵處理
- {
- case startBtn://開始暫停按下
- //if(runState) TR0 = 0; else TR0 = 1;
- //runState ? (TR0 = 0) : (TR0 = 1);
- runState = !runState;//改變狀態
- if(runState)//恢復時間
- {
- times = saveTimes;
- }
- else//保存時間
- {
- saveTimes = times;
- }
- break;
- case resetBtn: //重置
- if(!runState)
- {
- times = 0;
- saveTimes = 0;
- recodeNum = 0;
- P1 = 0xFF;
- }
- break;
- case counterBtn: //記錄或查看記錄
- if(runState)//運行時,記錄
- {
- if(recodeNum<8)
- {
- recode[recodeNum++] = times;
- P1 = (0xFF<<recodeNum);//點亮recodeNum個燈
- }
- }
- else//暫停查看記錄
- {
- P1 = (0xFF ^(1 << showRe));//點亮showRe位置的燈
- times = recode[showRe++];
- if(showRe >= recodeNum)
- {
- showRe = 0;//循環查看記錄
- }
- }
- break;
- }
- }
- }
- }
- void T0_2ms() interrupt 1
- {
- //定時器重新賦初值 放在終端服務程序最開始有利于降低定時中斷誤差
- TL0 = 0xCF; //設置定時初值
- TH0 = 0xF8; //設置定時初值
- if(++counter>=50 && runState)//運行狀態下100ms 加0.1秒
- {
- times++;
- counter = 0;
- }
- shuanXi = 1;//數碼管周期刷新
- if(++sXW>6) //六位循環刷新
- {
- sXW = 1;
- }
- if(keyTemp[0]) keyTemp[0]++;//按鍵持續
- if(keyTemp[1]) keyTemp[1]++;//按鍵持續
- if(keyTemp[2]) keyTemp[2]++;//按鍵持續
- }
復制代碼
|
|