我想把这存储id卡变为可以动态存储,可以通过串口添加删除卡,我尝试了好几次都没有解决不是报错就是下载程序lcd无反应串口卡住了,下面是我的源码
- #include <reg52.h>
- #include "lcd1602.h"
- #include "mfrc522.h"
- #include "uart.h"
- #include <stdio.h>
- // 系统时钟频率(Hz),用于计算延时
- #define FOSC 11059200
- // 定义蜂鸣器控制端口
- sbit BUZZER = P3^6;
- // 定义系统状态
- #define SYSTEM_IDLE 0 // 空闲状态
- #define SYSTEM_SUCCESS 1 // 签到成功状态
- #define SYSTEM_FAILURE 2 // 签到失败状态
- // 定义卡片数量
- #define CARD_COUNT 3
- // 学生信息结构体定义
- typedef struct {
- unsigned char card_id[4]; // 卡片ID
- unsigned char student_id[10]; // 学生学号
- unsigned char name[20]; // 学生姓名
- } StudentInfo;
- // 预定义学生信息 (3名学生)
- StudentInfo students[3] = {
- {{0xE4, 0xCA, 0x18, 0x05}, "2501", "张三"},
- {{0x16, 0x41, 0xC0, 0x01}, "2502", "李四"},
- {{0x70, 0x02, 0x53, 0xF4}, "2503", "王五"},
- };
- volatile unsigned char systemState = SYSTEM_IDLE;
- volatile unsigned int displayTimer = 0; // 显示计时器
- // 定义卡片数据缓冲区
- unsigned char card_data[16];
- unsigned char current_card_id[4];
- unsigned char display_card_id_str[13]; // 显示用卡号字符串
- // 存储当前学生信息
- unsigned char current_student_id[10]; // 当前学生学号
- unsigned char current_student_name[20]; // 当前学生姓名
- // 蜂鸣器状态定义
- #define BEEP_IDLE 0 // 空闲状态
- #define BEEP_ON 1 // 蜂鸣器开启
- #define BEEP_OFF 2 // 蜂鸣器关闭
- volatile unsigned char beepState = BEEP_IDLE; // 蜂鸣器状态
- volatile unsigned char beepCount = 0; // 剩余鸣叫次数
- volatile unsigned int beepTimer = 0; // 计时计数器
- // 蜂鸣器发声函数 - 成功时短鸣
- void beep_success(void) {
- unsigned int i, j;
- for(i = 0; i < 1000; i++) {
- BUZZER = ~BUZZER;
- for(j = 0; j < 30; j++); // 约0.5ms延时,1000次约500ms
- }
- BUZZER = 0; // 确保蜂鸣器最终关闭
- }
- //蜂鸣器失败提示音 - 短鸣三声
- void beep_failure(void) {
- if(beepState == BEEP_IDLE) { // 仅在空闲状态下启动
- beepState = BEEP_ON; // 切换到开启状态
- beepCount = 3; // 设置鸣响3次
- beepTimer = 500; // 首次鸣响500ms
- }
- }
- // 蜂鸣器任务
- void beepTask(void) {
- static unsigned int beepCounter = 0; // 新增计数器,跟踪精确计时
-
- // 如果处于空闲状态,直接返回,不执行任何操作
- if(beepState == BEEP_IDLE) {
- return;
- }
-
- switch(beepState) {
- case BEEP_ON:
- BUZZER = ~BUZZER; // 翻转电平发声
-
- // 精确计时控制
- if(++beepCounter >= 200) { // 500次计数约500ms
- beepCounter = 0;
- BUZZER = 0; // 关闭蜂鸣器
-
- // 检查是否为最后一声
- if(beepCount == 1) {
- beepState = BEEP_IDLE; // 最后一声后直接进入空闲状态
- BUZZER = 0; // 双重确保蜂鸣器关闭
- } else {
- beepState = BEEP_OFF; // 否则进入间隔状态
- beepTimer = 300; // 间隔300ms
- }
- }
- break;
-
- case BEEP_OFF:
- if(++beepCounter >= 300) { // 300次计数约300ms
- beepCounter = 0;
- beepCount--; // 剩余次数减1
- beepState = BEEP_ON; // 继续鸣响
- beepTimer = 500; // 鸣响500ms
- }
- break;
-
- default:
- beepCounter = 0; // 重置计数器
- beepState = BEEP_IDLE;
- BUZZER = 0; // 确保蜂鸣器关闭
- break;
- }
- }
- // 显示欢迎信息
- void display_welcome(void) {
- LCDInit();
- DisplayListChar(0, 0, "Student Attend");
- DisplayListChar(0, 1, "Place Card Here");
- }
- // 显示状态处理函数
- void displayTask(void) {
- switch(systemState) {
- case SYSTEM_SUCCESS:
- if(displayTimer > 0) {
- displayTimer--;
- } else {
- systemState = SYSTEM_IDLE;
- display_welcome();
- }
- break;
-
- case SYSTEM_FAILURE:
- if(displayTimer > 0) {
- displayTimer--;
- } else {
- systemState = SYSTEM_IDLE;
- display_welcome();
- }
- break;
-
- default: break;
- }
- }
- // 查找学生信息
- bit find_student_info(unsigned char *card_id) {
- unsigned char i, j;
-
- // 遍历所有学生信息
- for(i = 0; i < CARD_COUNT; i++) {
- // 逐个字节比较卡号
- for(j = 0; j < 4; j++) {
- if(card_id[j] != students[i].card_id[j]) {
- break;
- }
- }
-
- // 如果4个字节都匹配,找到学生信息
- if(j == 4) {
- // 复制学生ID和姓名
- for(j = 0; j < 10 && students[i].student_id[j] != '\0'; j++) {
- current_student_id[j] = students[i].student_id[j];
- }
- current_student_id[j] = '\0';
-
- for(j = 0; j < 20 && students[i].name[j] != '\0'; j++) {
- current_student_name[j] = students[i].name[j];
- }
- current_student_name[j] = '\0';
-
- return 1;
- }
- }
-
- // 未找到匹配的学生信息
- return 0;
- }
- // 显示签到成功信息
- void display_success(unsigned char *card_id) {
- unsigned char i, j;
-
- // 转换卡号为字符串(保持LCD显示不变)
- j = 0;
- for(i = 0; i < 4; i++) {
- display_card_id_str[j++] = (card_id[i] >> 4) + ((card_id[i] >> 4) < 10 ? '0' : 'A' - 10);
- display_card_id_str[j++] = (card_id[i] & 0x0F) + ((card_id[i] & 0x0F) < 10 ? '0' : 'A' - 10);
- display_card_id_str[j++] = ' ';
- }
- display_card_id_str[j] = '\0';
-
- // 发出成功提示音
- beep_success();
-
- // 设置显示状态
- LCDInit();
- DisplayListChar(0, 0, "Attend Success!");
- DisplayListChar(0, 1, display_card_id_str);
-
- systemState = SYSTEM_SUCCESS;
- displayTimer = 5000; // 5000个滴答 = 约5秒
-
- // 查找学生信息
- if(find_student_info(card_id)) {
- // 通过串口发送学生信息
- Uart_Send_String("签到成功 - ");
- Uart_Send_String("学号: ");
- Uart_Send_String(current_student_id);
- Uart_Send_String(" 姓名: ");
- Uart_Send_String(current_student_name);
- Uart_Send_String("\r\n");
- } else {
- // 未找到学生信息,发送卡号
- Uart_Send_String("签到成功 - 卡号: ");
- for(i = 0; i < 4; i++) {
- Sent_UART((card_id[i] >> 4) + ((card_id[i] >> 4) < 10 ? '0' : 'A' - 10));
- Sent_UART((card_id[i] & 0x0F) + ((card_id[i] & 0x0F) < 10 ? '0' : 'A' - 10));
- Sent_UART(' ');
- }
- Sent_UART('\r');
- Sent_UART('\n');
- }
- }
- // 显示签到失败信息
- void display_failure(unsigned char *card_id) {
- unsigned char i, j;
-
- // 转换卡号为字符串
- j = 0;
- for(i = 0; i < 4; i++) {
- display_card_id_str[j++] = (card_id[i] >> 4) + ((card_id[i] >> 4) < 10 ? '0' : 'A' - 10);
- display_card_id_str[j++] = (card_id[i] & 0x0F) + ((card_id[i] & 0x0F) < 10 ? '0' : 'A' - 10);
- display_card_id_str[j++] = ' ';
- }
- display_card_id_str[j] = '\0';
-
- // 发出失败提示音
- beep_failure();
-
- // 设置显示状态
- LCDInit();
- DisplayListChar(0, 0, "Invalid Card!");
- DisplayListChar(0, 1, display_card_id_str);
-
- systemState = SYSTEM_FAILURE;
- displayTimer = 5000; // 5000个滴答 = 约5秒
-
- // 通过串口发送未授权卡片信息
- Uart_Send_String("未授权卡片 - 卡号: ");
- for(i = 0; i < 4; i++) {
- Sent_UART((card_id[i] >> 4) + ((card_id[i] >> 4) < 10 ? '0' : 'A' - 10));
- Sent_UART((card_id[i] & 0x0F) + ((card_id[i] & 0x0F) < 10 ? '0' : 'A' - 10));
- Sent_UART(' ');
- }
- Sent_UART('\r');
- Sent_UART('\n');
- }
- // 核对卡片ID是否ok
- bit check_card_id(unsigned char *card_id) {
- unsigned char i, j;
-
- // 遍历所有学生信息
- for(i = 0; i < CARD_COUNT; i++) {
- // 逐个字节比较卡号
- for(j = 0; j < 4; j++) {
- if(card_id[j] != students[i].card_id[j]) {
- break;
- }
- }
-
- // 如果4个字节都匹配,返回ok
- if(j == 4) {
- return 1;
- }
- }
-
- // 未找到匹配的卡片,返回不ok
- return 0;
- }
- // 主函数
- void main(void) {
- unsigned char card_detected = 0;
-
- // 初始化系统
- PcdReset(); // 初始化RC522
- Uart_Init(); // 初始化串口
- LCDInit(); // 初始化LCD
- BUZZER = 0; // 初始化蜂鸣器端口
- // 串口提示系统启动
- Uart_Send_String("RFID Attendance System Started\r\n");
-
- display_welcome(); // 显示欢迎信息
-
- while(1) {
- // 处理蜂鸣器状态
- beepTask();
-
- // 处理显示状态
- displayTask();
-
- // 检测卡片(仅在空闲状态下检测)
- if(systemState == SYSTEM_IDLE &&
- PcdRequest(PICC_REQIDL, &card_data[0]) == MI_OK) {
- // 防冲突,获取卡片序列号
- if(PcdAnticoll(current_card_id) == MI_OK) {
- // 选卡
- if(PcdSelect(current_card_id) == MI_OK) {
- card_detected = 1;
-
- // 核对卡片ID
- if(check_card_id(current_card_id)) {
- // ok卡片,显示签到成功
- display_success(current_card_id);
- } else {
- // 不ok卡片,显示失败
- display_failure(current_card_id);
- }
-
- // 让卡片进入休眠状态
- PcdHalt();
- }
- }
- }
-
- // 延时降低CPU使用率(精确延时)
- delay_ms(1); // 1ms延时,提高响应速度
- }
- }
复制代码 |