找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 138|回复: 0
收起左侧

有没有大佬给我指教一下 我想把这存储id卡变为可以动态存储,可以通过串口添加删除卡

[复制链接]
ID:1154560 发表于 2025-6-21 16:01 | 显示全部楼层 |阅读模式
我想把这存储id卡变为可以动态存储,可以通过串口添加删除卡,我尝试了好几次都没有解决不是报错就是下载程序lcd无反应串口卡住了,下面是我的源码
  1. #include <reg52.h>
  2. #include "lcd1602.h"
  3. #include "mfrc522.h"
  4. #include "uart.h"
  5. #include <stdio.h>
  6. // 系统时钟频率(Hz),用于计算延时
  7. #define FOSC 11059200
  8. // 定义蜂鸣器控制端口
  9. sbit BUZZER = P3^6;
  10. // 定义系统状态
  11. #define SYSTEM_IDLE       0  // 空闲状态
  12. #define SYSTEM_SUCCESS    1  // 签到成功状态
  13. #define SYSTEM_FAILURE    2  // 签到失败状态
  14. // 定义卡片数量
  15. #define CARD_COUNT 3


  16. // 学生信息结构体定义
  17. typedef struct {
  18.     unsigned char card_id[4];    // 卡片ID
  19.     unsigned char student_id[10]; // 学生学号
  20.     unsigned char name[20];      // 学生姓名
  21. } StudentInfo;

  22. // 预定义学生信息 (3名学生)
  23. StudentInfo students[3] = {
  24.     {{0xE4, 0xCA, 0x18, 0x05}, "2501", "张三"},
  25.     {{0x16, 0x41, 0xC0, 0x01}, "2502", "李四"},
  26.     {{0x70, 0x02, 0x53, 0xF4}, "2503", "王五"},

  27. };

  28. volatile unsigned char systemState = SYSTEM_IDLE;
  29. volatile unsigned int displayTimer = 0;  // 显示计时器

  30. // 定义卡片数据缓冲区
  31. unsigned char card_data[16];
  32. unsigned char current_card_id[4];
  33. unsigned char display_card_id_str[13];  // 显示用卡号字符串

  34. // 存储当前学生信息
  35. unsigned char current_student_id[10];   // 当前学生学号
  36. unsigned char current_student_name[20]; // 当前学生姓名

  37. // 蜂鸣器状态定义
  38. #define BEEP_IDLE   0  // 空闲状态
  39. #define BEEP_ON     1  // 蜂鸣器开启
  40. #define BEEP_OFF    2  // 蜂鸣器关闭
  41. volatile unsigned char beepState = BEEP_IDLE;  // 蜂鸣器状态
  42. volatile unsigned char beepCount = 0;         // 剩余鸣叫次数
  43. volatile unsigned int beepTimer = 0;          // 计时计数器

  44. // 蜂鸣器发声函数 - 成功时短鸣
  45. void beep_success(void) {
  46.     unsigned int i, j;
  47.     for(i = 0; i < 1000; i++) {
  48.         BUZZER = ~BUZZER;
  49.         for(j = 0; j < 30; j++);  // 约0.5ms延时,1000次约500ms
  50.     }
  51.     BUZZER = 0;  // 确保蜂鸣器最终关闭
  52. }

  53. //蜂鸣器失败提示音 - 短鸣三声
  54. void beep_failure(void) {
  55.     if(beepState == BEEP_IDLE) {  // 仅在空闲状态下启动
  56.         beepState = BEEP_ON;       // 切换到开启状态
  57.         beepCount = 3;             // 设置鸣响3次
  58.         beepTimer = 500;           // 首次鸣响500ms
  59.     }
  60. }

  61. // 蜂鸣器任务
  62. void beepTask(void) {
  63.     static unsigned int beepCounter = 0;  // 新增计数器,跟踪精确计时
  64.    
  65.     // 如果处于空闲状态,直接返回,不执行任何操作
  66.     if(beepState == BEEP_IDLE) {
  67.         return;
  68.     }
  69.    
  70.     switch(beepState) {
  71.         case BEEP_ON:
  72.             BUZZER = ~BUZZER;  // 翻转电平发声
  73.             
  74.             // 精确计时控制
  75.             if(++beepCounter >= 200) {  // 500次计数约500ms
  76.                 beepCounter = 0;
  77.                 BUZZER = 0;                // 关闭蜂鸣器
  78.                
  79.                 // 检查是否为最后一声
  80.                 if(beepCount == 1) {
  81.                     beepState = BEEP_IDLE; // 最后一声后直接进入空闲状态
  82.                     BUZZER = 0;            // 双重确保蜂鸣器关闭
  83.                 } else {
  84.                     beepState = BEEP_OFF;  // 否则进入间隔状态
  85.                     beepTimer = 300;       // 间隔300ms
  86.                 }
  87.             }
  88.             break;
  89.             
  90.         case BEEP_OFF:
  91.             if(++beepCounter >= 300) {  // 300次计数约300ms
  92.                 beepCounter = 0;
  93.                 beepCount--;                 // 剩余次数减1
  94.                 beepState = BEEP_ON;         // 继续鸣响
  95.                 beepTimer = 500;             // 鸣响500ms
  96.             }
  97.             break;
  98.             
  99.         default:
  100.             beepCounter = 0;  // 重置计数器
  101.             beepState = BEEP_IDLE;
  102.             BUZZER = 0;       // 确保蜂鸣器关闭
  103.             break;
  104.     }
  105. }

  106. // 显示欢迎信息
  107. void display_welcome(void) {
  108.     LCDInit();
  109.     DisplayListChar(0, 0, "Student Attend");
  110.     DisplayListChar(0, 1, "Place Card Here");
  111. }

  112. // 显示状态处理函数
  113. void displayTask(void) {
  114.     switch(systemState) {
  115.         case SYSTEM_SUCCESS:
  116.             if(displayTimer > 0) {
  117.                 displayTimer--;
  118.             } else {
  119.                 systemState = SYSTEM_IDLE;
  120.                 display_welcome();
  121.             }
  122.             break;
  123.             
  124.         case SYSTEM_FAILURE:
  125.             if(displayTimer > 0) {
  126.                 displayTimer--;
  127.             } else {
  128.                 systemState = SYSTEM_IDLE;
  129.                 display_welcome();
  130.             }
  131.             break;
  132.             
  133.         default: break;
  134.     }
  135. }

  136. // 查找学生信息
  137. bit find_student_info(unsigned char *card_id) {
  138.     unsigned char i, j;
  139.    
  140.     // 遍历所有学生信息
  141.     for(i = 0; i < CARD_COUNT; i++) {
  142.         // 逐个字节比较卡号
  143.         for(j = 0; j < 4; j++) {
  144.             if(card_id[j] != students[i].card_id[j]) {
  145.                 break;
  146.             }
  147.         }
  148.         
  149.         // 如果4个字节都匹配,找到学生信息
  150.         if(j == 4) {
  151.             // 复制学生ID和姓名
  152.             for(j = 0; j < 10 && students[i].student_id[j] != '\0'; j++) {
  153.                 current_student_id[j] = students[i].student_id[j];
  154.             }
  155.             current_student_id[j] = '\0';
  156.             
  157.             for(j = 0; j < 20 && students[i].name[j] != '\0'; j++) {
  158.                 current_student_name[j] = students[i].name[j];
  159.             }
  160.             current_student_name[j] = '\0';
  161.             
  162.             return 1;
  163.         }
  164.     }
  165.    
  166.     // 未找到匹配的学生信息
  167.     return 0;
  168. }

  169. // 显示签到成功信息
  170. void display_success(unsigned char *card_id) {
  171.     unsigned char i, j;
  172.    
  173.     // 转换卡号为字符串(保持LCD显示不变)
  174.     j = 0;
  175.     for(i = 0; i < 4; i++) {
  176.         display_card_id_str[j++] = (card_id[i] >> 4) + ((card_id[i] >> 4) < 10 ? '0' : 'A' - 10);
  177.         display_card_id_str[j++] = (card_id[i] & 0x0F) + ((card_id[i] & 0x0F) < 10 ? '0' : 'A' - 10);
  178.         display_card_id_str[j++] = ' ';
  179.     }
  180.     display_card_id_str[j] = '\0';
  181.    
  182.     // 发出成功提示音
  183.     beep_success();
  184.    
  185.     // 设置显示状态
  186.     LCDInit();
  187.     DisplayListChar(0, 0, "Attend Success!");
  188.     DisplayListChar(0, 1, display_card_id_str);
  189.    
  190.     systemState = SYSTEM_SUCCESS;
  191.     displayTimer = 5000;  // 5000个滴答 = 约5秒
  192.    
  193.     // 查找学生信息
  194.     if(find_student_info(card_id)) {
  195.         // 通过串口发送学生信息
  196.         Uart_Send_String("签到成功 - ");
  197.         Uart_Send_String("学号: ");
  198.         Uart_Send_String(current_student_id);
  199.         Uart_Send_String(" 姓名: ");
  200.         Uart_Send_String(current_student_name);
  201.         Uart_Send_String("\r\n");
  202.     } else {
  203.         // 未找到学生信息,发送卡号
  204.         Uart_Send_String("签到成功 - 卡号: ");
  205.         for(i = 0; i < 4; i++) {
  206.             Sent_UART((card_id[i] >> 4) + ((card_id[i] >> 4) < 10 ? '0' : 'A' - 10));
  207.             Sent_UART((card_id[i] & 0x0F) + ((card_id[i] & 0x0F) < 10 ? '0' : 'A' - 10));
  208.             Sent_UART(' ');
  209.         }
  210.         Sent_UART('\r');
  211.         Sent_UART('\n');
  212.     }
  213. }

  214. // 显示签到失败信息
  215. void display_failure(unsigned char *card_id) {
  216.     unsigned char i, j;
  217.    
  218.     // 转换卡号为字符串
  219.     j = 0;
  220.     for(i = 0; i < 4; i++) {
  221.         display_card_id_str[j++] = (card_id[i] >> 4) + ((card_id[i] >> 4) < 10 ? '0' : 'A' - 10);
  222.         display_card_id_str[j++] = (card_id[i] & 0x0F) + ((card_id[i] & 0x0F) < 10 ? '0' : 'A' - 10);
  223.         display_card_id_str[j++] = ' ';
  224.     }
  225.     display_card_id_str[j] = '\0';
  226.    
  227.     // 发出失败提示音
  228.     beep_failure();
  229.    
  230.     // 设置显示状态
  231.     LCDInit();
  232.     DisplayListChar(0, 0, "Invalid Card!");
  233.     DisplayListChar(0, 1, display_card_id_str);
  234.    
  235.     systemState = SYSTEM_FAILURE;
  236.     displayTimer = 5000;  // 5000个滴答 = 约5秒
  237.    
  238.     // 通过串口发送未授权卡片信息
  239.     Uart_Send_String("未授权卡片 - 卡号: ");
  240.     for(i = 0; i < 4; i++) {
  241.         Sent_UART((card_id[i] >> 4) + ((card_id[i] >> 4) < 10 ? '0' : 'A' - 10));
  242.         Sent_UART((card_id[i] & 0x0F) + ((card_id[i] & 0x0F) < 10 ? '0' : 'A' - 10));
  243.         Sent_UART(' ');
  244.     }
  245.     Sent_UART('\r');
  246.     Sent_UART('\n');
  247. }

  248. // 核对卡片ID是否ok
  249. bit check_card_id(unsigned char *card_id) {
  250.     unsigned char i, j;
  251.    
  252.     // 遍历所有学生信息
  253.     for(i = 0; i < CARD_COUNT; i++) {
  254.         // 逐个字节比较卡号
  255.         for(j = 0; j < 4; j++) {
  256.             if(card_id[j] != students[i].card_id[j]) {
  257.                 break;
  258.             }
  259.         }
  260.         
  261.         // 如果4个字节都匹配,返回ok
  262.         if(j == 4) {
  263.             return 1;
  264.         }
  265.     }
  266.    
  267.     // 未找到匹配的卡片,返回不ok
  268.     return 0;
  269. }

  270. // 主函数
  271. void main(void) {
  272.     unsigned char card_detected = 0;
  273.    
  274.     // 初始化系统
  275.     PcdReset();         // 初始化RC522
  276.     Uart_Init();        // 初始化串口
  277.     LCDInit();          // 初始化LCD
  278.     BUZZER = 0;         // 初始化蜂鸣器端口
  279.     // 串口提示系统启动
  280.     Uart_Send_String("RFID Attendance System Started\r\n");
  281.    
  282.     display_welcome();  // 显示欢迎信息
  283.    
  284.     while(1) {
  285.         // 处理蜂鸣器状态
  286.         beepTask();
  287.         
  288.         // 处理显示状态
  289.         displayTask();
  290.         
  291.         // 检测卡片(仅在空闲状态下检测)
  292.         if(systemState == SYSTEM_IDLE &&
  293.            PcdRequest(PICC_REQIDL, &card_data[0]) == MI_OK) {
  294.             // 防冲突,获取卡片序列号
  295.             if(PcdAnticoll(current_card_id) == MI_OK) {
  296.                 // 选卡
  297.                 if(PcdSelect(current_card_id) == MI_OK) {
  298.                     card_detected = 1;
  299.                     
  300.                     // 核对卡片ID
  301.                     if(check_card_id(current_card_id)) {
  302.                         // ok卡片,显示签到成功
  303.                         display_success(current_card_id);
  304.                     } else {
  305.                         // 不ok卡片,显示失败
  306.                         display_failure(current_card_id);
  307.                     }
  308.                     
  309.                     // 让卡片进入休眠状态
  310.                     PcdHalt();
  311.                 }
  312.             }
  313.         }
  314.         
  315.         // 延时降低CPU使用率(精确延时)
  316.         delay_ms(1);  // 1ms延时,提高响应速度
  317.     }
  318. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表