效果預(yù)覽
IMG_1120
相關(guān)的開(kāi)發(fā)板原理圖解析
通過(guò)查看這三個(gè)原理圖我們可以得知控制K1、K2、K3及K4是通過(guò)P31、P30、P32及P33來(lái)實(shí)現(xiàn)的,控制8個(gè)數(shù)碼管是P22、P23及P24來(lái)實(shí)現(xiàn),
控制發(fā)光二極管則由P00-P07來(lái)實(shí)現(xiàn)。
正式代碼
代碼分為三部分分別為main.c、key.h、key.c
main.c代碼部分
#include<reg52.h>
#include"key.h"
//這里定義了一個(gè)10個(gè)元素的只讀數(shù)組zxCode,用于存放0~9的數(shù)碼管顯示碼。
code unsigned char zxCode[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//這里定義了一個(gè)10個(gè)元素的只讀數(shù)組_zxCode,用于存放0~9的數(shù)碼管帶點(diǎn)顯示碼。
code unsigned char _zxCode[10]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF};
//這里定義了一個(gè)長(zhǎng)度為8的數(shù)組DsBuf,用于存放需要顯示的數(shù)碼管數(shù)據(jù),數(shù)組的每一個(gè)元素代表數(shù)碼管的一個(gè)位置。
unsigned char DsBuf[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
/*控制數(shù)碼管顯示的函數(shù)。在該代碼中,使用P0口來(lái)控制8個(gè)數(shù)碼管的段選信號(hào),同時(shí)使用P2口的3個(gè)引腳(即A、B、C)來(lái)控制數(shù)碼管的位選信號(hào)。通過(guò)display函數(shù),可以將DsBuf數(shù)組中存儲(chǔ)的數(shù)值依次顯示在8個(gè)數(shù)碼管上,實(shí)現(xiàn)時(shí)分秒的動(dòng)態(tài)顯示。該函數(shù)中使用了一個(gè)靜態(tài)變量n來(lái)循環(huán)控制位選信號(hào)A、B、C的輸出,從而實(shí)現(xiàn)了數(shù)碼管顯示的循環(huán)刷新。*/
void display(){
static unsigned char n=0;
zixin=0x00;
if(n&0x01) A=1;
else A=0;
if(n&0x02) _B=1;
else _B=0;
if(n&0x04) C=1;
else C=0;
zixin=DsBuf[n];
n++;
n%=8;
}
/*filldisbuf函數(shù)的作用是將傳入的時(shí)分秒的值按照一定的格式進(jìn)行轉(zhuǎn)換,并將轉(zhuǎn)換后的結(jié)果存儲(chǔ)在DsBuf數(shù)組中,以便后續(xù)的數(shù)碼管顯示*/
void filldisbuf(unsigned int n,unsigned int m,unsigned int h){
DsBuf[0]=zxCode[n%10];
n /=10;
DsBuf[1]=zxCode[n%10];
DsBuf[2]=_zxCode[m%10];
m /=10;
DsBuf[3]=zxCode[m%10];
DsBuf[4]=_zxCode[h%10];
h /=10;
DsBuf[5]=zxCode[h%10];
}
//這里定義了一個(gè)延時(shí)函數(shù),用于延時(shí)一段時(shí)間,用于穩(wěn)定數(shù)碼管的顯示效果。
void delay(){
char i;
for(i=-100;i<100;i++);
}
//負(fù)責(zé)時(shí)間的走動(dòng)與暫停
void start(unsigned int s,unsigned int m,unsigned int h){
unsigned char i=0;
unsigned char paused = 0;//一個(gè)標(biāo)志,用來(lái)區(qū)分時(shí)間是在走動(dòng)的還是停止的
filldisbuf(s,m,h);
while(1){
if (!paused){
display();
delay();
i++;
if(i>=200){
i=0;
s = (++s) % 60;
if (s == 0) {
m = (++m) % 60;
if (m == 0) {
h = (++h) % 24;
}
}
filldisbuf(s, m, h);
}
}
else{
display();
delay();
i++;
if(i>=200){
i=0;
filldisbuf(s, m, h);}
}
//和main函數(shù)相同的功能,不同的是K4按鍵負(fù)責(zé)改變paused這個(gè)標(biāo)志的值
scankey();
if (k1_down) {
k1_down = 0;
h = (++h) % 24;
}
if (k2_down) {
k2_down = 0;
m = (++m) % 60;
}
if (k3_down) {
k3_down = 0;
s = (++s) % 60;
}
if (k4_down) {
k4_down = 0;
paused = !paused;
}
}
}
int main(){
unsigned int s=0;//表示秒
unsigned int m=0;//表示分
unsigned int h=0;//表示時(shí)
unsigned char i=0;
while(1){
scankey();//用來(lái)掃描按鍵的狀態(tài)
if(k1_down){//按下K1按鍵,數(shù)碼管負(fù)責(zé)顯示時(shí)的數(shù)值加1
k1_down=0;
h = (++h) % 24;
}
if(k2_down){//按下K2按鍵,數(shù)碼管負(fù)責(zé)顯示分的數(shù)值加1
k2_down=0;
m = (++m) % 60;
}
if(k3_down){
k3_down=0;//按下K3按鍵,數(shù)碼管負(fù)責(zé)顯示秒的數(shù)值加1
s = (++s) % 60;
}
if(k4_down){//按下K4按鍵,時(shí)間開(kāi)始走動(dòng),再按下K4按鍵,時(shí)間停止走動(dòng)
k4_down=0;
start(s,m,h);
}
delay();//主要功能時(shí)穩(wěn)定的顯示時(shí)間
display();
i++;
if(i>=200){
i=0;
filldisbuf(s, m, h);
}
}
}
key.h部分
#ifndef __KEY_H_
#define __KEY_H_
#include<reg52.h>
這里定義了4個(gè)端口位,分別命名為K1、K2、K3及K4,分別代表P3口的1、0、2、3位。
sbit K1=P3^1;
sbit K2=P3^0;
sbit K3=P3^2;
sbit K4=P3^3;
//這里定義了3個(gè)端口位,分別命名為A、_B、C,分別代表P2口的2、3、4位。
sbit A=P2^2;
sbit _B=P2^3;
sbit C=P2^4;
//這里定義了一個(gè)宏定義,P0代表的是單片機(jī)的一個(gè)8位數(shù)據(jù)總線口
#define zixin P0
extern bit k1_down,k2_down,k3_down,k4_down;
void scankey(void);
#endif
key.c部分
scankey()函數(shù)的主要代碼,通過(guò)軟件入手提高系統(tǒng)的可靠性,防止外界干擾或用戶按下按鈕時(shí)的輕微抖動(dòng)可能引起系統(tǒng)的誤判。
它的主要策略如下:1文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-745725.html
- 在固定時(shí)間間接掃描按鍵引腳狀態(tài)并記錄
- 若最近4次掃描結(jié)果出現(xiàn)1101或者0010,則認(rèn)為中間出現(xiàn)的0/1為抖動(dòng)或干擾,修正為1111和0000
- 若最近8次掃描結(jié)果為1111 0000,則可判斷按鍵有被“按下”的動(dòng)作發(fā)生;若結(jié)果為0000 1111,則可判斷按鍵有被“放開(kāi)”的動(dòng)作發(fā)生。
#include"key.h"
bit k1_down=0,k2_down=0,k3_down=0,k4_down=0;
bit k1_up=0,k2_up=0,k3_up=0,k4_up=0;
void scankey(){
static unsigned char filter1=0xFF,filter2=0xFF,filter3=0xFF,filter4=0xFF;
filter1<<=1;
filter2<<=1;
filter3<<=1;
filter4<<=1;
if(K1)filter1|=0x01;
if(K2)filter2|=0x01;
if(K3)filter3|=0x01;
if(K4)filter4|=0x01;
if((filter1&0x0F)==0x0D)filter1|=0x02;
if((filter2&0x0F)==0x0D)filter2|=0x02;
if((filter3&0x0F)==0x0D)filter3|=0x02;
if((filter4&0x0F)==0x0D)filter4|=0x02;
if((filter1&0x0F)==0x02)filter1&=0x0D;
if((filter2&0x0F)==0x02)filter2&=0x0D;
if((filter3&0x0F)==0x02)filter3&=0x0D;
if((filter4&0x0F)==0x02)filter4&=0x0D;
if(filter1==0xF0)k1_down=1;
if(filter2==0xF0)k2_down=1;
if(filter3==0xF0)k3_down=1;
if(filter4==0xF0)k4_down=1;
if(filter1==0x0F)k1_up=1;
if(filter2==0x0F)k2_up=1;
if(filter3==0x0F)k3_up=1;
if(filter4==0x0F)k4_up=1;
}
-
杜隆胤 面向系統(tǒng)集成的C51單片機(jī)教程 P54 ??文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-745725.html
到了這里,關(guān)于C51單片機(jī)的電子時(shí)鐘(數(shù)碼管顯示+獨(dú)立按鍵模塊修改及暫停時(shí)間)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!