/**
* 项目名:门禁系统
* 文件名:main.h
*/
#ifndef _MAIN_H
#define _MAIN_H
sbit RELAY_PIN = P0^4;
sbit BUZZER_PIN = P0^6;
void sys_init();
void samplingDS1302();
void samplingUlt();
void initDispMode1();
void initDispMode2();
void initDispMode3();
void refreshTimeDisplay();
#endif
/**
* 项目名:门禁系统
*
* 7:00-22:00工作在模式0(自动门状态)
* 22:00-7:00工作在模式1(密码门状态)
* 难点:继电器在接通5s后断开
* 蜂鸣器报警3s
* 文件名:main.c
*/
#include
#include
#include "stdint.h"
#include "timer.h"
#include "digitalTube.h"
#include "matrixKey.h"
#include "DS1302.h"
#include "EEPROM.h"
#include "ultrasonic.h"
#include "electromagneticDev.h"
#include "main.h"
volatile bit flag50ms = 0, flag200ms = 0, flag500ms = 0; //任务标志
bit workingMode = 1; //工作模式,初始化时间为06:59:00
uint8_t dispMode = 0; //在密码门状态下的显示模式{0, 1, 2, 3}
uint8_t code initPassword[7] = "654321"; //初始密码
uint8_t password[7]; //当前密码
bit isOpen = 0; //继电器是否打开
volatile bit enBuzzer = 0;
sTime_t time;
static uint8_t wrongTimes = 0, passwdTmpIndex = 0; //!!!here
void main() {
uint8_t cnt500ms = 0;
sys_init();
while (1) {
if (flag50ms) {
flag50ms = 0;
keyDriver();
}
if (flag200ms) {
flag200ms = 0;
samplingDS1302();
if (workingMode == 0) { //如果工作于自动门状态
samplingUlt(); //采样超声波模块
}
}
if (flag500ms) {
flag500ms = 0;
if (workingMode == 1) { //如果工作于密码门状态
if (isOpen) { //如果检测到门是打开的
if (cnt500ms == 10) {
cnt500ms = 0;
relay_off();
isOpen = 0;
} else {
cnt500ms++;
}
}
}
}
}
}
void sys_init() {
tmr0_init(2);
tmr1_specialInit();
stc15_tmr2_init(1); //!!!
DS1302_init();
EEPROM_read(password, 0, sizeof (password)); //addr=0
if (strncmp(password, "000000", 6) == 0) { //如果没有被初始化过
strncpy(password, initPassword, 6);
EEPROM_write(initPassword, 0, sizeof (initPassword));
}
}
void samplingDS1302() { //采样实时时间用于控制工作模式
static uint8_t preSec;
DS1302_getRealTime(&time);
if (time.hour == 0x07 && time.minute == 0x00) { //如果到了7:00
workingMode = 0; //工作于自动门状态
dispMode = 0; //!!!显示模式归0
wrongTimes = 0; //!!!
passwdTmpIndex = 0; //!!!
} else if (time.hour == 0x22 && time.minute == 0x00) { //如果到了22:00
workingMode = 1; //工作于密码门状态
}
if (dispMode == 0) { //如果是显示模式0,则更新显示
if (time.sec != preSec) { //秒有变化则更新显示
preSec = time.sec;
refreshTimeDisplay();
}
}
}
void samplingUlt() { //工作于自动门状态,由超声波测得的距离控制继电器的开闭
static uint8_t ultCnt200ms = 0;
uint8_t dis;
dis = ult_getDis();
if (isOpen == 0) { //如果之前是关闭的状态
if (dis < 30) { //如果测量到的距离小于30cm
relay_on();
isOpen = 1;
}
} else if (isOpen == 1) {
if (dis >= 30) {
if (ultCnt200ms == 24) {
ultCnt200ms = 0;
relay_off();
isOpen = 0;
} else {
ultCnt200ms++;
}
} else {
ultCnt200ms = 0;
}
}
}
void keyAction(uint8_t keyCode) {
static uint8_t passwdTmp[7];
if (workingMode == 0) //如果工作于自动门状态,则对按键无响应
return;
if (keyCode == 'q') { //如果按的是确认键
if (passwdTmpIndex == 6) { //如果输入了6位密码
passwdTmpIndex = 0; //!!!复位写索引
if (dispMode == 1) { //如果当前是密码验证界面
if (strncmp(passwdTmp, password, 6) == 0) { //如果密码匹配成功
dispMode = 0; //回到时间显示界面
refreshTimeDisplay(); //重新显示时间
relay_on(); //打开继电器
isOpen = 1; //!!!!!!
wrongTimes = 0; //!!!连续错误次数归0
} else { //密码匹配失败
if (wrongTimes >= 2) { //如果连续错误次数达到3次
enBuzzer = 1;
} else {
wrongTimes++;
}
initDispMode1(); //清空输入的密码
}
} else if (dispMode == 2) { //如果当前是旧密码验证界面
if (strncmp(passwdTmp, password, 6) == 0) { //如果密码匹配成功
//passwdTmpIndex = 0; //复位
dispMode = 3; //进入新密码输入界面
initDispMode3();
wrongTimes = 0; //!!!连续错误次数归0
} else { //密码匹配失败
if (wrongTimes == 2) { //如果错误次数达到3次
enBuzzer = 1;
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』