找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 53|回復: 0
打印 上一主題 下一主題
收起左側

有沒有大佬給我指教一下 我想把這存儲id卡變?yōu)榭梢詣討B(tài)存儲,可以通過串口添加刪除卡

[復制鏈接]
跳轉到指定樓層
樓主
ID:1154560 發(fā)表于 2025-6-21 16:01 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
我想把這存儲id卡變?yōu)榭梢詣討B(tài)存儲,可以通過串口添加刪除卡,我嘗試了好幾次都沒有解決不是報錯就是下載程序lcd無反應串口卡住了,下面是我的源碼
  1. #include <reg52.h>
  2. #include "lcd1602.h"
  3. #include "mfrc522.h"
  4. #include "uart.h"
  5. #include <stdio.h>
  6. // 系統(tǒng)時鐘頻率(Hz),用于計算延時
  7. #define FOSC 11059200
  8. // 定義蜂鳴器控制端口
  9. sbit BUZZER = P3^6;
  10. // 定義系統(tǒng)狀態(tài)
  11. #define SYSTEM_IDLE       0  // 空閑狀態(tài)
  12. #define SYSTEM_SUCCESS    1  // 簽到成功狀態(tài)
  13. #define SYSTEM_FAILURE    2  // 簽到失敗狀態(tài)
  14. // 定義卡片數(shù)量
  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. // 定義卡片數(shù)據(jù)緩沖區(qū)
  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. // 蜂鳴器狀態(tài)定義
  38. #define BEEP_IDLE   0  // 空閑狀態(tài)
  39. #define BEEP_ON     1  // 蜂鳴器開啟
  40. #define BEEP_OFF    2  // 蜂鳴器關閉
  41. volatile unsigned char beepState = BEEP_IDLE;  // 蜂鳴器狀態(tài)
  42. volatile unsigned char beepCount = 0;         // 剩余鳴叫次數(shù)
  43. volatile unsigned int beepTimer = 0;          // 計時計數(shù)器

  44. // 蜂鳴器發(fā)聲函數(shù) - 成功時短鳴
  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) {  // 僅在空閑狀態(tài)下啟動
  56.         beepState = BEEP_ON;       // 切換到開啟狀態(tài)
  57.         beepCount = 3;             // 設置鳴響3次
  58.         beepTimer = 500;           // 首次鳴響500ms
  59.     }
  60. }

  61. // 蜂鳴器任務
  62. void beepTask(void) {
  63.     static unsigned int beepCounter = 0;  // 新增計數(shù)器,跟蹤精確計時
  64.    
  65.     // 如果處于空閑狀態(tài),直接返回,不執(zhí)行任何操作
  66.     if(beepState == BEEP_IDLE) {
  67.         return;
  68.     }
  69.    
  70.     switch(beepState) {
  71.         case BEEP_ON:
  72.             BUZZER = ~BUZZER;  // 翻轉電平發(fā)聲
  73.             
  74.             // 精確計時控制
  75.             if(++beepCounter >= 200) {  // 500次計數(shù)約500ms
  76.                 beepCounter = 0;
  77.                 BUZZER = 0;                // 關閉蜂鳴器
  78.                
  79.                 // 檢查是否為最后一聲
  80.                 if(beepCount == 1) {
  81.                     beepState = BEEP_IDLE; // 最后一聲后直接進入空閑狀態(tài)
  82.                     BUZZER = 0;            // 雙重確保蜂鳴器關閉
  83.                 } else {
  84.                     beepState = BEEP_OFF;  // 否則進入間隔狀態(tài)
  85.                     beepTimer = 300;       // 間隔300ms
  86.                 }
  87.             }
  88.             break;
  89.             
  90.         case BEEP_OFF:
  91.             if(++beepCounter >= 300) {  // 300次計數(shù)約300ms
  92.                 beepCounter = 0;
  93.                 beepCount--;                 // 剩余次數(shù)減1
  94.                 beepState = BEEP_ON;         // 繼續(xù)鳴響
  95.                 beepTimer = 500;             // 鳴響500ms
  96.             }
  97.             break;
  98.             
  99.         default:
  100.             beepCounter = 0;  // 重置計數(shù)器
  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. // 顯示狀態(tài)處理函數(shù)
  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.         // 逐個字節(jié)比較卡號
  143.         for(j = 0; j < 4; j++) {
  144.             if(card_id[j] != students[i].card_id[j]) {
  145.                 break;
  146.             }
  147.         }
  148.         
  149.         // 如果4個字節(jié)都匹配,找到學生信息
  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.     // 發(fā)出成功提示音
  183.     beep_success();
  184.    
  185.     // 設置顯示狀態(tài)
  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.         // 通過串口發(fā)送學生信息
  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.         // 未找到學生信息,發(fā)送卡號
  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.     // 發(fā)出失敗提示音
  228.     beep_failure();
  229.    
  230.     // 設置顯示狀態(tài)
  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.     // 通過串口發(fā)送未授權卡片信息
  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.         // 逐個字節(jié)比較卡號
  255.         for(j = 0; j < 4; j++) {
  256.             if(card_id[j] != students[i].card_id[j]) {
  257.                 break;
  258.             }
  259.         }
  260.         
  261.         // 如果4個字節(jié)都匹配,返回ok
  262.         if(j == 4) {
  263.             return 1;
  264.         }
  265.     }
  266.    
  267.     // 未找到匹配的卡片,返回不ok
  268.     return 0;
  269. }

  270. // 主函數(shù)
  271. void main(void) {
  272.     unsigned char card_detected = 0;
  273.    
  274.     // 初始化系統(tǒng)
  275.     PcdReset();         // 初始化RC522
  276.     Uart_Init();        // 初始化串口
  277.     LCDInit();          // 初始化LCD
  278.     BUZZER = 0;         // 初始化蜂鳴器端口
  279.     // 串口提示系統(tǒng)啟動
  280.     Uart_Send_String("RFID Attendance System Started\r\n");
  281.    
  282.     display_welcome();  // 顯示歡迎信息
  283.    
  284.     while(1) {
  285.         // 處理蜂鳴器狀態(tài)
  286.         beepTask();
  287.         
  288.         // 處理顯示狀態(tài)
  289.         displayTask();
  290.         
  291.         // 檢測卡片(僅在空閑狀態(tài)下檢測)
  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.                     // 讓卡片進入休眠狀態(tài)
  310.                     PcdHalt();
  311.                 }
  312.             }
  313.         }
  314.         
  315.         // 延時降低CPU使用率(精確延時)
  316.         delay_ms(1);  // 1ms延時,提高響應速度
  317.     }
  318. }
復制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表