第十一集 矩阵按键 学习笔记
用行和列组合,以减少IO口的使用数量
任务1:数码管显示当前的按键号
把多任务定时器那个目录整个拷过来
在main.c中,加入
Init_595(); //在EA = 1;之前
在task.c中建立2个任务
{0, 10, 10, Task_1},
{0, 100, 100, Seg_Task},
在io.c中加入
u8 SEG_NUM[]=
{
0x3F, /*'0', 0*/
0x06, /*'1', 1*/
0x5B, /*'2', 2*/
0x4F, /*'3', 3*/
0x66, /*'4', 4*/
0x6D, /*'5', 5*/
0x7D, /*'6', 6*/
0x07, /*'7', 7*/
0x7F, /*'8', 8*/
0x6F, /*'9', 9*/
0x77, /*'A', 10*/
0x7C, /*'B', 11*/
0x39, /*'C', 12*/
0x5E, /*'D', 13*/
0x79, /*'E', 14*/
0x71, /*'F', 15*/
0x40, /*'-', 16*/
0x00, /*' ', 17*/
0x80, /*'.', 18*/
};
u8 T_NUM[8] =
{
0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80
};
void Init_595(void)
{
HC595_SER = 0;
HC595_RCK = 0;
HC595_SCK = 0;
}
/************向HC595发送一个字节函数************/
void Send_595(u8 dat)
{
u8 i;
for (i=0;i<8;i++)
{
dat<<=1;
HC595_SER = CY; //先把数据写到引脚上
HC595_SCK = 1; //输出上升沿的时钟信号
HC595_SCK = 0;
}
}
void Display_Seg(u8 HC595_1, u8 HC595_2)
{
Send_595(HC595_1); //数码管段码输出,高电平点亮
Send_595(HC595_2); //数码管位码输出,低电平点亮
HC595_RCK = 1; //数据输出
HC595_RCK = 0;
}
u8 Seg_no = 0;
void Seg_Task(void)
{
if(key_num == 0xff)
Display_Seg( SEG_NUM[17], ~T_NUM[0]);
else
Display_Seg( SEG_NUM[key_num], ~T_NUM[0]);
}
u8 key_num = 0xff;
//任务1:数码管显示当前的按键号
void Task_1(void)
{
COL1 = 0;
COL2 = 0;
COL3 = 0;
COL4 = 0;
ROW1 = 1;
ROW2 = 1;
if((ROW1 == 0)||(ROW2 == 0))
{
if(( ROW1 == 0 ) && ( ROW2 == 0 ))
{
;
}
else if((( ROW1 == 0 ) && ( ROW2 == 1 )) || (( ROW1 == 1 ) && ( ROW2 == 0 )))
{
if( ROW1 == 0) //判断行起始序号
key_num = 0;
else if( ROW2 ==0)
key_num = 4;
COL1 = 1;
COL2 = 1;
COL3 = 1;
COL4 = 1;
ROW1 = 0;
ROW2 = 0;
if(COL1 == 0) //判断列起始序号
{
key_num += 0;
}
else if(COL2 == 0)
{
key_num += 1;
}
else if(COL3 == 0)
{
key_num += 2;
}
else if(COL4 == 0)
{
key_num += 3;
}
}
COL1 = 0;
COL2 = 0;
COL3 = 0;
COL4 = 0;
ROW1 = 1;
ROW2 = 1;
}
else
{
key_num = 0xff;
}
}
在io.h中加入
#define HC595_SER P34
#define HC595_RCK P35
#define HC595_SCK P32
#define ROW1 P06
#define ROW2 P07
#define COL1 P00
#define COL2 P01
#define COL3 P02
#define COL4 P03
//extern u8 key_num;
void Task_1(void);
void Init_595(void);
void Seg_Task(void);
编译下载,运行OK。
任务2:密码锁
1、没有输入时,显示“--------”
2、有输入时,按下一个按键,开始顺序写入
3、当按下的密码为“12345670”,数码管显示“ 1”
否则,还是显示“--------”
在main.c中,加入
Init_595(); //在 EA = 1;之前
在Task.c中,加入
{0, 10, 10, Task_1},
{0, 1, 1, Seg_Task},
{0, 10, 10, PW_write_Task},
在io.c中,加入
u8 SEG_NUM[]=
{
0x3F, /*'0', 0*/
0x06, /*'1', 1*/
0x5B, /*'2', 2*/
0x4F, /*'3', 3*/
0x66, /*'4', 4*/
0x6D, /*'5', 5*/
0x7D, /*'6', 6*/
0x07, /*'7', 7*/
0x7F, /*'8', 8*/
0x6F, /*'9', 9*/
0x77, /*'A', 10*/
0x7C, /*'B', 11*/
0x39, /*'C', 12*/
0x5E, /*'D', 13*/
0x79, /*'E', 14*/
0x71, /*'F', 15*/
0x40, /*'-', 16*/
0x00, /*' ', 17*/
0x80, /*'.', 18*/
};
u8 T_NUM[8] =
{
0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80
};
#define HC595_SER P34
#define HC595_RCK P35
#define HC595_SCK P32
void Init_595(void)
{
HC595_SER = 0;
HC595_RCK = 0;
HC595_SCK = 0;
}
/************向HC595发送一个字节函数************/
void Send_595(u8 dat)
{
u8 i;
for (i=0;i<8;i++)
{
dat<<=1;
HC595_SER = CY; //先把数据写到引脚上
HC595_SCK = 1; //输出上升沿的时钟信号
HC595_SCK = 0;
}
}
void Display_Seg(u8 HC595_1, u8 HC595_2)
{
Send_595(HC595_1); //数码管段码输出,高电平点亮
Send_595(HC595_2); //数码管位码输出,低电平点亮
HC595_RCK = 1; //数据输出
HC595_RCK = 0;
}
u8 Seg_no = 0;
u8 password[8] = {16,16,16,16,16,16,16,16};
void Seg_Task(void)
{
u8 num = 0;
if(Seg_no==0)
{
Display_Seg( SEG_NUM[password[0]], ~T_NUM[Seg_no]);
}
else if(Seg_no==1)
{
Display_Seg( SEG_NUM[password[1]], ~T_NUM[Seg_no]);
}
else if(Seg_no==2)
{
Display_Seg( SEG_NUM[password[2]], ~T_NUM[Seg_no]);
}
else if(Seg_no==3)
{
Display_Seg( SEG_NUM[password[3]], ~T_NUM[Seg_no]);
}
else if(Seg_no==4)
{
Display_Seg( SEG_NUM[password[4]], ~T_NUM[Seg_no]);
}
else if(Seg_no==5)
{
Display_Seg( SEG_NUM[password[5]], ~T_NUM[Seg_no]);
}
else if(Seg_no==6)
{
Display_Seg( SEG_NUM[password[6]], ~T_NUM[Seg_no]);
}
else if(Seg_no==7)
{
Display_Seg( SEG_NUM[password[7]], ~T_NUM[Seg_no]);
}
Seg_no++;
if(Seg_no>7)
Seg_no = 0;
}
u8 Key_Vol3 = 0;
u8 key_no = 0;
void PW_write_Task(void)
{
if (key_num != 0xff)
{
Key_Vol3++;
if (Key_Vol3==5)
{
//按键按下的任务
if( key_no == 0 )
{
password[0] = 16;
password[1] = 16;
password[2] = 16;
password[3] = 16;
password[4] = 16;
password[5] = 16;
password[6] = 16;
password[7] = 16;
}
password[key_no] = key_num;
key_no++;
//password[7] = 17;
if(key_no == 8) //密码输入完毕
{
if ((password[0] == 1) &&
(password[1] == 2) &&
(password[2] == 3) &&
(password[3] == 4) &&
(password[4] == 5) &&
(password[5] == 6) &&
(password[6] == 7) &&
(password[7] == 0))
{
password[0] = 17;
password[1] = 17;
password[2] = 17;
password[3] = 17;
password[4] = 17;
password[5] = 17;
password[6] = 17;
password[7] = 1;
}
else
{
password[0] = 16;
password[1] = 16;
password[2] = 16;
password[3] = 16;
password[4] = 16;
password[5] = 16;
password[6] = 16;
password[7] = 16;
}
key_no = 0;
}
}
}
else
{
Key_Vol3 = 0;
}
}
u8 key_num = 0xff;
//任务1:数码管显示当前的按键号
void Task_1(void)
{
COL1 = 0;
COL2 = 0;
COL3 = 0;
COL4 = 0;
ROW1 = 1;
ROW2 = 1;
if((ROW1 == 0)||(ROW2 == 0))
{
if(( ROW1 == 0 ) && ( ROW2 == 0 ))
{
;
}
else if((( ROW1 == 0 ) && ( ROW2 == 1 )) || (( ROW1 == 1 ) && ( ROW2 == 0 )))
{
if( ROW1 == 0) //判断行起始序号
key_num = 0;
else if( ROW2 ==0)
key_num = 4;
COL1 = 1;
COL2 = 1;
COL3 = 1;
COL4 = 1;
ROW1 = 0;
ROW2 = 0;
if(COL1 == 0) //判断列起始序号
{
key_num += 0;
}
else if(COL2 == 0)
{
key_num += 1;
}
else if(COL3 == 0)
{
key_num += 2;
}
else if(COL4 == 0)
{
key_num += 3;
}
}
COL1 = 0;
COL2 = 0;
COL3 = 0;
COL4 = 0;
ROW1 = 1;
ROW2 = 1;
}
else
{
key_num = 0xff;
}
}
在io.h中加入
#define HC595_SER P34
#define HC595_RCK P35
#define HC595_SCK P32
#define ROW1 P06
#define ROW2 P07
#define COL1 P00
#define COL2 P01
#define COL3 P02
#define COL4 P03
extern u8 key_num;
void Key_Task(void);
void Task_1(void);
void Init_595(void);
void Seg_Task(void);
void PW_write_Task(void);
编译成功,运行OK
课后练习题目
简易洗衣机面板 1、 按下开机键后,数码管显示1,表示默认为清洗模式1 2、 用矩阵按键模拟洗衣机的操作面板,前五个按钮模拟1-5的清洗模式按键选择几就显示数字几,表示当前为第几个功能 3、 按下启动后,按照选择的模式对应的时间开始倒计时,倒计时结束后,数码管熄灭,表示清洗完成,清洗时间任意设定。
|