姓名: 张? 李四 王五
张三不能正常显示三,其他还没有尝试
以下是我的代码
#include <reg52.h>
#include "lcd1602.h"
#include "mfrc522.h"
#include "uart.h"
#include <stdio.h>
// 定义蜂鸣器控制端口
sbit BUZZER = P3^6;
// 系统时钟频率(Hz),用于计算延时
#define FOSC 11059200
// 学生信息结构体定义
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", "王五"},
};
// 定义卡片数量
#define CARD_COUNT 3
// 定义系统状态
#define SYSTEM_IDLE 0 // 空闲状态
#define SYSTEM_SUCCESS 1 // 签到成功状态
#define SYSTEM_FAILURE 2 // 签到失败状态
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是否合法
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个字节都匹配,返回合法
if(j == 4) {
return 1;
}
}
// 未找到匹配的卡片,返回不合法
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)) {
// 合法卡片,显示签到成功
display_success(current_card_id);
} else {
// 非法卡片,显示失败
display_failure(current_card_id);
}
// 让卡片进入休眠状态
PcdHalt();
}
}
}
// 延时降低CPU使用率(精确延时)
delay_ms(1); // 1ms延时,提高响应速度
}
}
|