附注:
原理圖各接口連接配接關系可參考代碼中的端口定義;
P0口資料鎖存器為兩片74HC573晶片;
1.對獨立鍵盤的檢測
/*--------------------------
功能:用數位管實作60s計時器
上電時,數位管顯示00
key4控制開始/暫停計時
暫停狀态下,key1進行加1操作
key2進行減1操作
key3進行清零操作
---------------------------
Author: Zhang Kaizhou
Date: 2019-5-19 19:14:20
--------------------------*/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key1 = P3^4;
sbit key2 = P3^5;
sbit key3 = P3^6;
sbit key4 = P3^7;
sbit wei_address = P2^7;
sbit duan_address = P2^6;
uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f,
0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c,
0x39, 0x5e, 0x79, 0x71}; // 定義一個無符号字元型數組table[],存放在單片機内部的ROM或Flash中
uchar n1 = 0, n2 = 0;
void init();
void display(uchar num);
void keyScan();
void delay(uchar xms);
void main()
{
init();
while(1)
{
keyScan();
display(n1);
}
}
/*初始化函數*/
void init()
{
TMOD = 0x01; // 定時器0,方式1
TH0 = (65536 - 45872) / 256; // 定時50ms
TL0 = (65536 - 45872) % 256;
EA = 1; // 開全局中斷
ET0 = 1; // 開定時器0溢出中斷
}
/*定時器0中斷服務程式*/
void T0_interrupt() interrupt 1
{
TH0 = (65536 - 45872) / 256; // 定時器0重裝初值
TL0 = (65536 - 45872) % 256;
n2++;
if(n2 == 20) // 定時到1s
{
n2 = 0;
n1++;
if(n1 == 60)
{
n1 = 0;
}
}
}
/*數位管顯示函數*/
void display(uchar num)
{
uchar shi, ge;
shi = num / 10;
ge = num % 10;
duan_address = 1; // 在數位管上顯示十位的數字
P0 = table[shi];
duan_address = 0;
P0 = 0xff;
wei_address = 1;
P0 = 0xfe;
wei_address = 0;
delay(5);
duan_address = 1; // 在數位管上顯示個位的數字
P0 = table[ge];
duan_address = 0;
P0 = 0xff;
wei_address = 1;
P0 = 0xfd;
wei_address = 0;
delay(5);
}
/*鍵盤掃描函數*/
void keyScan()
{
if(!key1) // key1按下,加1
{
delay(10);
if(!key1)
{
n1++;
if(n1 == 60)
{
n1 = 0;
}
while(!key1);
}
}
if(!key2) // key2按下,減1
{
delay(10);
if(!key2)
{
if(!n1)
{
n1 = 60;
}
n1--;
while(!key2);
}
}
if(!key3) // key4按下,暫停或開始定時器0
{
delay(10);
if(!key3)
{
n1 = 0;
while(!key3);
}
}
if(!key4)
{
delay(10);
if(!key4)
{
while(!key4);
TR0 = ~TR0;
}
}
}
/*延時函數*/
void delay(uchar xms)
{
uchar i, j;
for(i = 0; i < xms; i++)
for(j = 0; j < 110; j++);
}
2.對矩陣鍵盤進行掃描
/*------------------------
功能:掃描4x4矩陣鍵盤
Author: Zhang Kaizhou
Date: 2019-5-21 21:37:31
-------------------------*/
#include <reg52.h>
#define uchar unsigned char
sbit wei_address = P2^7;
sbit duan_address = P2^6;
uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f,
0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c,
0x39, 0x5e, 0x79, 0x71}; // 定義一個無符号字元型數組table[],存放在單片機内部的ROM或Flash中
uchar buffer, key;
void init_digitron();
void array_scan_oneline(uchar address);
void array_scan();
void display(uchar key);
void delay(uchar xms);
void main()
{
init_digitron(); // 初始化數位管
while(1) // 循環逐行掃描按鍵是否按下
{
array_scan();
}
}
/*數位管初始化函數*/
void init_digitron()
{
P0 = 0; // 關閉所有數位管
duan_address = 1;
duan_address = 0;
P0 = 0x00; // 選中所有數位管
wei_address = 1;
wei_address = 0;
}
/*矩陣鍵盤掃描函數*/
void array_scan()
{
array_scan_oneline(0xfe);
array_scan_oneline(0xfd);
array_scan_oneline(0xfb);
array_scan_oneline(0xf7);
}
/*矩陣鍵盤掃描一行的函數*/
void array_scan_oneline(uchar address)
{
P3 = address;
buffer = P3;
buffer = buffer & 0xf0;
if(buffer != 0xf0) // 有鍵按下
{
delay(10); // 消抖
buffer = P3;
buffer = buffer & 0xf0;
if(buffer != 0xf0)
{
buffer = P3;
switch(buffer)
{
case 0xee: key = 0; break;
case 0xde: key = 1; break;
case 0xbe: key = 2; break;
case 0x7e: key = 3; break;
case 0xed: key = 4; break;
case 0xdd: key = 5; break;
case 0xbd: key = 6; break;
case 0x7d: key = 7; break;
case 0xeb: key = 8; break;
case 0xdb: key = 9; break;
case 0xbb: key = 10; break;
case 0x7b: key = 11; break;
case 0xe7: key = 12; break;
case 0xd7: key = 13; break;
case 0xb7: key = 14; break;
case 0x77: key = 15; break;
}
while(buffer != 0xf0) // 等待按鍵釋放
{
buffer = P3;
buffer = buffer & 0xf0;
}
display(key);
}
}
}
/*延時函數*/
void delay(uchar xms)
{
uchar i, j;
for(i = 0; i < xms; i++)
for(j = 0; j < 110; j++);
}
/*數位管顯示函數*/
void display(uchar key)
{
P0 = table[key];
duan_address = 1;
duan_address = 0;
}