功能:
0.本项目采用STC89C52作为单片机系统的控制MCU,LCD1602作为显示器
1.3张卡别代表依次是张、李、王,任何一个人刷卡成功能,1602液晶响应显示,未刷卡显示空“ ”位置上空的,刷卡成功后相应位置显示有人。
2.液晶第二行显示刷卡人数,即出勤总人数,一个功能按键,按下按键表示上课,如果签到人数和总人数不符合,蜂鸣器报警处理。
4.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
#include <intrins.h>
#include "delay.h"
#include "rc522.h"
#include "lcd1602.h"
sbit KEY_CHECK = P3^2;
sbit BUZZER = P1^0;
/*********/
// ID由串口信息获取
unsigned char code zsID[4] = {0x4C, 0x8C, 0xE4, 0x17}; //张三卡号
unsigned char code lsID[4] = {0x2C, 0x96, 0xE4, 0x17}; //李四卡号
unsigned char code weID[4] = {0x59, 0x7B, 0x07, 0xE5}; //王二卡号
/*********/
unsigned char UID[4]; //卡号
unsigned char Temp[4]; //暂存数组
unsigned long time_20ms; //定时计数
char dis0[16]; //液晶显示数组
char dis1[16];
unsigned char zsFlag = ' '; //张三 是否到标志
unsigned char lsFlag = ' '; //李四 是否到标志
unsigned char weFlag = ' '; //王二 是否到标志
unsigned char disFlag = 0; //显示标志
unsigned char manNum = 0; //人数
bit buzFlag = 0; //蜂鸣器报警标志
bit rekey = 0; //蜂鸣器报警标志
void Timer0_Init(void); //函数声明
void UART_Init(void);
void UART_SendStr(unsigned char *s, unsigned char length);
void UART_SendByte(unsigned char dat);
void main(void)
{
unsigned char disPlace = 0; //显示位置
Timer0_Init(); //定时器0初始化
UART_Init(); //串口初始化
BUZZER = 0; //报警 开
LCD_Init(); //初始化液晶
DelayMs(100); //延时有助于稳定
LCD_Clear();
BUZZER = 1; //报警 关
PcdReset(); //复位RC522
PcdAntennaOn(); //开启天线发射
sprintf(dis0, "ZS:%c LS:%c WE:%c ", zsFlag, lsFlag, weFlag); //打印数据
LCD_DispStr(0, 0, dis0); //显示第二行
while (1) //主循环
{
if (PcdRequest(0x52, Temp) == MI_OK) //检测到卡
{
DelayS(1);
if (PcdRequest(0x52, Temp) == MI_OK) //1S后仍然检测到卡
{
if (PcdAnticoll(UID) == MI_OK) //读取卡号成功
{
UART_SendByte(0x00); //串口发送卡号
UART_SendStr(UID, 4);
UART_SendByte(0x00);
if ((UID[0] == zsID[0]) && (UID[1] == zsID[1])) //张三 到
{
if (zsFlag != 0xff) //第一次刷到该卡
{
zsFlag = 0xff; //显示 到
manNum++;
}
else
{
zsFlag = ' '; //显示 离开
manNum--;
}
time_20ms = 8;
BUZZER = 0; //蜂鸣器短暂鸣叫
}
else if ((UID[0] == lsID[0]) && (UID[1] == lsID[1])) //李四 到
{
if (lsFlag != 0xff) //第一次刷到该卡
{
lsFlag = 0xff; //显示 到
manNum++;
}
else
{
lsFlag = ' '; //显示 离开
manNum--;
}
time_20ms = 8;
BUZZER = 0; //蜂鸣器短暂鸣叫
}
else if ((UID[0] == weID[0]) && (UID[1] == weID[1])) //李四 到
{
if (weFlag != 0xff) //第一次刷到该卡
{
weFlag = 0xff; //显示 到
manNum++;
}
else
{
weFlag = ' '; //显示 离开
manNum--;
}
time_20ms = 8;
BUZZER = 0; //蜂鸣器短暂鸣叫
}
}
}
}
if (disFlag == 1)
{
sprintf(dis0, "ZS:%c LS:%c WE:%c ", zsFlag, lsFlag, weFlag); //打印数据
LCD_DispStr(0, 0, dis0); //显示第二行
sprintf(dis1, "Total: %d ", (int)manNum); //打印数据
LCD_DispStr(0, 1, dis1); //显示第二行
disFlag = 0;
}
if (KEY_CHECK == 0) //按键按下
{
DelayMs(10);
if (KEY_CHECK == 0 && rekey == 0) //按键按下
{
rekey = 1;
if (manNum < 3) //人数不够
{
buzFlag = ~buzFlag; //蜂鸣器报警标志
}
else
{
buzFlag = 0;
}
}
}
else
{
rekey = 0;
}
}
}
void Timer0_Init(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0 = (65536 - 18432) / 256; //重新赋值 20ms
TL0 = (65536 - 18432) % 256;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}
void Timer0_Interrupt(void) interrupt 1
{
TH0 = (65536 - 18432) / 256; //重新赋值 20ms
TL0 = (65536 - 18432) % 256;
time_20ms++;
if (time_20ms % 10 == 0) //定时显示
{
disFlag = 1;
DelayMs(150);
if (buzFlag == 1)
BUZZER = !BUZZER; //蜂鸣器报警
else
BUZZER = 1; //不报警
}
}
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TL1 = TH1;
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 0; //关闭串口中断
}
void UART_SendByte(unsigned char dat)
{
unsigned char time_out;
time_out = 0x00;
SBUF = dat; //将数据放入SBUF中
while ((!TI) && (time_out < 100)) //检测是否发送出去
{
time_out++;
DelayUs10x(2);
} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
void UART_SendStr(unsigned char *s, unsigned char length)
{
unsigned char cnt;
cnt = 0x00;
while (cnt < length) //发送长度对比
{
UART_SendByte(*s); //放松单字节数据
s++; //指针++
cnt++; //下一个++
}
}
// void UART_Interrupt(void) interrupt 4 //串行中断服务程序
// {
// if (RI) //判断是接收中断产生
// {
// RI = 0; //标志位清零
// }
// if (TI) //如果是发送标志位,清零
// TI = 0;
// }