任务4-5 密码锁设计 (课件)-《单片机技术与应用》同步教学(电子工业版)

2024-07-11
| 42页
| 24人阅读
| 2人下载
普通

内容正文:

任务4-5 密码锁设计 1 一、任务导入 任务要求 设计具有16个按键和1个数码管显示的密码锁,具体要求: 输入一位密码(为0~9,A~F之间的数字),密码输入正确显示“P”并将锁打开;否则显示“E”,继续保持锁定状态。 硬件电路 共阳数码管显示抢答器的状态信息; 16个按键连接成4×4矩阵键盘方式; 连接P3.0的发光二极管的亮灭表示开锁或关锁状态。 二、矩阵键盘 4×4矩阵键盘 四行 四列 0 1 2 3 0 1 2 3 行线 列线 6 4×4矩阵键盘 0 1 2 3 0 1 2 3 行线 列线 单片机 +VCC 4x4矩阵键盘将16根独立连接的控制线减少到只需要8根控制线,即4根行线、4根列线 7 如何识别矩阵式键盘中的按键? 8 识别按键一般应包括以下内容: (1)判别有无键按下。 (2)键盘扫描取得闭合键的行、列号。 (3)用计算法或查表法得到键值。 (4)判断闭合键是否释放,如没释放则继续等待。 (5)将闭合键的键值保存,同时转去执行该闭合键的功能。 逐列扫描法 行列反转法 9 0 1 2 3 0 1 2 3 行线 列线 +VCC 1K×4 逐列扫描法 输出-列线 输入-行线 P0.0 P0.1 P0.2 P0.3 P2.0 P2.1 P2.2 P2.3 是否有键按下; 判断具体按键; 10 第一步,先来判断是否有键按下,向P2.0到P2.3的四条列线全部输出低电平,读入P0.0-P0.3四条行线的信号 0 1 2 3 0 1 2 3 行线 列线 +VCC 是否有键按下; 判断具体按键; 逐列扫描法: 1K×4 输出 输入 0 0 0 0 0 0 0 0 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 信号读入 P2.0 P2.1 P2.2 P2.3 P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P2.1 P0.2 P0.0 P0.3 P2.3 P2.1 P0.2 P0.0 P0.3 P2.0 P2.3 P2.1 P0.2 P0.0 P0.3 11 当所有的按键都没有被按下时,p0.0到P0.3读入的行电平都为高。 0 1 2 3 0 1 2 3 行线 列线 +VCC 1K×4 输出 输入 0 0 0 0 无键按下 1 1 1 1 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 是否有键按下; 判断具体按键; 逐列扫描法: P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P2.0 P2.1 P2.2 P2.3 P2.1 P2.3 P2.1 P2.0 P2.3 P2.1 12 有键按下,例如这个9#键按下,这个键所在的2#行线与1#列线导通,读入的P0.2行电平为低。 0 1 2 3 0 1 2 3 行线 列线 +VCC 是否有键按下; 判断具体按键; 逐列扫描法: 1K×4 输出 输入 0 0 0 0 1 1 1 1 0 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 P2.0 P2.1 P2.2 P2.3 P2.1 P2.3 P2.1 P2.0 P2.3 P2.1 P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 13 0 1 2 3 0 1 2 3 行线 列线 +VCC 是否有键按下; 判断具体按键; 逐列扫描法: 1K×4 输出 输入 0 0 0 0 1 1 1 1 0 行电平不全为高→有键按下 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P2.0 P2.1 P2.2 P2.3 P2.1 P2.3 P2.1 P2.0 P2.3 P2.1 14 第二步,判断到底是哪一个键按下。 0 1 2 3 0 1 2 3 行线 列线 +VCC 是否有键按下; 判断具体按键; 逐列扫描法: 1K×4 输出 输入 0 0 0 0 1 1 0 1 行电平不全为高→有键按下 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P2.0 P2.1 P2.2 P2.3 P2.1 P2.3 P2.1 P2.0 P2.3 P2.1 15 逐列扫描:具体方法是,先给第0列输出低电平“0”,其他三列都为高电平“1”。读入行电平,判断第一列四个按键的状态。 0 1 2 3 0 1 2 3 行线 列线 +VCC 是否有键按下; 判断具体按键; 逐列扫描法: 1K×4 输出 输入 1 1 1 0 1 1 0 1 行电平不全为高→有键按下 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P2.0 P2.1 P2.2 P2.3 P2.1 P2.3 P2.1 P2.0 P2.3 P2.1 16 送第1列为低电平“0”,其他三列为高电平,进行第一列4个按键是否按下的判断。 0 1 2 3 0 1 2 3 行线 列线 +VCC 是否有键按下; 判断具体按键; 逐列扫描法: 1K×4 输出 输入 1 1 0 1 行电平不全为高→有键按下 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P2.0 P2.1 P2.2 P2.3 P2.1 P2.3 P2.1 P2.0 P2.3 P2.1 17 送第2列为低电平“0”, 其他三列为高电平,进行第2列4个按键是否按下的判断。 0 1 2 3 0 1 2 3 行线 列线 +VCC 是否有键按下; 判断具体按键; 逐列扫描法: 1K×4 输出 输入 1 0 1 1 行电平不全为高→有键按下 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P2.0 P2.1 P2.2 P2.3 P2.1 P2.3 P2.1 P2.0 P2.3 P2.1 18 0 1 2 3 0 1 2 3 行线 列线 +VCC 是否有键按下; 判断具体按键; 逐列扫描法: 1K×4 输出 输入 0 1 1 1 行电平不全为高→有键按下 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P2.0 P2.1 P2.2 P2.3 P2.1 P2.3 P2.1 P2.0 P2.3 P2.1 19 0 1 2 3 0 1 2 3 行线 列线 +VCC 是否有键按下; 判断具体按键; 逐列扫描法: 1K×4 输出 输入 行电平不全为高→有键按下 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 逐列送低电平→判断每列按键状态 P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P2.0 P2.1 P2.2 P2.3 P2.1 P2.3 P2.1 P2.0 P2.3 P2.1 20 0 1 2 3 0 1 2 3 行线 列线 +VCC 是否有键按下; 判断具体按键; 逐列扫描法: 1K×4 输出 输入 行电平不全为高→有键按下 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 逐列送低电平→判断每列按键状态 键值= 列号+行号*4 P0.0 P0.1 P0.2 P0.3 P0.3 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P0.2 P0.0 P0.3 P2.0 P2.1 P2.2 P2.3 P2.1 P2.3 P2.1 P2.0 P2.3 P2.1 21 三、程序设计 char scan_key ( ) { char i, temp,m,n; bit find=0; //有键按下标志位 P2=0xf0; //向所有的列线上输出低电平 i=P0; //读入行值 i&=0x0f; //屏蔽掉高四位 if(i!=0x0f) //行值不为全1,有键按下 { delay(1200); //延时消抖 i=P0; //再次读入行值 i&=0x0f; //屏蔽掉高四位 if(i!=0x0f) //第二次判断有键按下 { for(i=0;i<4;i++) { P2=0xfe<<i; //逐列送出低电平 temp=~P0; //读行值,并取反,全1→全0 temp=temp&0x0f; //屏蔽掉行值高4位 if(temp!=0x00) //判断有无键按下,为0则无键按下,否则有键按下 { m=i; //保存列号至m变量 find=1; //置找到按键标志 switch(temp) //判断哪一行有键按下,记录行号到n变量 { case 0x01:n=0;break; //第0行有键按下 case 0x02: n=1;break; //第1行有键按下 case 0x04: n=2;break; //第2行有键按下 case 0x08: n=3;break; //第3行有键按下 default:break; } break; } //有键按下,退出for循环 } } } if(find==0) return -1; //无键按下则返回-1 else return(n*4+m); //否则返回键值,键值=列号*4+行号 } #include <reg51.h> //包含头文件reg51.h,定义51单片机的专用寄存器 sbit P30=P3^0; //位定义,控制发光二极管,其亮灭表示锁的打开和锁定状态 void main() //主函数 { unsigned char led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e}; //0~9、A~F的共阳极显示码 unsigned char led1[]={0xbf,0x8c,0x86}; //“”、“P”和“E”的共阳极显示码 unsigned char i; P1=led1[0]; //数码管显示“” P30=1; //开锁指示灯关闭 P0=0xff; //P0口低四位做输入口,先输出全1 while(1) { i=scan_key(); //调用键盘函数 if(i==-1)continue; //没有键按下,继续循环 else if(i!=8){ //按键不是密码8 P1=led[i]; //显示按下键的数字号 delay(10000); //延时 P1=led1[2]; //显示E delay(50000); //延时 P1=led1[0]; //显示“” } else { //按键是密码8 P1=led[i]; //显示按下键的数字号 delay(10000); //延时 P1=led1[1]; //显示P P30=0; //开锁 delay(50000); //延时 P1=led1[0]; //数码管显示“” P30=1; //开锁指示灯关闭 } } } 四、举一反三 系统上电,液晶显示“password:”,此时可以输入6位数字密码,然后以10号键作为输入结束键,如果输入密码位数错误,或位数正确但密码错误,在液晶第二行显示“error”,并自动重新进入密码输入状态;当输入密码正确,在液晶第二行显示“pass”,密码锁解锁。 在密码锁已经解锁的状态下,如果按下11号键(密码设置按键),则进入密码重置状态,按其它任意键则返回密码输入状态。 进入密码重置状态时,液晶第一行显示“password setup:”,等待输入6位0-9 的新数字密码,6位数字密码输入完毕,则自动进入密码输入状态。 假设初始密码为000000。 设计一个具有16个按键输入,1602液晶显示的实用6位密码锁。 具体要求: 举一反三 26 硬件设计 P17 P16 P15 P14 P13 P12 P11 P10 P32 P31 P30 P10 P11 P12 P13 P14 P15 P16 P17 P30 P31 P32 P20 P21 P22 P23 P24 P25 P26 P27 P24 P25 P26 P27 P20 P21 P22 P23 P33 P33 行列反转法识别按键 Keil C51多文件项目工程管理 行列反转法 多文件项目工程 软件设计思路 使用一个I/O口的低4位、高4位分别连接矩阵键盘的行线和列线,可考虑用行列反转方法来识别按键。 行列反转法按键识别码 0 1 2 3 0 1 2 3 行线 列线 +VCC 行列反转法 输出两次 行列相反 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 30 0 1 2 3 0 1 2 3 行线 列线 +VCC S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 P2=0x0f; 输出 行列反转法 输出:列全0行全1 31 0 1 2 3 0 1 2 3 行线 列线 +VCC S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 0 0 0 0 1 1 1 1 读入 行列反转法 输出:列全0行全1 ;读入:行列值 例S0按下,P2值为0x0E 32 0 1 2 3 0 1 2 3 行线 列线 +VCC S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 P2=0xf0; 输出 行列反转法 输出:列全1行全0 ; 输出:列全0行全1;读入:行列值 例S0按下,P2值为0x0E 33 0 1 2 3 0 1 2 3 行线 列线 +VCC S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 1 1 1 1 0 0 0 0 行列反转法 再次读入 输出:列全1行全0 ;再读入:行列值 输出:列全0行全1 ;读入:行列值 例S0按下,P2值为0x0E 例S0按下,P2值为0xE0 34 行列反转法 输出:列全0行全1;再读入:行列值 输出:列全0行全1 ; 读入:行列值 例S0按下,P2值为0x0E 例S0按下,P2值为0xE0 两次行列值合并,形成扫描码 相加 按位或 例:0xEE,S0的扫描码 16个按键的扫描码 确定 按键 35 keyscan 变量定义 键值key赋-1 列全1、行全0 读行列值 有键按下? 再次读行列值 有键按下? 延时去抖 列全0、行全1 读行列值 两次行列值相或 查取键号 返回键号 N N Y Y //行列反转法得到键值 char keyscan() { char scan1,scan2,keycode,j,key; key=-1; //键值初值为-1,如果没有扫描到按键,函数返回-1 P2=0xf0; //写:行为全1,列为全0 scan1=P2; //读:行列值 if(scan1!=0xf0) //如果读入的值不为0xf0,则表示有键按下 { delay(1200); //延时去抖 scan1=P2; //再次读入行列值 if(scan1!=0xf0) //再次判断是否有键按下 { P2=0x0f; //行列反转,写:行为全0,列为全1 scan2=P2; //读入行列值 keycode=scan1|scan2; //两次读入值按位或操作,合并在一起,得到扫描码 for(j=0;j<16;j++) //由扫描码表得到键值 { if(keycode==key_code[j]) { key=j;break; } } } } return(key); //返回键值 } #include <reg51.h> //包含头文件reg51.h,定义51单片机的专用寄存器 #include <lcd.h > //包含lcd子函数头文件 void delay (unsigned int i); //延时函数声明,函数定义参见任务2中的ex1_1.c char keyscan(); //采用行列反转法实现的矩阵键盘扫描函数 void puts(unsigned char ch[]); //显示字符串函数 void set_pw(); //密码设置函数,设置6位密码,存放到pw数组中 unsigned char code key_code[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb, 0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77}; //键盘按键对应的扫描码表 unsigned char pw[6]={0,0,0,0,0,0}; //存放原始密码 unsigned char pwnew[10]={0,0,0,0,0,0,0,0,0,0}; //pwnew存放输入的密码 sbit P33=P3^3; //控制发光二极管的亮灭,表示锁的打开和锁定状态 void main() { unsigned char i,count; bit pw_flag; //密码标志,1表示输入密码正确,0表示输入密码错误 P0=0xff; lcd_int(); //lcd初始化 delay(255); lcd_w_cmd(0x80); //光标定位,第1行第1列 puts("password:"); //显示字符串"password:" count=0; //输入字符个数清0 while(1){ //等待按键输入 i=keyscan(); //调用键盘扫描函数 if(i!=-1) //判断按键为有效键 { if(i>=0&&i<=9) //i是0-9之间的数字 { pwnew[count]=i; //输入数字存入pwnew数组 lcd_w_dat(i+0x30); //显示输入密码 count++; //不是结束键,则输入字符个数增1 P2=0xf0; while(P2!=0xf0); //判断按键释放 } else if(i==10) //判断是否10号键,如果是,则结束密码输入 { else { for(i=0;i<6;i++) //比较输入字符与原密码是否相同 { if(pw[i]!=pwnew[i]) //有不相同字符,则修改密码标志为0 { pw_flag=0; break; } } } if(pw_flag==1) //密码标志为1,密码输入正确 { lcd_w_cmd(0xc0); //光标定位,第2行第1列 puts("pass"); //显示字符串"pass" P33=0; //开锁指示灯点亮 while(1){ //等待按键按下 i=keyscan(); if(i!=-1)break; //有键按下则退出等待按键状态 } P2=0xf0; while(P2!=0xf0); //判断按键释放 if(i==11) set_pw(); //判断是否11号键,如果是,则进入密码设置 //调用密码设置函数 } else //密码输入错误 { lcd_w_cmd(0xc0); //光标定位,第2行第1列 P33=1; //开锁指示灯熄灭 puts("error"); //显示字符串"error" } count=0; delay (50000); //延时 lcd_w_cmd(0x01); //清屏 puts("password:"); //显示字符串"password:" } } } } //函数名:puts //函数功能:在lcd上显示字符串函数 //形式参数:待显示字符串的首地址 //返回值:无 void puts(unsigned char ch[]) { unsigned char i; i=0; while(ch[i]!='\0') { lcd_w_dat(ch[i]); i++; } } //函数名:set_pw //函数功能:密码设置函数,设置6位密码,存放到pw数组中 //形式参数:无 //返回值:无 void set_pw() { unsigned char key,count; lcd_w_cmd(0x01); //清屏,并光标定位,第1行第1列 puts("password setup:"); //显示字符串"password setup:" lcd_w_cmd(0xc0); //光标定位,第2行第2列 while(1) { key=keyscan(); if(key>=0&&key<=9) //key是0-9之间的数字 { lcd_w_dat('*'); //显示“*” pw[count]=key; //输入数字存入pwnew数组 count++; //不是结束键,则输入字符个数增1 if(count==6)break; //输入6个字符,自动结束 P1=0xf0; while(P1!=0xf0); //判断按键释放 } } } 在项目工程下组织若干个包含项目需要子函数的模块文件,避免大量函数代码都堆积在主程序文件中,使得程序的结构清晰、模块性强,提高可读性和可移植性。 lcd.c源文件中包含除主函数main()以外的所有读状态、写命令、写数据、初始化等LCD的子函数。 lcd.h头文件,对lcd.c中的子函数进行外部函数声明 $$

资源预览图

任务4-5  密码锁设计 (课件)-《单片机技术与应用》同步教学(电子工业版)
1
任务4-5  密码锁设计 (课件)-《单片机技术与应用》同步教学(电子工业版)
2
任务4-5  密码锁设计 (课件)-《单片机技术与应用》同步教学(电子工业版)
3
任务4-5  密码锁设计 (课件)-《单片机技术与应用》同步教学(电子工业版)
4
任务4-5  密码锁设计 (课件)-《单片机技术与应用》同步教学(电子工业版)
5
任务4-5  密码锁设计 (课件)-《单片机技术与应用》同步教学(电子工业版)
6
由于学科网是一个信息分享及获取的平台,不确保部分用户上传资料的 来源及知识产权归属。如您发现相关资料侵犯您的合法权益,请联系学科网,我们核实后将及时进行处理。