OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5689|回复: 4

密码锁(状态机)

[复制链接]

5

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2015-9-16
在线时间
0 小时
发表于 2015-10-21 21:12:11 | 显示全部楼层 |阅读模式
[mw_shl_code=c,true]#include <reg52.h> #include <intrins.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef enum{ STATE0 = 0, STATE1, STATE2, STATE3, STATE4, }STATE; STATE current_state = STATE0; #define uint unsigned int #define uchar unsigned char #define DataPort P0 #define RS_CLR RS=0 #define RS_SET RS=1 #define RW_CLR RW=0 #define RW_SET RW=1 #define EN_CLR EN=0 #define EN_SET EN=1 sbit RS = P2^4; //?¨??????,?è?? sbit RW = P2^5; sbit EN = P2^6; uchar key=20,ch; uchar table[]={'1','2','3','4','5','6','7','8','9','0'}; void delayms(uint); void LCD_show(); void test(); void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } // 1602???? /*------------------------------------------------ ?????ü??????M ------------------------------------------------*/ void LCD_Write_Com(unsigned char com) { delayms(5); RS_CLR; RW_CLR; EN_SET; DataPort= com; _nop_(); EN_CLR; } /*------------------------------------------------ ???????????? ------------------------------------------------*/ void LCD_Write_Data(unsigned char Data) { //while(LCD_Check_Busy()); //???ò???? delayms(5); RS_SET; RW_CLR; EN_SET; DataPort= Data; _nop_(); EN_CLR; } /*------------------------------------------------ ???????? ------------------------------------------------*/ void LCD_Clear(void) { LCD_Write_Com(0x01); delayms(5); } /*------------------------------------------------ ????×?·??®???? ------------------------------------------------*/ void LCD_Write_String(uchar x,uchar y,uchar *s) { if (y == 0) { LCD_Write_Com(0x80 + x); } else { LCD_Write_Com(0xC0 + x); } while (*s) { LCD_Write_Data( *s); s ++; } } /*------------------------------------------------ ????×?·????? ------------------------------------------------*/ void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) { if (y == 0) { LCD_Write_Com(0x80 + x); } else { LCD_Write_Com(0xC0 + x); } LCD_Write_Data( Data); } /*------------------------------------------------ ?????????? ------------------------------------------------*/ void LCD_Init(void) { LCD_Write_Com(0x38); /*?????????è??*/ delayms(5); LCD_Write_Com(0x38); delayms(5); LCD_Write_Com(0x38); delayms(5); LCD_Write_Com(0x38); LCD_Write_Com(0x08); /*??????±?*/ LCD_Write_Com(0x01); /*????????*/ LCD_Write_Com(0x06); /*??????±ê?????è??*/ delayms(5); LCD_Write_Com(0x0C); /*???????°??±ê?è??*/ } //???ó?ü?? void matrixkeyscan() { uchar temp; P3=0xfe; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xee: key=11; break; case 0xde: key=3; break; case 0xbe: key=2; break; case 0x7e: key=1; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } } } P3=0xfd; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xed: key=12; break; case 0xdd: key=6; break; case 0xbd: key=5; break; case 0x7d: key=4; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } } } P3=0xfb; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xeb: key=13; break; case 0xdb: key=9; break; case 0xbb: key=8; break; case 0x7b: key=7; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } } } P3=0xf7; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xe7: key=16; break; case 0xd7: key=12; break; case 0xb7: key=11; break; case 0x77: key=10; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } } } } uchar datadeal() { if(key<=10) return table[key-1]; else return 0xff; } void main() { uchar k,i; LCD_Init(); LCD_Write_Com(0x0F); LCD_Write_String(1,0,"Input the code"); delayms(2000); while(1) { for(i=0;i<4;) { matrixkeyscan(); while((ch!=datadeal())&&(datadeal()!=0xff)) { ch=datadeal(); LCD_Write_Char(0+k,1,ch);//????????????×?·? k++; switch(current_state){ case STATE0: if(ch == '2') current_state = STATE1; break; case STATE1: if(ch == '4') current_state = STATE2; break; case STATE2: if(ch == '7') current_state = STATE3; break; case STATE3: if(ch == '9') current_state = STATE4; break; default: current_state = STATE0; break; } i++; } }k=0; if(current_state == STATE4){ LCD_Clear(); delayms(10); LCD_Write_Com(0x0c); LCD_Write_String(4,0,"Correct"); LCD_Write_String(2,1,"Lock is open"); current_state = STATE0; while(1); }else { LCD_Clear(); LCD_Write_String(4,0,"Wrong"); LCD_Write_String(1,1,"Lock is closed"); current_state = STATE0; } break; } delayms(2000); } [/mw_shl_code]
这是我第一次用状态机的概念来编程,程序比较小,功能也比较简单,就是用矩阵键盘输入数字,1602液晶显示,不过与一般密码锁有所不同,我用状态机来比较输入的数字与正确数字,感觉比较简单,但是,还有很多不足:输入的数字无法显示最后一位,但是状态机可以判断(这个暂时未解决,希望大家给些建议);本来想把是1602显示的部分和状态机部分分别做成函数,但是那样运行不成功,就这样写了,程序看起来不太清晰,望提宝贵意见
自强不息,厚德载物 我有我精彩
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165369
金钱
165369
注册时间
2010-12-1
在线时间
2110 小时
发表于 2015-10-21 21:39:34 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2015-9-16
在线时间
0 小时
 楼主| 发表于 2015-10-21 23:13:45 | 显示全部楼层
回复【2楼】正点原子:
能不能顺便帮忙解答下
自强不息,厚德载物 我有我精彩
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165369
金钱
165369
注册时间
2010-12-1
在线时间
2110 小时
发表于 2015-10-25 23:23:14 | 显示全部楼层
回复【3楼】海之殇:
---------------------------------
没搞过
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

20

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
323
金钱
323
注册时间
2018-1-23
在线时间
40 小时
发表于 2018-3-25 20:25:07 | 显示全部楼层
厉害了!顶!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-1 11:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表