STM32技术打造:智能考勤打卡系统 | 刷卡式上下班签到自动化解决方案

文章目录


哔哩哔哩:
https://www.bilibili.com/video/BV1NZ421Y79W/?spm_id_from=333.999.0.0&vd_source=e5082ef80535e952b2a4301746491be0

一、简易刷卡式打卡考勤系统

(一)功能简介

1、材料:STM32F103C8T6、MFR522、O.96寸OLED、4个按键

2、功能:

①初始化管理员卡片,请放入管理员卡片

②进入管理界面,按键可以选择录入新员工、删除员工、更换管理员卡片、设置时间、设置上下班时间、查看考勤信息、恢复出厂设置等功能

③管理界面可以查看考勤信息

④退出管理界面后到正常界面,正常界面显示时间,有员工刷卡显示"员工X 早上好\中午好\下午好\晚上好\辛苦了"等字样

原理图设计

采用最普遍的STM32F103C8T6便宜好用又稳定

下载接口用排针

这次用TYPEC来供电5V,一看充电器9V12V不要慌,接上没带协议的设备是通通都5V。只要能接就不会爆炸。

5V转3.3降压采用降压芯片AMS1117C33电流大稳定可靠

用RFID射频卡来刷卡打卡

采用7针SPI OLED显示 ,屏幕是单色128*64分辨率

按键用来设置信息

蜂鸣器用来提示打卡成功或者失败

程序设计

这段代码是主程序,包含了初始化和主循环部分。在初始化部分,

程序设置了延时函数、NVIC中断分组、串口、OLED显示屏、蜂鸣器和实时时钟(RTC)。

主循环中,程序根据系统标志位sysFlag.DisMain的值来执行不同的任务,如锁定界面、

管理员界面和解锁界面的任务。

c 复制代码
#include "main.h"  // 包含主程序的头文件
#include <string.h>  // 包含字符串处理函数

// 系统参数结构体
SysTemPat sys;
// 系统标志位定义
SysflagTypedef sysFlag;

// 函数声明
void Display_Data(void);  // 显示时间的函数
void starting(void);     // 开机界面信息的函数
u8 MFRC522_lock(void);   // 刷卡功能的函数
u8 Add_Rfid(void);      // 录入RFID的函数
u8 Delt_Rfid(void);     // 删除RFID的函数
void Set_Time(void);     // 设置时间的函数
void Massige(void);      // 信息提示的函数
void SysPartInit(void);  // 系统参数初始化的函数

// 主函数
int main(void)
{
    //初始化延时函数
    delay_init();     
    // 设置NVIC中断分组为2:2位抢占优先级,2位响应优先级
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
    // 初始化串口,波特率为115200
    uart_init(115200);	printf("串口功能正常\r\n"); 
    // 初始化按键
	KEY_Init();
    // 初始化OLED显示屏
    OLED_Init();  
    // 清除OLED显示屏
    OLED_Clear();  
    // 初始化蜂鸣器
    BEEP_Init();    
    // 显示开机信息
    starting();
    // 初始化RTC(实时时钟)
    RTC_Init();
    // 初始化系统参数
    SysPartInit();   
    // 主循环
    while(1)
    {
        // 根据系统标志位sysFlag.DisMain的值执行不同的任务
        switch(sysFlag.DisMain)
        {
            case DIS_MAIN:   main_task();  break;  // 执行锁定界面任务
            case DIS_MANAGE: manage_task();  break;  // 执行管理员界面任务
            case DIS_INFO:   info_task();  break;  // 执行解锁界面任务
        }
    }
}

使用删除数组并前移的方式来删除指定的员工

c 复制代码
// 删除数组中的指定元素,并将后续元素前移
void deleteAndShift_card(int indexToDelete) {
    int i, j;
    if (indexToDelete >= 0 && indexToDelete <= sys.userNum) {
        // 从要删除的元素开始,将后续元素前移
        for ( i = indexToDelete; i < sys.userNum; i++) {
            memcpy(sys.cardid[i],sys.cardid[i+1],5);
        }
    } else {
        printf("索引无效。\n");
    }
}
// 删除数组中的指定元素,并将后续元素前移
void deleteAndShift_user(int indexToDelete) {
    int i, j;
    if (indexToDelete >= 0 && indexToDelete <= sys.userNum) {
        // 从要删除的元素开始,将后续元素前移
        for ( i = indexToDelete; i < sys.userNum; i++) {
            memcpy(&sys.user[i],&sys.user[i+1],sizeof(sys.user[0]));
        }
    } else {
        printf("索引无效。\n");
    }
}

主界面显示任务

