基于stc15系列芯片的电子密码锁代码
时间:2023-10-09 17:37:00
/********************************************************************************** 功能: 包括必要的头文件,宏定义,位定义,声明变量和函数 ***********************************************************************************/ #include"STC15W4K.h" #define uint unsigned int #define uchar unsigned char //on_off的状态值,表示电子密码的状态 #define FLAG_OFF 0 //关闭 #define FLAG_ON 1 //打开 #define FLAG_SETTING 2 //设置 //nset状态值,表示是否处于重置状态 #define FLAG_RESET_ON 1 //重置 #define FLAG_RESET_OFF 0 //非重置 //key几个特殊值 #define KEY_BORDER 0x0a //键值边界,密码号不超过9 #define KEY_ENSURE 0x0c //关闭 #define KEY_RESET 0x0d //重置 //定义按钮的位置 sbit L1 = P1^0; sbit L2 = P1^1; sbit L3 = P1^2; sbit L4 = P1^3; //led蜂鸣器定义,test用作测试 sbit LED_ON = P3^2; sbit LED_OFF = P3^3; sbit LED_SET = P3^4; sbit test = P3^5; sbit fmq = P3^6; sbit led = P5^5; ///全局声明变量 extern uchar key_times; extern uchar nset; extern uchar on_off; extern uchar i,j,temp; extern uchar key; extern uchar key_delay; //函数声明 void delayms(uint xms); void scankey(); void led_change(uchar option); bit judge(); void init(); void scomm();
#include "function.h" ///保存当前密码,输入密码 uchar password[] = {0x01,0x01,0x01,0x01,0x01,0x01}; uchar input[] = {0xff,0xff,0xff,0xff,0xff,0xff}; /********************************************************************************** 功能: 延时,最小单位为ms(晶振为11.0592 计算方法:一for循环 = 8个指令周期 = 8*12个机器周期 = 8*12*1/11.0592 = 0.0086ms xms = 0.0086 * 110 = 0.946 ms ***********************************************************************************/ void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } /********************************************************************************** 功能: 改变几个led的状态 ***********************************************************************************/ void led_change(uchar option) { if(option == 0) ///关闭状态 { LED_ON = 1; LED_OFF = 0; LED_SET = 1; } else if(option == 1) //打开状态 { LED_ON = 0; LED_OFF = 1; LED_SET = 1; } else if(option == 2) //设置状态 { LED_ON = 1; LED_OFF = 1; LED_SET = 0; } } /********************************************************************************** 功能: 扫描按钮得到键值 方法: 先扫行,再扫列 ***********************************************************************************/ void scankey() { P1 = 0xef; //key = 0xff; for(i=0;i<4;i ) { if(L1==0) { delayms(key_delay); if(L1==0) key = i*4 0; if(key < KEY_BORDER && on_off != FLAG_ON)///解锁后按钮不计数 key_times = key_times 1; } if(L2==0) { delayms(key_delay); if(L2==0) key = i*4 1; if(key < KEY_BORDER && on_off != FLAG_ON) key_times = key_times 1; } if(L3==0 && on_off != FLAG_ON) { delayms(key_delay); if(L3==0) key = i*4 2; if(key < KEY_BORDER) key_times = key_times 1; } if(L4==0 && on_off != FLAG_ON) { delayms(key_delay); if(L4==0) key = i*4 3; if(key < KEY_BORDER) key_times = key_times 1; } delayms(5); ///准备下次扫描的时间间隔 temp=P1; temp=temp|0x0f; temp=temp<<1; temp=temp|0x0f; P1=temp; } //扫描后判断键值 switch(key) { case KEY_ENSURE: { led_change(0); ///改变灯的状态 key_times = 0; on_off = FLAG_OFF;//定义宏 } break; case KEY_RESET: { if(on_off == FLAG_ON) { led_change(2); key_times = 0; on_off = FLAG_SETTING; nset = FLAG_RESET_ON; } else if(on_off == FLAG_OFF) { fmq = 0; delayms(10); fmq = 1; key = 0x00; //防止在这里循环 } } break; default:break; } } /********************************************************************************** 功能: 判断密码是否符合设置密码,重置新密码 ***********************************************************************************/ bit judge() { if(nset == FLAG_RESET_OFF) ///默认状态 { //test密码输入后可以进入 switch(key_times) { case 1:input[0] = key;break; case 2:input[1] = key;break; case 3:input[2] = key;break; case 4:input[3] = key;break; case 5:input[4] = key;break; case 6:input[5] = key;break; default:break; } } if(nset == FLAG_RESET_ON) ///重置状态,更换旧密码,打开锁 { switch(key_times) { case 1:password[0] = key;input[0] = key;break; case 2:password[1] = key;input[1] = key;break; case 3:password[2] = key;input[2] = key;break; case 4:password[3] = key;input[3] = key;break; case 5:password[4] = key;input[4] = key;break; case 6:password[5] = key;input[5] = key;break; default:break; } } if(key_times == 6) { if(nset == FLAG_RESET_ON ) nset = FLAG_RESET_OFF; key_times = 0; for(j=0;j<6;j ) { if(password[j] != input[j]) //报警 { LED_ON 1;
fmq = 0;
delayms(30);
LED_OFF = ~LED_OFF;
delayms(30);
LED_OFF = ~LED_OFF;
delayms(30);
LED_OFF = ~LED_OFF;
delayms(30);
LED_OFF = ~LED_OFF;
fmq = 1;
return 0;
}
}
on_off = FLAG_ON;
scomm();
return 1;
}
return 0;
}
/**********************************************************************************
功能: 初始化,包括对led,定时器,串口的初始化
***********************************************************************************/
void init()
{
led_change(0);
fmq = 0;
delayms(20);
fmq = 1;
P1M0 = 0;P1M1 = 0;
SCON = 0x40;
T2L = 0xe0; //定时器2作为波特率发生器
T2H = 0xfe;
AUXR = 0x14;
AUXR |= 0x01;
TI = 1;
}
/**********************************************************************************
功能: 发送单片机信息,一次七个字节,其中首字节为状态,其余六字节为当前密码
***********************************************************************************/
void scomm()
{
uchar i;
SBUF = on_off;
while(TI == 0);
TI = 0;
for(i=0;i<6;i++)
{
while(TI == 0);
{
TI = 0;
SBUF = password[i];
}
}
}
/********************************************************************************************
File name: 电子密码锁
Main fouction: 六位密码开解锁,包含重置功能,并将实时信息发送到上位机
Last modified Date: 2017-10-22
Created by: zzh
Steps for test 1 输入原始密码111111,看是否打开
2 再锁定,看是否关闭
3 此时输入错误密码,看是否报警
4 此时重设,因未解锁看是否报警
5 输入正确密码,此时重设,输入新密码,此时应保持解锁状态
6 关锁,输入新密码
7 重复2~6
*********************************************************************************************/
#include "function.h"
//变量初始化
uchar key_times = 0;
uchar nset = FLAG_RESET_OFF;
uchar on_off = FLAG_OFF;
uchar i,j,temp;
uchar key = 0xff;
uchar key_delay = 5;
void main()
{
uint t;
init();
while(1)
{
scankey();
if(judge() == 1)
{
led_change(1);
on_off = FLAG_ON;
}
if(key_times > 6)
key_times = 0;
}
}