T039基于51单片机射频RFID卡考勤人数计数系统设计原理图PCB

功能:
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;
// }

实物演示视频:
https://www.bilibili.com/video/BV1gG4y157yg/

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值