蓝桥杯的矩阵按键的扫描,使用reg52.h头文件的时候需要自定义P4接口,因为在该头文件中并没有定义P4接口。
#include "reg52.h"
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
sfr P4 = 0xc0; // 自定义P4接口,P4^4代替P3^7,P4^2代替P3^6
sbit R1 = P3^0; // 行
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C1 = P4^4; // 列
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;
u8 temp_keys = 0; // 按键的位数
u8 code shuma[12] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xbf};
// 外设初始化函数
void init_system()
{
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 = (P2 & 0x1f);
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0x00;
P2 = (P2 & 0x1f);
P2 = (P2 & 0x1f) | 0xc0;
P0 = 0x00;
P2 = (P2 & 0x1f);
}
// 外设选通函数
void select(u8 local)
{
switch(local)
{
case(4): P2 = (P2 & 0x1f) | 0x80; break;
case(5): P2 = (P2 & 0x1f) | 0xa0; break;
case(6): P2 = (P2 & 0x1f) | 0xc0; break;
case(7): P2 = (P2 & 0x1f) | 0xe0; break;
}
}
// 简单延时函数
void delay()
{
u8 t = 200;
while(t--);
}
// 数码管点亮函数,单个数码管
void display(u8 local, u8 num)
{
select(6);
P0 = 0x80 >> (local - 1);
P2 = P2 & 0x1f;
select(7);
P0 = num;
P2 = P2 & 0x1f;
delay();
}
// 数码管消隐函数
void close_display()
{
// 消隐
select(6);
P0 = 0x00;
P2 = P2 & 0x1f;
}
// 按键扫描函数
void scan_keys()
{
R1 = 0;
R2 = R3 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0)
{
delay();
if(C1 == 0)
{
temp_keys = 7;
}
while(!C1);
}
else if(C2 == 0)
{
delay();
if(C2 == 0)
{
temp_keys = 11;
}
while(!C2);
}
else if(C3 == 0)
{
delay();
if(C3 == 0)
{
temp_keys = 15;
}
while(!C3);
}
else if(C4 == 0)
{
delay();
if(C4 == 0)
{
temp_keys = 19;
}
while(!C4);
}
R2 = 0;
R1 = R3 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0)
{
delay();
if(C1 == 0)
{
temp_keys = 6;
}
while(!C1);
}
else if(C2 == 0)
{
delay();
if(C2 == 0)
{
temp_keys = 10;
}
while(!C2);
}
else if(C3 == 0)
{
delay();
if(C3 == 0)
{
temp_keys = 14;
}
while(!C3);
}
else if(C4 == 0)
{
delay();
if(C4 == 0)
{
temp_keys = 18;
}
while(!C4);
}
R3 = 0;
R2 = R1 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0)
{
delay();
if(C1 == 0)
{
temp_keys = 5;
}
while(!C1);
}
else if(C2 == 0)
{
delay();
if(C2 == 0)
{
temp_keys = 9;
}
while(!C2);
}
else if(C3 == 0)
{
delay();
if(C3 == 0)
{
temp_keys = 13;
}
while(!C3);
}
else if(C4 == 0)
{
delay();
if(C4 == 0)
{
temp_keys = 17;
}
while(!C4);
}
R4 = 0;
R2 = R3 = R1 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0)
{
delay();
if(C1 == 0)
{
temp_keys = 4;
}
while(!C1);
}
else if(C2 == 0)
{
delay();
if(C2 == 0)
{
temp_keys = 8;
}
while(!C2);
}
else if(C3 == 0)
{
delay();
if(C3 == 0)
{
temp_keys = 12;
}
while(!C3);
}
else if(C4 == 0)
{
delay();
if(C4 == 0)
{
temp_keys = 16;
}
while(!C4);
}
if(temp_keys == 4)
{
TR1 = ~TR1;
t1_sec = t1_sec;
t1_min = t1_min;
t1_hour = t1_hour;
}
else if(temp_keys == 5)
{
t1_sec = 0;
t1_min = 0;
t1_hour = 0;
}
else if(temp_keys == 6)
{
select(4);
P0 = 0xfe;
P2 = P2 & 0x1f;
}
else if(temp_keys == 7)
{
select(4);
P0 = 0xff;
P2 = P2 & 0x1f;
}
}
void main()
{
init_system();
while(1)
{
scan_keys();
display(1, shuma[temp_keys%10]);
display(2, shuma[ temp_keys/10]);
close_display();
}
}
初始化外设一般都是蓝桥杯一上电就需要完成的事情,关闭蜂鸣器以及继电器还有关闭LED灯和数码管这些外设,不然会使得上电之后无关的外设同时工作影响正常的显示效果。