×
单片机 > 单片机程序设计 > 详情

51单片机项目 门禁系统

发布时间:2020-06-15 发布时间:
|


/**

 * 项目名:门禁系统

 * 文件名: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;

                        


关键字:51单片机  门禁系统  蜂鸣器

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
如何为单片机选择合适的负载电容