c 复制代码
void main_task(void)
{
#define DATA_TIME 100
#define KEY_TIME 10
#define RC522_TIME 300

    static u32 scan_time = 0;

    u8 key_num;

    scan_time++; //扫描计数

    if(scan_time % DATA_TIME == 1) {
        Display_Data();//时间显示:每1000ms更新一次显示数据
        if(sysFlag.DisFlag == 1)
        {
            sysFlag.DisFlag = 0;
            OLED_Refresh_Gram();//更新显示
        }
    }
    //MFRC522解锁
    if(scan_time % RC522_TIME == 1) {
        u8 ret =  MFRC522_lock();
        if(ret == 0)//MFRC522解锁
        {
            sysFlag.DisMain = DIS_MANAGE; //跳到管理界面
        }
    }

    key_num = KEY_Scan(0);
    if(key_num)
    {
        dis_info((u8*)"请刷卡打卡!",3000);
    }
    delay_ms(1);
}

管理员模式任务

c 复制代码
void manage_task(void)
{
    static char arrow = 0; //箭头位子
    static u32 scan_time = 0;
    static u8 dis_first = 1;
    u8 key_num = 0;
    if(dis_first)
    {
        dis_first = 0;
        OLED_Clear_NOupdate();
        Dis_SysSetup(arrow);
    }
    //超时
    scan_time++;
    //功能选项选择
    key_num = KEY_Scan(0);
    if(scan_time > 30000 | key_num == KEY2_PRES) {
        scan_time = 0;
        sysFlag.DisMain = DIS_MAIN; //跳到锁定界面
        dis_first = 1;
    }
    if(key_num)
    {
        scan_time = 0;
        if(key_num == KEY0_PRES) {
            if(arrow > 0)arrow--;
        }
        if(key_num == KEY1_PRES) {
            if(arrow < MAX_SYS_PARA_NUM - 1)arrow++;
        }
        Dis_SysSetup(arrow);
        if(key_num == KEY3_PRES) {
            switch(arrow)
            {
            case ADD_RFID:
                Add_Rfid();
                break;//录入新员工
            case DEL_RFID:
                Delt_Rfid();
                break;//删除员工
            case MOD_MANG_PSWD:
                SetManage();
                break;//更换管理员卡片
            case MOD_TIMES:
                Set_Time();
                break;//设置时
            case MOD_WORK_TIMES:
                Set_WorkTime();
                break;  //设置上下班时间
            case READ_SYS_INFO:
                //查看考勤信息
                Read_ColokinInfo();
                break;
            case FACTORY_RESET:
                //恢复出厂设置
                set_facory_reset();
                break;
            }
            dis_first = 1;
        }
    }
    delay_ms(1);
}

系统参数结构体

c 复制代码
typedef struct 
{
	u32 HZCFlag;
	u8  cardid[MAXRFIDNUM][CARID_LENGTH];
	u8  errCnt;//错误计数
	u8  errTime;//等待错误时间
    u16  userNum;//员工人数
    _time_obj sb_time;	//上班时间
    _time_obj xb_time;  //下班时间
	_user_obj user[MAXRFIDNUM];		
}SysTemPat;
相关推荐
King's King5 小时前
自动化立体仓库出入库能力及堆垛机节拍
运维·自动化
yumuing blog6 小时前
【论文解读】AGENTLESS:揭开基于LLM的软件工程代理的神秘面纱,重塑软件工程自动化新基线
运维·自动化·软件工程·llama
远望创客学堂6 小时前
【单片机毕业设计选题24047】-基于阿里云的工地环境监测系统
stm32·单片机·嵌入式硬件·阿里云·云计算·课程设计·arduino
极客小张7 小时前
利用 STM32 实现多协议物联网网关:Modbus/Zigbee 到以太网/Wi-Fi 的数据桥接
stm32·单片机·嵌入式硬件·物联网·网络协议·https·硬件工程
FPGAmaster创新者7 小时前
基于AGX ORIN与FPGA K7实现PCIE高速数据通信/Orin与FPGA高速数据传输/XDMA在linux系统使用教程
linux·嵌入式硬件·fpga开发
maybe_YX8 小时前
51单片机基础8——单片机控制超声波模块
c语言·单片机·嵌入式硬件·51单片机
@一二三四五8 小时前
STM32 看门狗 HAL
stm32·单片机·嵌入式硬件
北京迅为8 小时前
【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第一篇 嵌入式Linux入门篇-第四章 Ubuntu启用root用户
linux·嵌入式硬件
maybe_YX9 小时前
51单片机基础10——串口实验
c语言·单片机·嵌入式硬件·51单片机
Qingniu0110 小时前
开关电源的电路组成原理
单片机·嵌入式硬件·新能源·电源模块·无刷电机