密碼鎖課程設(shè)計(jì)
1.設(shè)計(jì)基于單片機(jī)控制的密碼鎖
本文引用地址:http://www.ex-cimer.com/article/201611/315775.htm2.基本功能要求:
a.12個(gè)按鍵,用于輸入密碼及設(shè)定,其中s/c分短按(clear)和長(zhǎng)按(set)
b.兩個(gè)led燈反映密碼輸入正確(綠燈亮),錯(cuò)誤(紅燈亮)
c.原始密碼為:000000 應(yīng)可隨以修改(掉電新密碼不丟失)
下面是我做的具體過(guò)程
下面是protues的截圖如下(你可以照著在proteus中設(shè)置):
代碼貼出來(lái),可以直接子啊uvision4上運(yùn)行的。。。
//下面程序?yàn)槊艽a鎖控制程序,可實(shí)現(xiàn)設(shè)定密碼,判斷密碼是否正確,并且掉電不丟失的功能
#include
//類型重定義
#define uchar unsigned char
#define uint unsigned int
//函數(shù)聲明
void start();//開(kāi)始信號(hào)
uchar read_add(uchar);
void key_scan();
void write_add(uchar address,uchar date);
void delay1ms(uint z);
void delay();
void stop(); //停止
void respons();//應(yīng)答
void init();
void write_byte(uchar date);
uchar read_byte();
//全局變量聲明
uchar key=0;
uchar password[6];
uchar KeyCnt;
uchar flag=0;
uchar password_err;
uchar ok_right;
//ii2c芯片的時(shí)鐘線和數(shù)據(jù)線
sbit sda=P2^3;
sbit scl=P2^2;
//主函數(shù)
void main(){
uchar temp,i;
uchar password_err=0;
uchar password_old[6]={0};
KeyCnt=0;
flag=0;
ok_right=0;
password_err=0;
init();//ii2c芯片初始化
for(i=0;i<6;i++){
temp=read_add(i+1);//調(diào)用ii2c芯片中的數(shù)據(jù)(已設(shè)定為6位)
if(temp<0 || temp >9 ){//如果讀出的數(shù)據(jù)不對(duì),說(shuō)明為第一次使用密碼鎖,就初始化為0
for(i=0;i<6;i++)
password_old[i]=0;
break;
}
password_old[i]=read_add(i+1);
delay1ms(10);
}
key=255;//默認(rèn)key值設(shè)定為255,為了調(diào)試使用
while(1){
key_scan();//掃描按鍵掃描函數(shù)
if( key <= 9 ){
password[KeyCnt]=key;
P3=KeyCnt;//輸出調(diào)試信息
}
if(key == 11){//對(duì)應(yīng)于ok鍵,判斷密碼是否正確
for(i=0;i<6;i++)
if(password_old[i] != password[i]){
password_err=1;
break;
}
if(password_err==1){
P2 =(P2&0xfc)|0x02;
password_err=0;
}
else {
P2 =(P2 &0xfc)|0x01;
}
}
if(key==10){//對(duì)應(yīng)于s/c鍵,進(jìn)入重設(shè)密碼子程序
KeyCnt=0;
ok_right=0;
while(1){
key_scan();
//;//key=0;key=16;
if( key <= 9 ){
password[KeyCnt]=key;
P3=KeyCnt;
}
if(flag==2){ //長(zhǎng)按
P2 =P2&0xfc;//重設(shè)的話,雙燈亮
if(ok_right==7&&key==11){
for(i=0;i<6;i++)
{//重設(shè)的密碼寫入存儲(chǔ)芯片中
write_add(i+1,password[i]);
delay1ms(10);
}
key=255;
KeyCnt=0;
ok_right=0;
break;
}
}
if(flag == 1){//短按
for(i=0;i<6;i++){
write_add(i+1,0);
if((i+1)/2) P2 =(P2&0xfc)|0x02;
elseP2 =(P2&0xfc)|0x01;
delay1ms(300);
}
KeyCnt=0;
ok_right=0;
key=255;
break;
}
}
}
}
}
/***************************下面為ii2c芯片操作函數(shù)集**************************/
void delay()
{ ;; }
void delay1ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void start()//開(kāi)始信號(hào)
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop()//停止
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void respons()//應(yīng)答
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
void init()
{
sda=1;
delay();
scl=1;
delay();
}
void write_byte(uchar date)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
}
uchar read_byte()
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
//向ii2c芯片中寫入數(shù)據(jù)
void write_add(uchar address,uchar date)
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
//從ii2c芯片中讀出數(shù)據(jù)
uchar read_add(uchar address)
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
/***************************下面為按鍵掃描函數(shù)**************************/
void key_scan()
{
uchar m0,m1;
uchar temp;
P1=0xf0;//這樣設(shè)置是為了能使低四位將高四位拉低,釋放時(shí)自動(dòng)拉高高四位
temp=P1;
if(temp!=0xf0)
{
delay1ms(10);//延時(shí),去除抖動(dòng)
if(temp!=0xf0)
{
m0=temp;//獲得按鍵的列號(hào)(對(duì)應(yīng)的就是高4位)
P1=0x0f;
temp=P1;
if(temp!=0x0f)
{
m1=temp;//獲得按鍵的行號(hào)(對(duì)應(yīng)的就是低4位)
temp=m0|m1;//組合成最終的按鍵好
}
KeyCnt++;
if(KeyCnt==7)
KeyCnt=0;
ok_right++;
if(ok_right==8)
ok_right=0;
switch(temp)
{
case 0xee:key=0;break;//按鍵對(duì)應(yīng)的碼表
case 0xde:key=1;break;
case 0xbe:key=2;break;
case 0x7e:key=3;break;
case 0xed:key=4;break;
case 0xdd:key=5;break;
case 0xbd:key=6;break;
case 0x7d:key=7;break;
case 0xeb:key=8;break;
case 0xdb:key=9;break;
case 0xbb:
key=10;
P1=0x0f;
delay1ms(700);
temp=P1;
if(temp == 0x0f) //短按
flag=1;
else
flag=2;//長(zhǎng)按
break;
case 0x7b:key=11;break;
default:key=16;break;
}
do{
temp=P1;//消除按起抖動(dòng)
temp&=0X0f;
}while(temp!=0x0f);
}
}
}
以上內(nèi)容就可以滿足要求。。。。
評(píng)論