第11集 矩阵按键 课后小练
简易洗衣机面板
1.按下开机键后,数码管显示1,表示默认为清洗模式1;
2.用矩阵按键模拟洗衣机的操作面板,前五个按键模拟1-5的清洗模式按键,选择几的时候数码管显示数字几,表示以当前为第几个功能;
3.按下启动后,按照选择的模式对应的时间开始倒计时,倒计时结束后,数码管熄灭,表示清洗完成(清洗时间自己随意设置)。
因为手头没有合适的矩阵键盘所以今天现焊了一块4 x 4的矩阵键盘。
1-5键设置了模式参数,16键设置为启动键。6-15键没设置,为空键。
矩阵键盘接口为P2口。数码管显示采用HC595驱动的8位数码管,但只驱动了末后两位。程序在冲哥的第11集DEMO程序的基础上稍作了一些增减。
下面为矩阵键盘扫描程序
- void KEY_Task(void) //4*4矩阵键盘扫描
- { //#define key P2 //矩阵键盘的数据口为P2
- u8 key_temp;
- u8 key1,key2;
- key=0xf0;
- key1=key;
- if(key1 != 0xf0 )
- {
- key1=key&0xf0; //确定哪一行的按键按下
- key=0x0f;
- key2=key;
- if(key2 != 0x0f )
- key2=key&0x0f; //确定哪一列的按键按下
- key_temp=key1|key2; //确定按键位置
- }
- // else
- // key_temp = no_key ;
- switch(key_temp) //当确定按键按下后,列举所有的按键情况
- {
- case 0xee: key_value=0;break;
- case 0xde: key_value=1;break;
- case 0xbe: key_value=2;break;
- case 0x7e: key_value=3;break;
- case 0xed: key_value=4;break;
- case 0xdd: key_value=5;break;
- case 0xbd: key_value=6;break;
- case 0x7d: key_value=7;break;
- case 0xeb: key_value=8;break;
- case 0xdb: key_value=9;break;
- case 0xbb: key_value=10;break;
- case 0x7b: key_value=11;break;
- case 0xe7: key_value=12;break;
- case 0xd7: key_value=13;break;
- case 0xb7: key_value=14;break;
- case 0x77: key_value=15;break;
- // case 0xff: key_value=16;break;
- }
- switch(key_value)
- {
- case 0: fen = 10;break; //赋予1-5各按键所表示模式运行时间
- case 1: fen = 11;break;
- case 2: fen = 12;break;
- case 3: fen = 13;break;
- case 4: fen = 14;break;
- case 15: start = 1;break; //第16键设置为启动工作键
- }
- }
复制代码
数码管显示程序:
- 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*/
- };
复制代码
- void Seg_Task(void)
- {
- if(key_value != 15) //按任意一个模式选择键,回到等待启动状态
- start = 0;
- if(start) //启动工作后数码管显示倒计时时间,否则显示模式编号
- num = fen;
- else
- num = key_value+1; //+1 为默认模式号为1
-
-
- if( Seg_no ==0 )
- {
- if(num%10==0&&num/10==0) //如果十位和个位都为0,则消隐
- Display_Seg( SEG_NUM[17] , ~T_NUM[7]);
- else
- Display_Seg( SEG_NUM[num%10] , ~T_NUM[7]); //显示个位数字
- }
- else if( Seg_no ==1 )
- {
- if(num/10==0) //如果十位为0,则消隐
- Display_Seg( SEG_NUM[17] , ~T_NUM[6]);
- else
- Display_Seg( SEG_NUM[num/10] , ~T_NUM[6]);
- }
- else
- { }
- Seg_no ++;
- if( Seg_no>1 )
- Seg_no=0;
- }
复制代码
ISP软件端虚拟数码管显示程序:
- void SEG_PC( void ) //只显示末两位
- {
- u8 cod[8];
-
- cod[0] = SEG_NUM[17];
- cod[1] = SEG_NUM[17];
- cod[2] =SEG_NUM[17];
-
- cod[3] = SEG_NUM[17];
- cod[4] = SEG_NUM[17];
- cod[5] = SEG_NUM[17];
- if(num/10==0) //如果十位为0,则消隐
- cod[6] = SEG_NUM[17];
- else
- cod[6] = SEG_NUM[num/10];
- if(num/10==0 && num%10==0) //如果十位和个位都为0,则消隐
- cod[7] = SEG_NUM[17];
- else
- cod[7] = SEG_NUM[num%10];
-
- SEG7_ShowCode(cod);
- }
复制代码
放上完整演示视频
|