51RFID一卡通扣费充值系统设计-RFID-LCD1602-KEY
本设计由STC89C52单片机电路+RFID读卡器模块+液晶LCD1602显示电路+按键电路+串口模块PL2303电路+电源电路组成。
1、可以通过按键K1、K2设置扣费金额,金额为0-20,按键设置精度为1。
2、按下按键K3,则进入扣费状态,如果RFID卡刷卡后,则开始扣费。
3、按下按键K4,则扣费,按一次,扣一次。
4、LCD1602液晶实时显示扣费金额、余额。
5、如果系统有任何操作,则系统通过串口将当前信息上传到电脑,否则不上传。
6、液晶实时显示读卡状态,是否有效卡及有无卡状态提示。
7、充值后金额过充提醒,扣费金额不足提醒。
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<stdio.h>
#include <intrins.h>
#include "delay.h"
#include "rc522.h"
#include "1602.h"
#include "eeprom.h"
sbit key1 =P1^0; //引脚定义
sbit key2 =P1^1;
sbit key3 =P1^2;
sbit key4 =P1^3;
/********************/
unsigned char cardId[4]={0xD6,0x5F,0x2A,0x79}; //该出修改有效卡ID号
/********************/
unsigned char UID[5]; //暂存卡号
unsigned char Temp[4] ; //中间变量
unsigned long time_20ms; //定时计数
xdata char dis0[16]; //显示数组变量
xdata char dis1[25]; //显示数组变量
bit disFlag; //显示更新标志
unsigned char timelater =0; //时间延时计数
unsigned char readCardFlag = 0; //读卡状态
unsigned int SetNum = 10;//扣费金额
bit rekey =0;//防止重复按下
unsigned char yuE = 100;//余额
void Init_Timer0(void);
void uartSendStr(unsigned char *s,unsigned char length);
void UART_Init(void);
void uartSendByte(unsigned char dat);
unsigned char initFlagData; //初始化数据存读取
/******************把数据保存到单片机内部eepom中******************/
void write_eeprom()
{
SectorErase(0x2000); //擦除整个扇区 注意整个扇区数据都擦出了
byte_write(0x2001, yuE);
byte_write(0x2055, initFlagData);
}
/******************把数据从单片机内部eepom中读出来*****************/
void read_eeprom()
{
yuE = byte_read(0x2001); //读取高字节
initFlagData = byte_read(0x2055); //数据初始化读取
}
/**************开机初始化保存的数据*****************/
void init_eeprom()
{
read_eeprom(); //先读
if(initFlagData != 0x55) //新的单片机初始单片机内问eeprom 如果不是0x55重新写入
{
yuE = 100;
initFlagData = 0x55; //修改值
write_eeprom(); //保存数据
}
}
void main (void)
{
Init_Timer0(); //定时器0初始化
UART_Init();
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear();
init_eeprom();
uartSendStr("ready ok!",9);
PcdReset();//复位RC522
PcdAntennaOn();//开启天线发射
while (1) //主循环
{
if(PcdRequest(0x52,Temp)==MI_OK)
{
if(PcdAnticoll(UID)==MI_OK)
{
// uartSendByte(0x00);
// uartSendStr(UID,4);//上报卡号
// uartSendByte(0x00);
}
}
if(disFlag == 1) //定时更新显示
{
if(readCardFlag == 1) //有效卡
{
LCD_Write_String(0,0,"S:YouXiaoIDCZ:10");//显示
}
else if(readCardFlag == 2) //无效卡
{
LCD_Write_String(0,0,"S:WuXiaoID CZ:10");//显示
}
else //无卡
{
LCD_Write_String(0,0,"S:NoID CZ:10");//显示
}
}
if((key1==0)||(key2==0)||(key3==0)||(key4==0)) //检测到按键按下
{
if(rekey == 0)//防止重复按下
{
DelayMs(20);
if(key1==0)//按键按下
{
rekey =1;
if(readCardFlag == 1) //有效卡
{
if(yuE <= 190) //防止过充 最高充值200元
{
yuE = yuE + 10 ;//充值10元
sprintf(dis1,"CZ:10 NowYuE:%03d \r\n ",(unsigned int)yuE);
uartSendStr(dis1,20);//发送数据
}
}
}
else if(key2==0)//按键按下
{
rekey =1;
if(SetNum>1) //值--
{SetNum =SetNum-1;}
}
write_eeprom(); //保存数据
}
}
else
{rekey =0 ;} //防止重复按下
}
}
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=(65536-20000)/256; //重新赋值 20ms
TL0=(65536-20000)%256;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
void Timer0_isr(void) interrupt 1
{
TH0=(65536-20000)/256; //重新赋值 20ms
TL0=(65536-20000)%256;
time_20ms++;
if(time_20ms%10==0) //定时显示
{disFlag =1;}
if(timelater>0) //延时计数时间--
{timelater--;}
else
{readCardFlag=0;} //清除读卡标志
}
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TL1 = TH1;
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void uartSendByte(unsigned char dat)
{
unsigned char time_out;
time_out=0x00;
SBUF = dat; //将数据放入SBUF中
while((!TI)&&(time_out<100)) //检测是否发送出去
{time_out++;DelayUs2x(10);} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
void uartSendStr(unsigned char *s,unsigned char length)
{
unsigned char NUM;
NUM=0x00;
while(NUM<length) //发送长度对比
{
uartSendByte(*s); //放松单字节数据
s++; //指针++
NUM++; //下一个++
}
}
void UART_SER (void) interrupt 4 //串行中断服务程序
{
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
}
if(TI) //如果是发送标志位,清零
TI=0;
}
资料下载地址