代码拉取完成,页面将自动刷新
/*
* Copyright (c) 2019-2021, jswy
*
* SPDX-License-Identifier: LGPL-3.0
*
* Change Logs:
* Date Author Notes
* 2019-03-01 jswy the first version
*/
/**
* @brief 相关寄存器
*/
#include <reg52.h>
#include "intrins.h"
sfr AUXR = 0x8E;
sfr T2H = 0xD6;
sfr T2L = 0xD7;
sbit door = P3 ^ 3;
/**
* @brief 指纹模块控制命令
*/
typedef enum
{
CMD_LED_RED_ON, /**< 亮红灯 */
CMD_LED_GREEN_ON, /**< 亮绿灯 */
CMD_LED_YELLOW_ON, /**< 亮黄灯 */
CMD_LED_ALL_OFF, /**< 熄灭所有灯 */
CMD_FINGER_DETECT, /**< 检测有无手指按下 */
CMD_GET_IMAGE, /**< 从指纹模块采集指纹数据 */
CMD_SEARCH_FINGERPRINT, /**< 验证是否匹配已录入的指纹 */
CMD_GET_EMPTY_ID, /**< 获取未录入指纹的第一个编号 */
CMD_GENERATE_0, /**< 暂存录入的第一次指纹 */
CMD_GENERATE_1, /**< 暂存录入的第二次指纹 */
CMD_GENERATE_2, /**< 暂存录入的第三次指纹 */
CMD_MERGE_CHAR, /**< 合并录入的三次指纹特征 */
CMD_STORE_CHAR /**< 存储合并后的指纹 */
} Command_t;
/**
* @brief 控制命令数据,和前面的枚举一一对应
*/
code unsigned char cmd_data[][26] =
{
"\x55\xAA\x00\x00\x24\x00\x04\x00\x03\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2C\x01",
"\x55\xAA\x00\x00\x24\x00\x04\x00\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2B\x01",
"\x55\xAA\x00\x00\x24\x00\x04\x00\x03\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2D\x01",
"\x55\xAA\x00\x00\x24\x00\x04\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2A\x01",
"\x55\xAA\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x01",
"\x55\xAA\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\x01",
"\x55\xAA\x00\x00\x63\x00\x06\x00\x00\x00\x01\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xB9\x01",
"\x55\xAA\x00\x00\x45\x00\x04\x00\x01\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\x01",
"\x55\xAA\x00\x00\x60\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x01",
"\x55\xAA\x00\x00\x60\x00\x02\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x62\x01",
"\x55\xAA\x00\x00\x60\x00\x02\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x01",
"\x55\xAA\x00\x00\x61\x00\x03\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x66\x01",
};
/** @brief 接收缓冲区,接收字符个数,已录入过指纹个数 */
unsigned char recv_buff[26], recv_count, empty_number;
/** @brief 定时器计数、PWM值 */
int T0_count, pwm = 50;
/**
* @brief 软件延时1毫秒
*
* @note 仅适用于STC15Fxx/STC15Lxx/STC15Wxx系列单片机,其它系列请使用STC-ISP软件生成,
* 方法参见: @ref https://jswyll.com/MCU51.html#软件延时代码生成
*/
void Delay1ms(void)
{
unsigned char i, j;
i = 12;
j = 169;
do
{
while (--j)
;
} while (--i);
}
/**
* @brief 软件延时n毫秒
*
* @note 仅适用于STC15Fxx/STC15Lxx/STC15Wxx系列单片机,其它系列请使用STC-ISP软件生成,
* 参见 @ref https://jswyll.com/MCU51.html#软件延时代码生成
*/
void delay_ms(unsigned int ms)
{
while (ms--)
Delay1ms();
}
/**
* @brief 串口初始化,波特率115200bps,启用中断
*
* @note 使用STC-ISP软件生成,
* 参见 @ref https://jswyll.com/MCU51.html#波特率代码生成;
* 对于STC15W204S单片机,只有定时器0和定时器2,请勿使用定时器1产生波特率
*/
void UartInit() // 115200bps@12.000MHz
{
SCON = 0x50; // 8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器2时钟为Fosc,即1T
T2L = 0xE6; //设定定时初值
T2H = 0xFF; //设定定时初值
AUXR |= 0x10; //启动定时器2
ES = 1; //打开串口发送/接收中断
}
/**
* @brief 从串口1以阻塞方式发送一个字节
*
* @param ch 待发送字符
*/
void uart_putchar(unsigned char ch)
{
SBUF = ch;
while (TI == 0)
;
TI = 0;
}
/**
* @brief 从串口1以阻塞方式发送字符数组
*
* @param tx_data 待发送字符数组
* @param num 需要发送的字符个数
*/
void uart_puts(unsigned char *tx_data, unsigned char num)
{
unsigned char i = 0;
while (i++ < num)
{
uart_putchar(*tx_data++);
}
}
/**
* @brief 根据枚举值的不同发送不同的指令给指纹模块
*
* @param cmd 指定命令 @ref Command_t
*/
void send_cmd(Command_t cmd)
{
switch (cmd)
{
case CMD_STORE_CHAR:
{
/* 根据指纹模块通讯协议,以录入编号计算检验和 */
unsigned int sum = 0x143 + empty_number;
uart_puts("\x55\xAA\x00\x00\x40\x00\x04\x00", 8);
uart_putchar(empty_number);
uart_puts("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 15);
uart_putchar(sum);
uart_putchar(sum >> 8);
break;
}
default:
uart_puts(cmd_data[cmd], 26);
break;
}
/* 等待指纹模块返回26个字节应答数据(中断接收) */
while (recv_count < 26)
;
recv_count = 0;
}
/**
* @brief 阻塞等待指纹模块上有手指按下
*/
void waitForFingerTouch()
{
/* 应答码第11个字节为1表示有手指按下 */
do
{
send_cmd(CMD_FINGER_DETECT);
} while (recv_buff[10] != 1);
/* 从指纹模块采集指纹数据 */
send_cmd(CMD_GET_IMAGE);
}
/**
* @brief 定时器0初始化,设置每10微秒产生中断
*/
void Timer0Init(void) // 10微秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x88; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
}
/**
* @brief UART1中断处理
*/
void UART1_IRQHandler() interrupt 4
{
if (RI)
{
RI = 0;
if (SBUF == 0xAA)
{
recv_count = 0;
}
recv_buff[recv_count++] = SBUF;
}
}
/**
* @brief 定时器中断,用于产生PWM
*/
void T0_IRQHandler() interrupt 1
{
if (T0_count < pwm)
door = 1;
else
door = 0;
if (++T0_count == 2000)
T0_count = 0;
}
/**
* @brief 开门。绿灯亮,PWM驱动舵机开门
*/
void open_door(void)
{
int i = 0;
send_cmd(CMD_LED_GREEN_ON);
/* 平滑打舵 */
for (i = 0; i < 130; i += 3)
{
pwm = 50 + i;
delay_ms(1);
}
delay_ms(800);
pwm = 50;
}
/**
* @brief 程序入口
*/
void main()
{
P3M0 = 0xff;
P3M1 = 0x00;
door = 1;
Timer0Init();
UartInit();
EA = 1;
pwm = 50;
while (1)
{
/* 指示灯灭, 阻塞等待指纹模块上有手指按下 */
send_cmd(CMD_LED_ALL_OFF);
do
{
send_cmd(CMD_GET_IMAGE);
} while (recv_buff[8] != 0x00);
/* 生成指纹特征并验证是否匹配已录入的指纹 */
send_cmd(CMD_GENERATE_0);
send_cmd(CMD_SEARCH_FINGERPRINT);
if (recv_buff[6] == 0x05 && recv_buff[10] > 0)
{
/* 如果匹配的是已录入的编号1(管理员),录入新指纹 */
if (recv_buff[10] == 1)
{
/* 获取第一个未被注册的编号 */
send_cmd(CMD_GET_EMPTY_ID);
empty_number = recv_buff[10];
/* 连续采集3次 */
send_cmd(CMD_LED_YELLOW_ON); //亮黄灯,等待手指按下
delay_ms(500); //延时,避免录入的第一个是管理员未弹起的手指
waitForFingerTouch(); //调用采集指纹函数
send_cmd(CMD_GENERATE_0); //暂存录入的第一次指纹
send_cmd(CMD_LED_ALL_OFF); //灭灯,提示手指移开
delay_ms(500); //等待手指移开
send_cmd(CMD_LED_YELLOW_ON);
waitForFingerTouch();
send_cmd(CMD_GENERATE_1);
send_cmd(CMD_LED_ALL_OFF);
delay_ms(500);
send_cmd(CMD_LED_YELLOW_ON);
waitForFingerTouch();
send_cmd(CMD_GENERATE_2);
send_cmd(CMD_LED_ALL_OFF);
/* 合成三次录入的指纹特征并存储 */
send_cmd(CMD_MERGE_CHAR);
send_cmd(CMD_STORE_CHAR);
}
/* 绿灯亮,表示指纹匹配或者指纹录入完成,控制继电器开门 */
open_door();
}
else
{
/* 指纹数据和录入过的都不匹配,亮红灯 */
send_cmd(CMD_LED_RED_ON);
/* 延时再作匹配判断,避免短时间触发判断两次同样的指纹 */
delay_ms(500);
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。