/*******************************************************************************
* 目标:第三届题目 “门禁系统” 设计任务书
* 密码正确进入,密码错误回到时钟状态
* 注意:J3跳线配置为IO方式,J5配置为KBD、J2配置为1-3和2-4
* 作者:祝云翔
* 日期版本:2021-1-23/V1.0
*******************************************************************************/
#include <STC15F2K60S2.h>
#include "intrins.h"
#include "ds1302.h"
#include "iic.h"
#define somenop \
{ \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
_nop_(); \
}
// 15个
sbit TX = P1 ^ 0; //发射引脚
sbit RX = P1 ^ 1; //接收引脚
// 小数点是第8位为0 原本数字 - 0x80
unsigned char data_pros[] = {
0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0xff, 0xbf};
unsigned char dspbuf[8] = {10, 10, 10, 10, 10, 10, 10, 10}; //显示缓冲区
unsigned char *time_ds1302; // 时间
unsigned char ds1302_flag = 0; // 0 1
unsigned char mode_flag = 1; // 初始值1
unsigned char key_flag = 0;
unsigned char smg_location = 2; // 从2开始
unsigned char ultrasonic_flag = 0;
// 初始化值
void close_init()
{
P2 = 0xA0;
P0 = 0x00;
P2 = 0x80;
P0 = 0xff;
P2 = 0x00;
}
void Delay5ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{
while (--j)
;
} while (--i);
}
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 22;
j = 3;
k = 227;
do
{
do
{
while (--k)
;
} while (--j);
} while (--i);
}
// 显示函数 dspbuf为数码管的缓冲区
void display()
{
static unsigned char dspnum = 0; // 数码管的位置
P2 = 0xE0;
P2 = 0xff; // 消影
P2 = 0xc0;
P0 = (1 << dspnum);
P2 = 0xe0;
P0 = data_pros[dspbuf[dspnum]];
P2 = 0x00;
if (++dspnum == 8)
dspnum = 0;
}
void Timer0Init(void) // 1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
// add
TH1 = 0;
TL1 = 0;
ET0 = 1;
EA = 1;
}
// 注意J5设置为KBD模式(J5的2和1相连)
unsigned char read_keys()
{
static unsigned char hang, lie;
static unsigned char key_state = 0, key_value = 0;
switch (key_state)
{
case 0:
{
P3 = 0x0f;
P42 = 0;
P44 = 0; // 消抖
if (P3 != 0x0f) //有按键按下
key_state = 1;
}
break;
case 1:
{
P3 = 0x0f;
P42 = 0;
P44 = 0;
Delay5ms();
if (P3 != 0x0f) //有按键按下 确定行
{
if (P30 == 0)
hang = 1;
if (P31 == 0)
hang = 2;
if (P32 == 0)
hang = 3;
if (P33 == 0)
hang = 4;
}
else
key_state = 0;
P3 = 0xf0;
P42 = 1;
P44 = 1;
Delay5ms();
if ((P3 != 0xf0) || (P42 != 0) || (P44 != 0)) //有按键按下 确定列
{
if (P44 == 0)
lie = 1;
if (P42 == 0)
lie = 2;
if (P35 == 0)
lie = 3;
if (P34 == 0)
lie = 4;
key_state = 2;
key_value = lie + (hang - 1) * 4 - 1; //修改
return key_value;
}
else
key_state = 0;
}
break;
case 2:
{
P3 = 0x0f;
P42 = 0;
P44 = 0;
if (P3 == 0x0f) //按键放开
key_state = 0;
}
break;
}
return 0xff;
}
// 判断密码是否正确 正确传回1
unsigned char password(unsigned char yi[], unsigned char er[])
{
unsigned char j = 0;
for (j = 0; j < 6; j++)
{
if (yi[j] != er[j + 2])
return 0xff;
}
return 1;
}
// 判断密码是否都为0-9 正确传回1
unsigned char password_0_9(unsigned char yi[])
{
unsigned char j = 0;
for (j = 2; j < 6; j++)
{
if (yi[j] > 9)
return 0xff;
}
return 1;
}
// TX引脚发送40KHz方波信号驱动超声波发送探头
//使用软件延时注意RC振荡器频率
void send_wave(void)
{
unsigned char i = 8; //发送8个脉冲
unsigned char j = 0;
do
{
TX = 1;
for (j = 0; j < 16; j++)
somenop;
TX = 0;
for (j = 0; j < 16; j++)
somenop;
} while (i--);
}
// 超声波测距 TMOD |= 0x11; //配置定时器工作模式 999 无返回
unsigned int ultrasonic(void)
{
// 包括超声波
// TH1 = 0;
// TL1 = 0;
// ET0 = 1;
// EA = 1;
static unsigned int distance = 0, time = 0;
/** 关闭定时器0中断:计算超声波发送到返回的时间 */
// ET0 = 0;
send_wave(); //发送方波信号
TR1 = 1; //启动计时
while ((RX == 1) && (TF1 == 0))
; //等待收到脉冲,没有计满溢出
TR1 = 0; //关闭计时
//发生溢出
if (TF1 == 1)
{
TF1 = 0;
distance = 999; //无返回
}
else
{
/** 计算时间 */
time = TH1;
time <<= 8;
time |= TL1;
distance = (unsigned int)(time * 0.017); //计算距离
}
TH1 = 0;
TL1 = 0;
return distance;
}
void main()
{
unsigned char key_value = 0; // 键值
unsigned char i;
unsigned char eeprom_value[6] = {6, 5, 4, 3, 2, 1};
unsigned char eeprom_value_old[6] = {6, 5, 4, 3, 2, 1};
unsigned char eeprom_location[6] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
unsigned char password_value = 0;
unsigned char password_number = 0; // 错误次数
unsigned int ultrasonic_value = 0;
unsigned char now_time = 0;
close_init();
Timer0Init();
SetRTC(); // 设置初始时间
Delay5ms();
// for (i = 0; i < 6; i++) // 初始化密码
// {
// Write_EEPROM(eeprom_location[i], eeprom_value[i]);
// Delay500ms();
// Delay500ms();
// }
// Delay500ms();
// Delay500ms();
for (i = 0; i < 6; i++) // 读取存放的密码
{
eeprom_value[i] = Read_EEPROM(eeprom_location[i]);
// mode_flag = 2;
// dspbuf[i] = eeprom_value[i];
Delay500ms();
}
while (1)
{
if ((ds1302_flag == 1) && (mode_flag == 1)) // 时钟
{
ds1302_flag = 0;
time_ds1302 = ReadRTC();
// 更新时间
dspbuf[0] = time_ds1302[0];
dspbuf[1] = time_ds1302[1];
dspbuf[2] = 11;
dspbuf[3] = time_ds1302[2];
dspbuf[4] = time_ds1302[3];
dspbuf[5] = 11;
dspbuf[6] = time_ds1302[4];
dspbuf[7] = time_ds1302[5];
smg_location = 2;
now_time = time_ds1302[0] * 10 + time_ds1302[1]; // 判断现在是什么模式
if ((time_ds1302[2] > 0) || (time_ds1302[3] > 0) || (time_ds1302[4] > 0) || (time_ds1302[5] > 0))
now_time++;
}
if ((ultrasonic_flag == 1) && (mode_flag == 1) && (now_time > 7) && (now_time <= 22))
{
ultrasonic_flag = 0;
ultrasonic_value = ultrasonic(); // 距离
评论0