00 要求
基于51单片机和RFID模块实现门禁的设计。使之具有以下功能:
- 能够正常的读卡信息;
- 在正常刷卡通过后,可以控制电子锁动作;
- 在刷卡失败后,可以产生报警信号;
01 功能分析
读卡后会RFID会自动通过TXD(串口)发送一段数据,调用串口接收即可
02 效果演示
03 硬件部分
LCD硬件电路部分
RFID刷卡器部分
步进电机部分
04 软件部分(核心代码)
完整工程代码部分,待实训结束后公开
如果需要技术支持可以加我的QQ交流:
cs
27969203789
RFID刷卡器部分
cs
void shuakaji(long idcard)
{
int a = 0;
int j=0;
if(flag == 1) //读完了数据就处理
{
for(a=1;a<11;a++)
{
recv_buf_play[a]=recv_buf[a];
if( recv_buf[a] >= '0' && recv_buf[a] <= '9')
{
recv_buf[a] = recv_buf[a] - '0';
}
else if(recv_buf[a] >= 'A' && recv_buf[a] <= 'F')
{
recv_buf[a] = recv_buf[a] - 'A' + 10;
} //计算出对应的字符的整型数据
id = id << 4 | recv_buf[a];
}
if( id == idcard )
{
start=1;
}
else
{
BUZZ = 0;
Delay_ms(500);
BUZZ = 1;
for( j=0;j<=12;j++)
{
recv_buf_play[j]=0;
}
}
flag = 0;//清除标志位
}
}
步进电机部分
cs
void MotorPlay()
{
if(start)//电机驱动
{
if(speed<10+speed_set)//速度
speed++;
else
{
speed=0;
if((step<step_set))
{
step++;
if(fang)//方向
{
switch(cixu)
{
case 0:L2=1;break;
case 1:L1=0;break;
case 2:L3=1;break;
case 3:L2=0;break;
case 4:L4=1;break;
case 5:L3=0;break;
case 6:L1=1;break;
case 7:L4=0;
}
}
else
{
switch(cixu)
{
case 0:L4=1;break;
case 1:L1=0;break;
case 2:L3=1;break;
case 3:L4=0;break;
case 4:L2=1;break;
case 5:L3=0;break;
case 6:L1=1;break;
case 7:L2=0;
}
}
if(cixu<7)
cixu++;
else
cixu=0;
}
else
{
step=0; //停止
start=0;
}
}
}
}
LCD部分
cs
#include "lcd1602.h"
/* 等待液晶准备好 */
void LcdWaitReady()
{
unsigned char sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1;
sta = LCD1602_DB; //读取状态字
LCD1602_E = 0;
}while (sta & 0x80); //bit7等于1表示液晶正忙,重复检测直到其等于0为止
}
/* 向LCD1602液晶写入一字节命令,cmd-待写入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 向LCD1602液晶写入一字节数据,dat-待写入数据值 */
void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;
if (y == 0) //由输入的屏幕坐标计算显示RAM的地址
addr = 0x00 + x; //第一行字符地址从0x00起始
else
addr = 0x40 + x; //第二行字符地址从0x40起始
LcdWriteCmd(addr | 0x80); //设置RAM地址
}
/* 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,
str-字符串指针,len-需显示的字符长度 */
void LcdShowStr(unsigned char x, unsigned char y,
unsigned char *str, unsigned char len)
{
LcdSetCursor(x, y); //设置起始地址
while (len--) //连续写入len个字符数据
{
LcdWriteDat(*str++);
}
}
/* 初始化1602液晶 */
void InitLcd1602()
{
LcdWriteCmd(0x38); //16*2显示,5*7点阵,8位数据接口
LcdWriteCmd(0x0C); //显示器开,光标关闭
LcdWriteCmd(0x06); //文字不动,地址自动+1
LcdWriteCmd(0x01); //清屏
}