蓝桥杯 小蜜蜂 单元训练07:矩阵键盘的基本操作
sbit写法中加入了定时器使用。
#include "stc15f2k60s2.h"
typedef unsigned char uint8_t;
uint8_t timerCounter = 0;
uint8_t timerEnable = 0;
#define LED(X) \
{ \
P0 = X; \
P2 = (P2 & 0x1f | 0x80); \
P2 &= 0x1f; \
}
// 数码管
// 段选
#define COM(x) \
{ \
P0 = x; \
P2 = P2 & 0x1F | 0xc0; \
P2 &= 0x1F; \
}
// 位选
#define SEG(x) \
{ \
P0 = x; \
P2 = P2 & 0x1F | 0xE0; \
P2 &= 0x1F; \
}
code unsigned char Seg_Table[] =
{
0xc0, // 0
0xf9, // 1
0xa4, // 2
0xb0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xf8, // 7
0x80, // 8
0x90, // 9
0x88, // A
0x83, // b
0xc6, // C
0xa1, // d
0x86, // E
0x8e // F
}; // 表不用记,官方提供资源包里面有。
// 数码管第一位显示
void DisplayNo1(uint8_t no)
{
COM(0x01);
SEG(Seg_Table[no]);
}
// 矩阵键盘 行
sbit row1 = P3 ^ 0;
sbit row2 = P3 ^ 1;
sbit row3 = P3 ^ 2;
sbit row4 = P3 ^ 3;
// 矩阵键盘 列
sbit col1 = P4 ^ 4;
sbit col2 = P4 ^ 2;
sbit col3 = P3 ^ 5;
sbit col4 = P3 ^ 4;
void ClearRow()
{
row1 = 0;
row2 = 0;
row3 = 0;
row4 = 0;
col1 = 1;
col2 = 1;
col3 = 1;
col4 = 1;
}
void ClearCol()
{
col1 = 0;
col2 = 0;
col3 = 0;
col4 = 0;
row1 = 1;
row2 = 1;
row3 = 1;
row4 = 1;
}
code uint8_t ArrayNum[4][4] = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
{12, 13, 14, 15}};
uint8_t keyStatus;
uint8_t key_row;
uint8_t key_col;
uint8_t keyValue = 255;
void KeyScan()
{
switch (keyStatus)
{
case 0:
ClearCol();
if ((row1 == 0) || (row2 == 0) || (row3 == 0) || (row4 == 0))
{
keyStatus = 1;
}
break;
case 1:
ClearCol();
if (row1 == 0)
{
key_row = 1;
keyStatus = 2;
}
else if (row2 == 0)
{
key_row = 2;
keyStatus = 2;
}
else if (row3 == 0)
{
key_row = 3;
keyStatus = 2;
}
else if (row4 == 0)
{
key_row = 4;
keyStatus = 2;
}
break;
case 2:
ClearRow();
if (col1 == 0)
{
key_col = 1;
keyStatus = 3;
}
else if (col2 == 0)
{
key_col = 2;
keyStatus = 3;
}
else if (col3 == 0)
{
key_col = 3;
keyStatus = 3;
}
else if (col4 == 0)
{
key_col = 4;
keyStatus = 3;
}
break;
case 3:
ClearRow();
if ((col1 == 1) && (col2 == 1) && (col3 == 1) && (col4 == 1))
keyStatus = 0;
break;
default:
keyStatus = 0;
break;
}
}
void SegShow()
{
if (timerEnable)
KeyScan();
timerEnable = 0;
DisplayNo1(ArrayNum[key_row - 1][key_col - 1]);
}
void Timer0_Init(void) // 1毫秒@12.000MHz
{
AUXR |= 0x80; // 定时器时钟1T模式
TMOD &= 0xF0; // 设置定时器模式
TL0 = 0x20; // 设置定时初始值
TH0 = 0xD1; // 设置定时初始值
TF0 = 0; // 清除TF0标志
TR0 = 1; // 定时器0开始计时
ET0 = 1; // 使能定时器0中断
EA = 1;
}
void main()
{
Timer0_Init();
LED(0xff);
SEG(0xff);
COM(0xff);
while (1)
{
SegShow();
}
}
void Timer0_Isr(void) interrupt 1
{
if (timerCounter++ == 1) // 1ms
{
timerCounter = 0;
timerEnable = 1;
}
}