概述
任务摘要
当今社会,交通压力不断增加,智能停车场管理系统是人们对便捷高效交通的一种追求。本智能停车场管理系统运用RFID技术,采用STC8H8K64U单片机、RC522、串口屏、光电传感器实现系统设计的基本功能要求。用光电传感器检测车位信号;用RC522实现读卡,获取卡片信息,检测卡片有效性;用LCD串口屏幕显示系统时间日期、持卡人姓名、总停车位、可用停车位、距离最近车位、停车时间和收费以及卡片无效提醒;用单片机控制舵机转动,代表栏杆抬起和落下;用单片机实现从卡片中自动扣费,当车辆进出场时使用语音提醒。本设计主要应用于小区、学校等场所,给人们提供便捷高效地停车服务。
在设计该智能停车场管理系统时,使用到了软件和硬件知识,包括原理的设计、各个模块的连接、RC522模块的使用、单片机程序设计、显示屏界面设计。通过设计、调整和调试后,本设计大致完成了以下指标:
(1)实现了光电传感器检测车位信号;
(2)实现了RC522读取卡片,检测卡片有效性;
(3)实现了LCD串口屏幕显示系统时间日期、持卡人姓名、总停车位、可用停车位、距离最近车位、停车时间和收费以及卡片无效提醒;
(4)实现了车辆入场出场时语音播报提醒;
(5)实现了单片机控制舵机转动;
(6)实现了单片机从卡片自动扣费。
实物
本系统使用光电传感器做车位检测,其体积小,成本低,使用简单,适合IO引脚有限制的设计。
对比分析,超声波传感器虽然精度较高,但安装位置固定,超声波散射和发射容易引起误判导致检测错误,而光电传感器虽精度没有超声波传感器好,但稳定性较好,在室内停车场中受环境因素影响小,所以综合考虑下,采用光电传感器。
屏幕显示:
单片机最小系统板:
使用STC8H8V64U单片机作为智能停车场管理系统的核心板,STC8H8V64U有64个I/O口,具有超高速8051内核。由于该系统使用到的I/O口较少,如果使用STM32单片机作为核心板则体现不出性价比从而造成资源的浪费。STC8H8V64U不需要外部晶振,运行频率45MHZ。所以综合功能要求、性价比等方面,该设计选择使用性价比较高的STC8H8V64U单片机作为核心板。
原理图
系统架构
本系统设计的智能停车场管理系统主要由STC8H8K64U单片机、光电传感器、LCD串口屏幕、RC522射频模块、语音播报模块、DS1302时钟模块、舵机和对应驱动板等多个元器件组成,总框图如图所示。在本设计中,使用舵机充当栏杆,使用光电传感器代替停车位。本设计虚拟设置了100个停车位,但由于设计区域的限制,实际用了9个光电传感器来代替。
模块讲解
语音模块
语音模块使用的是SYN6288中文语音合成芯片,其可以接受待合成的文本数据,实现文本到语音的转换,语音合成效果较好。语音播报模块电路如图所示。语音模块使用串口进行数据通信,将要发送的数据使用串口发送给模块即可命令模块进行播放,但要注意发送字节长度有限。
驱动程序:
/***************************YS-SYN语音合成驱动程序(STC51核)****************************
** 晶振:
** 波特率:9600 bit/S
** 作者:
** 联系:
/***************************YS-SYN语音合成驱动程序(STC51核)******************************/
#ifndef SYN6288_H
#define SYN6288_H
#include "config.h"
#include "UART.h"
#define SYN_DelayMs delay_ms
#define SYN_SendByte TX2_write2buff //单个字符串发送函数
sbit BUSY_SYN6288=P1^4;
void YS_SYN_Init(void);
void SYN_FrameInfo(uint8_t Music,uint8_t *HZdata);
#endif
/***************************YS-SYN语音合成驱动程序(STC51核)****************************
** 晶振:
** 波特率:9600 bit/S
** 作者:
** 联系:
/***************************YS-SYN语音合成驱动程序(STC51核)******************************/
#include "SYN6288.h"
/**************芯片设置命令*********************/
uint8_t code SYN_StopCom[]={0xFD,0X00,0X02,0X02,0XFD};//停止合成
uint8_t code SYN_SuspendCom[]={0XFD,0X00,0X02,0X03,0XFC};//暂停合成
uint8_t code SYN_RecoverCom[]={0XFD,0X00,0X02,0X04,0XFB};//恢复合成
uint8_t code SYN_ChackCom[]={0XFD,0X00,0X02,0X21,0XDE};//状态查询
uint8_t code SYN_PowerDownCom[]={0XFD,0X00,0X02,0X88,0X77};//进入POWER DOWN 状态命令
uint8_t code SYN_Sound_RD[]={0xFD, 0x00 ,0x08, 0x01 ,0x01, 0x5B ,0x76, 0x31, 0x35, 0x5D, 0x87 }; //人声声音 等级第三
uint8_t code SYN_Sound_BK[]={0xFD, 0x00, 0x08, 0x01, 0x01 ,0x5B, 0x76 ,0x31, 0x35, 0x5D, 0x81 }; //背景声音最大
/***********************************************/
/*************************************************************************
** 函数名称:串口发送一个字符串
**************************************************************************/
void SYN_SendStr(unsigned char *DAT,uchar len)
{
uint8_t i;
for(i=0;i<len;i++)
{
SYN_SendByte(*DAT++);
}
}
/***********************************************************
* 名 称: YS-SYN6288 文本合成函数
* 功 能: 发送合成文本到SYN6288芯片进行合成播放
* 入口参数:Music(背景音乐选择):0无背景音乐。1-15:相关背景音乐
*HZdata:文本指针变量
* 出口参数:
* 说 明: 本函数只用于文本合成,具备背景音乐选择。默认波特率9600bps。
* 调用方法:例: SYN_FrameInfo(0,“黄淮学院测试语音合成”);
Busy(BY引脚)为高电平时表明芯片正在合成播放文本状态,低电平代表芯片处于空闲状态
采用串口三定时器3制作的驱动;可根据自己需求进行修改
**********************************************************/
void SYN_FrameInfo(uint8_t Music,uint8_t *HZdata)
{
/****************需要发送的文本**********************************/
unsigned char xdata Frame_Info[50]={0};
unsigned char HZ_Length=0;
unsigned char ecc = 0; //定义校验字节
unsigned int i=0;
HZ_Length =strlen(HZdata); //需要发送文本的长度
BUSY_SYN6288=1;
/*****************帧固定配置信息**************************************/
Frame_Info[0] = 0xFD ; //构造帧头FD
Frame_Info[1] = 0x00 ; //构造数据区长度的高字节
Frame_Info[2] = HZ_Length + 3; //构造数据区长度的低字节
Frame_Info[3] = 0x01 ; //构造命令字:合成播放命令
Frame_Info[4] = 0x01 | Music<<3 ; //构造命令参数:背景音乐设定 左移3位
/*******************校验码计算***************************************/
for(i = 0; i<5; i++) //依次发送构造好的5个帧头字节
{
ecc=ecc^(Frame_Info[i]); //对发送的字节进行异或校验
}
for(i= 0; i<HZ_Length; i++) //依次发送待合成的文本数据
{
ecc=ecc^(HZdata[i]); //对发送的字节进行异或校验
}
/*******************发送帧信息***************************************/
memcpy(&Frame_Info[5], HZdata, HZ_Length);
Frame_Info[5+HZ_Length]=ecc;
SYN_SendStr(Frame_Info,5+HZ_Length+1);
SYN_DelayMs(0xff); //延时必须要
while(BUSY_SYN6288); //等待播放完成
SYN_DelayMs(0xff); //延时必须要
}
/***********************************************************
* 名 称:
* 功 能: 程序入口
* 入口参数: *Info_data:固定的配置信息变量
* 出口参数:
* 说 明:本函数用于配置,停止合成、暂停合成等设置 ,默认波特率9600bps。
* 调用方法:通过调用已经定义的相关数组进行配置。
**********************************************************/
void YS_SYN_Set(uint8_t *Info_data)
{
uint8_t Com_Len;
Com_Len =strlen(Info_data);
SYN_SendStr(Info_data,Com_Len);
}
void YS_SYN_Init()
{
YS_SYN_Set(SYN_Sound_RD); //人声声音 等级第三
YS_SYN_Set(SYN_Sound_BK); //背景声音最大
SYN_DelayMs(0x2f);
}
光电检测模块
光电检测逻辑:
驱动程序:
#ifndef __GUANGDIAN_H__
#define __GUANGDIAN_H__
#include "config.h"
#define gd_GPIO P2
sbit gd_hang02 = P0^7;
#define GD_MAXNUM 9
typedef struct {
uchar label_pai;
uchar label_hao;
uchar count_gd;
}STRUCT_gd;
extern STRUCT_gd gd_Structure;
void gd_GPIO_Init(void);
void gd_scan(void);
#endif
#include "guangdian.h"
STRUCT_gd gd_Structure;
void gd_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //结构定义
GPIO_InitStructure.Pin = GPIO_Pin_All; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P2,&GPIO_InitStructure); //初始化
GPIO_InitStructure.Pin = GPIO_Pin_7; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P0,&GPIO_InitStructure); //初始化
gd_Structure.label_pai = 1;
gd_Structure.label_hao = 1;
gd_Structure.count_gd = 0;
}
void gd_scan(void) //检测哪些IO口被占用,还剩多少个未使用
{
uchar temp_gd=0;
uchar temp_location=0;
uchar i;
gd_GPIO=0xff;
temp_gd=gd_GPIO;
temp_location=gd_GPIO;
if(temp_location!=0x00) //如果IO没有被使用完,代表车辆没有将车位用完,进入子程序来寻找最近的为1(未使用)的IO口
{
for(i=0;i<8;i++)
{
if(temp_location&0x01)
{
gd_Structure.label_pai=1;
gd_Structure.label_hao=i+1;
break;
}
else
{
temp_location=temp_location>>1;
}
}
}
else if(gd_hang02 == 1)
{
gd_Structure.label_pai=2;
gd_Structure.label_hao=0;
}
else{}
gd_Structure.count_gd=0;
if(temp_gd!=0xff)
{
for(i=0;i<8;i++)
{
if((temp_gd&0x80)==0)
{
gd_Structure.count_gd++;
}
temp_gd=temp_gd<<1;
}
}
if(gd_hang02 == 0)
{
gd_Structure.count_gd++;
}
}
串口屏
本设计采用的是2.4寸的LCD串口显示屏,点阵分辨率为240*320,能够在屏幕上的任意位置显示图片及任意的图形。该模块主要通过RXD、TXD对数据进行异步通讯接收和发送,在本设计中,显示模块主要是接收单片机STC8H给出的数据指令。采用LCD显示模块实现单片机对一些数据的显示,智能停车场管理系统可以直接在LCD显示屏上看到系统的时间、总停车位、剩余停车位以及卡片信息等内容。
驱动程序:
#ifndef __LCDUART_h
#define __LCDUART_h
#include "config.h"
#include <string.h>
#include <stdio.h>
#define LCD_COLOR_BLACK 0
#define LCD_COLOR_RED 1
#define LCD_COLOR_GREEN 2
#define LCD_COLOR_BLUE 3
#define LCD_COLOR_YELLOW 4
#define LCD_COLOR_BLUE02 5
#define LCD_COLOR_PURPLE 6
#define LCD_COLOR_GREY 7
#define LCD_COLOR_WHITE 16
#define LCD_BackColor LCD_COLOR_WHITE
#define LCD_TextColor LCD_COLOR_PURPLE
#define LCD_SBCColor LCD_COLOR_WHITE
#define LCD_WarningColor LCD_COLOR_RED
#define LCD_Light 20
#define LCD_BUFFMAX 50
typedef struct {
u16 RxCounter;
u8 RxBuffer[LCD_BUFFMAX];
FlagState IS_Start;
FlagState IS_Finish;
}STRUCT_LCD;
extern STRUCT_LCD LCD_Structure;
void LCD_CheckBusy(void);
void LCD_Receive(u8 recChar);
#endif
#include "lcdUart.h"
void LCD_CLR(void)
{
u8 i =0;
LCD_Structure.IS_Finish = FALSE;
LCD_Structure.RxCounter = 0;
for(i=0;i<LCD_BUFFMAX;i++)
LCD_Structure.RxBuffer[i]=0;
}
int LCD_FindCmd(char *a)
{
if(strstr((char *)LCD_Structure.RxBuffer,(char *)a)!=NULL)
{
return 1;
}
else
{
return 0;
}
}
void LCD_CheckBusy(void)
{
int wait_time = 200;
while(wait_time--)
{
if(LCD_Structure.IS_Finish == TRUE)
{
if(LCD_FindCmd("OK"))
wait_time=0;
}
delay_ms(1);
}
LCD_CLR();
}
STRUCT_LCD LCD_Structure;
void LCD_Receive(u8 recChar)
{
LCD_Structure.RxBuffer[LCD_Structure.RxCounter++] = recChar;
if(recChar == 'r')
{
LCD_Structure.IS_Finish = TRUE;
}
if(LCD_Structure.RxCounter > LCD_BUFFMAX)
{
LCD_Structure.RxCounter = 0;
LCD_Structure.IS_Finish = TRUE;
}
}
RFID,RC522驱动
#ifndef __RC522_H
#define __RC522_H
#include "config.h"
#include <intrins.h>
//射频模块:SDA(NSS): SCk: MOSI: MISO: RST:
sbit MF522_NSS = P3^3; //RC500片选 SDA
sbit MF522_SCK = P3^4;
sbit MF522_SI = P3^5; //MOSI
sbit MF522_SO = P3^6; //MISO
sbit MF522_RST = P3^7;
/
//函数原型
/
void InitRC522(void);
void PcdGpioConfig(void);
char PcdReset(void);
void PcdAntennaOn(void);
void PcdAntennaOff(void);
char PcdRequest(unsigned char req_code,unsigned char *pTagType);
char PcdAnticoll(unsigned char *pSnr);
char PcdComMF522(unsigned char Command,
unsigned char *pInData,
unsigned char InLenByte,
unsigned char *pOutData,
unsigned int *pOutLenBit);
void WriteRawRC(unsigned char Address,unsigned char value);
unsigned char ReadRawRC(unsigned char Address);
void SetBitMask(unsigned char reg,unsigned char mask);
void ClearBitMask(unsigned char reg,unsigned char mask);
/
//MF522命令字
/
#define PCD_IDLE 0x00 //取消当前命令
#define PCD_AUTHENT 0x0E //验证密钥
#define PCD_RECEIVE 0x08 //接收数据
#define PCD_TRANSMIT 0x04 //发送数据
#define PCD_TRANSCEIVE 0x0C //发送并接收数据
#define PCD_RESETPHASE 0x0F //复位
#define PCD_CALCCRC 0x03 //CRC计算
/
//Mifare_One卡片命令字
/
#define PICC_REQIDL 0x26 //寻天线区内未进入休眠状态
#define PICC_REQALL 0x52 //寻天线区内全部卡
#define PICC_ANTICOLL1 0x93 //防冲撞
#define PICC_ANTICOLL2 0x95 //防冲撞
#define PICC_AUTHENT1A 0x60 //验证A密钥
#define PICC_AUTHENT1B 0x61 //验证B密钥
#define PICC_READ 0x30 //读块
#define PICC_WRITE 0xA0 //写块
#define PICC_DECREMENT 0xC0 //扣款
#define PICC_INCREMENT 0xC1 //充值
#define PICC_RESTORE 0xC2 //调块数据到缓冲区
#define PICC_TRANSFER 0xB0 //保存缓冲区中数据
#define PICC_HALT 0x50 //休眠
/
//MF522 FIFO长度定义
/
#define DEF_FIFO_LENGTH 64 //FIFO size=64byte
/
//MF522寄存器定义
/
// PAGE 0
#define RFU00 0x00
#define CommandReg 0x01
#define ComIEnReg 0x02
#define DivlEnReg 0x03
#define ComIrqReg 0x04
#define DivIrqReg 0x05
#define ErrorReg 0x06
#define Status1Reg 0x07
#define Status2Reg 0x08
#define FIFODataReg 0x09
#define FIFOLevelReg 0x0A
#define WaterLevelReg 0x0B
#define ControlReg 0x0C
#define BitFramingReg 0x0D
#define CollReg 0x0E
#define RFU0F 0x0F
// PAGE 1
#define RFU10 0x10
#define ModeReg 0x11
#define TxModeReg 0x12
#define RxModeReg 0x13
#define TxControlReg 0x14
#define TxAutoReg 0x15
#define TxSelReg 0x16
#define RxSelReg 0x17
#define RxThresholdReg 0x18
#define DemodReg 0x19
#define RFU1A 0x1A
#define RFU1B 0x1B
#define MifareReg 0x1C
#define RFU1D 0x1D
#define RFU1E 0x1E
#define SerialSpeedReg 0x1F
// PAGE 2
#define RFU20 0x20
#define CRCResultRegM 0x21
#define CRCResultRegL 0x22
#define RFU23 0x23
#define ModWidthReg 0x24
#define RFU25 0x25
#define RFCfgReg 0x26
#define GsNReg 0x27
#define CWGsCfgReg 0x28
#define ModGsCfgReg 0x29
#define TModeReg 0x2A
#define TPrescalerReg 0x2B
#define TReloadRegH 0x2C
#define TReloadRegL 0x2D
#define TCounterValueRegH 0x2E
#define TCounterValueRegL 0x2F
// PAGE 3
#define RFU30 0x30
#define TestSel1Reg 0x31
#define TestSel2Reg 0x32
#define TestPinEnReg 0x33
#define TestPinValueReg 0x34
#define TestBusReg 0x35
#define AutoTestReg 0x36
#define VersionReg 0x37
#define AnalogTestReg 0x38
#define TestDAC1Reg 0x39
#define TestDAC2Reg 0x3A
#define TestADCReg 0x3B
#define RFU3C 0x3C
#define RFU3D 0x3D
#define RFU3E 0x3E
#define RFU3F 0x3F
/
//和MF522通讯时返回的错误代码
/
#define MI_OK 1
#define MI_NOTAGERR (-1)
#define MI_ERR (-2)
#endif
#include "RC522.h"
#define MAXRLEN 18
void InitRC522(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //结构定义
GPIO_InitStructure.Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P3,&GPIO_InitStructure); //初始化
}
/
//功 能:寻卡
//参数说明: req_code[IN]:寻卡方式
// 0x52 = 寻感应区内所有符合14443A标准的卡
// 0x26 = 寻未进入休眠状态的卡
// pTagType[OUT]:卡片类型代码
// 0x4400 = Mifare_UltraLight
// 0x0400 = Mifare_One(S50)
// 0x0200 = Mifare_One(S70)
// 0x0800 = Mifare_Pro(X)
// 0x4403 = Mifare_DESFire
//返 回: 成功返回MI_OK
/
char PcdRequest(unsigned char req_code,unsigned char *pTagType)
{
char status;
unsigned int unLen;
unsigned char xdata ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg,0x08);
WriteRawRC(BitFramingReg,0x07);
SetBitMask(TxControlReg,0x03);
ucComMF522Buf[0] = req_code;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);
if ((status == MI_OK) && (unLen == 0x10))
{
*pTagType = ucComMF522Buf[0];
*(pTagType+1) = ucComMF522Buf[1];
}
else
{ status = MI_ERR;
}
return status;
}
/
//功 能:防冲撞
//参数说明: pSnr[OUT]:卡片序列号,4字节
//返 回: 成功返回MI_OK
/
char PcdAnticoll(unsigned char *pSnr)
{
char status;
unsigned char i,snr_check=0;
unsigned int unLen;
unsigned char xdata ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg,0x08);
WriteRawRC(BitFramingReg,0x00);
ClearBitMask(CollReg,0x80);
ucComMF522Buf[0] = PICC_ANTICOLL1;
ucComMF522Buf[1] = 0x20;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);
if (status == MI_OK)
{
for (i=0; i<4; i++)
{
*(pSnr+i) = ucComMF522Buf[i];
snr_check ^= ucComMF522Buf[i];
}
if (snr_check != ucComMF522Buf[i])
{ status = MI_ERR; }
}
SetBitMask(CollReg,0x80);
return status;
}
/
//功 能:复位RC522
//返 回: 成功返回MI_OK
/
char PcdReset(void)
{
//unsigned char i;
MF522_RST=1;
_nop_();
MF522_RST=0;
_nop_();
MF522_RST=1;
_nop_();
WriteRawRC(CommandReg,PCD_RESETPHASE);
_nop_();
WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363
WriteRawRC(TReloadRegL,30);
WriteRawRC(TReloadRegH,0);
WriteRawRC(TModeReg,0x8D);
WriteRawRC(TPrescalerReg,0x3E);
WriteRawRC(TxAutoReg,0x40);
return MI_OK;
}
/
//功 能:读RC632寄存器
//参数说明:Address[IN]:寄存器地址
//返 回:读出的值
/
unsigned char ReadRawRC(unsigned char Address)
{
unsigned char i, ucAddr;
unsigned char ucResult=0;
MF522_SCK = 0;
MF522_NSS = 0;
ucAddr = ((Address<<1)&0x7E)|0x80;
for(i=8;i>0;i--)
{
MF522_SI = ((ucAddr&0x80)==0x80);
MF522_SCK = 1;
ucAddr <<= 1;
MF522_SCK = 0;
}
for(i=8;i>0;i--)
{
MF522_SCK = 1;
ucResult <<= 1;
ucResult|=(bit)MF522_SO;
MF522_SCK = 0;
}
MF522_NSS = 1;
MF522_SCK = 1;
return ucResult;
}
/
//功 能:写RC632寄存器
//参数说明:Address[IN]:寄存器地址
// value[IN]:写入的值
/
void WriteRawRC(unsigned char Address, unsigned char value)
{
unsigned char i, ucAddr;
MF522_SCK = 0;
MF522_NSS = 0;
ucAddr = ((Address<<1)&0x7E);
for(i=8;i>0;i--)
{
MF522_SI = ((ucAddr&0x80)==0x80);
MF522_SCK = 1;
ucAddr <<= 1;
MF522_SCK = 0;
}
for(i=8;i>0;i--)
{
MF522_SI = ((value&0x80)==0x80);
MF522_SCK = 1;
value <<= 1;
MF522_SCK = 0;
}
MF522_NSS = 1;
MF522_SCK = 1;
}
/
//功 能:置RC522寄存器位
//参数说明:reg[IN]:寄存器地址
// mask[IN]:置位值
/
void SetBitMask(unsigned char reg,unsigned char mask)
{
char tmp = 0x0;
tmp = ReadRawRC(reg);
WriteRawRC(reg,tmp | mask); // set bit mask
}
/
//功 能:清RC522寄存器位
//参数说明:reg[IN]:寄存器地址
// mask[IN]:清位值
/
void ClearBitMask(unsigned char reg,unsigned char mask)
{
char tmp = 0x0;
tmp = ReadRawRC(reg);
WriteRawRC(reg, tmp & ~mask); // clear bit mask
}
/
//功 能:通过RC522和ISO14443卡通讯
//参数说明:Command[IN]:RC522命令字
// pInData[IN]:通过RC522发送到卡片的数据
// InLenByte[IN]:发送数据的字节长度
// pOutData[OUT]:接收到的卡片返回数据
// *pOutLenBit[OUT]:返回数据的位长度
/
char PcdComMF522(unsigned char Command,
unsigned char *pInData,
unsigned char InLenByte,
unsigned char *pOutData,
unsigned int *pOutLenBit)
{
char status = MI_ERR;
unsigned char irqEn = 0x00;
unsigned char waitFor = 0x00;
unsigned char lastBits;
unsigned char n;
unsigned int i;
switch (Command)
{
case PCD_AUTHENT:
irqEn = 0x12;
waitFor = 0x10;
break;
case PCD_TRANSCEIVE:
irqEn = 0x77;
waitFor = 0x30;
break;
default:
break;
}
WriteRawRC(ComIEnReg,irqEn|0x80);
ClearBitMask(ComIrqReg,0x80);
WriteRawRC(CommandReg,PCD_IDLE);
SetBitMask(FIFOLevelReg,0x80);
for (i=0; i<InLenByte; i++)
{ WriteRawRC(FIFODataReg, pInData[i]); }
WriteRawRC(CommandReg, Command);
if (Command == PCD_TRANSCEIVE)
{ SetBitMask(BitFramingReg,0x80); }
i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms
do
{
n = ReadRawRC(ComIrqReg);
i--;
}
while ((i!=0) && !(n&0x01) && !(n&waitFor));
ClearBitMask(BitFramingReg,0x80);
if (i!=0)
{
if(!(ReadRawRC(ErrorReg)&0x1B))
{
status = MI_OK;
if (n & irqEn & 0x01)
{ status = MI_NOTAGERR; }
if (Command == PCD_TRANSCEIVE)
{
n = ReadRawRC(FIFOLevelReg);
lastBits = ReadRawRC(ControlReg) & 0x07;
if (lastBits)
{ *pOutLenBit = (n-1)*8 + lastBits; }
else
{ *pOutLenBit = n*8; }
if (n == 0)
{ n = 1; }
if (n > MAXRLEN)
{ n = MAXRLEN; }
for (i=0; i<n; i++)
{ pOutData[i] = ReadRawRC(FIFODataReg); }
}
}
else
{ status = MI_ERR; }
}
SetBitMask(ControlReg,0x80); // stop timer now
WriteRawRC(CommandReg,PCD_IDLE);
return status;
}
/
//开启天线
//每次启动或关闭天险发射之间应至少有1ms的间隔
/
void PcdAntennaOn()
{
unsigned char i;
i = ReadRawRC(TxControlReg);
if (!(i & 0x03))
{
SetBitMask(TxControlReg, 0x03);
}
}
/
//关闭天线
/
void PcdAntennaOff()
{
ClearBitMask(TxControlReg, 0x03);
}
源代码
主程序main.c文件就是对于各个驱动的综合调用。
/*******************************************************************************
* 文件名称:基于51单片机的RFID停车计费系统
* 实验目的:1.
* 2.
* 程序说明:完整程序Q:277 227 2579;@: itworkstation@ hotmail.com
* 日期版本:本项目分享关键细节,熟悉使用单片机的可做参考代码。完整讲解+源代码工程可联系获取,可定制。
*******************************************************************************/
#include "config.h"
#include "UART.h"
#include "lcdUart.h"
#include "lcdUart02.h"
#include "SYN6288.h"
#include "ds1302.h"
#include "timer.h"
#include "SG90.h"
#include "RC522.h"
#include "RC522OUT.h"
#include "guangdian.h"
#include "eeprom.h"
/************* 本地常量声明 **************/
/*******************测试串口格式化输出方式,51的C是改动版本***********************
unsigned char a = 10;
char b = -15 ;
unsigned short c = 20;
short d = -25;
unsigned int e = 65535;
int f = -32765;
sprintf(LCD_DisBuff,"DCV16(92,50,'欢迎使用基于STM32单片机的自动视力检测仪a=%bu b=%bd c=%hu d=%hd e=%hu f=%hd',%burn",a,b,c,d,e,f,LCD_TextColor);
********************************************************************************/
/************* 本地变量声明 **************/
#define LCDNUMBERMAX 120
char LCD_DisBuff[LCDNUMBERMAX];
#define LCD02NUMBERMAX 120
char LCD02_DisBuff[LCDNUMBERMAX];
#define PLAYNUMBERMAX 120
char YuYin_PlayBuff[PLAYNUMBERMAX];
uchar date1302[]={22,5,8,13,21,0};
#define RCREADTIME 2000
#define NONEClient 0
#define NONECARD 0xff
bit flag_ReceiveCard = FALSE,flag_ReceiveCard_Out = FALSE;
uchar Client=NONEClient,Client_Out=NONEClient;
unsigned char xdata g_ucTempbuf[20],g_ucTempbuf_Out[20];
uchar xdata Xuhao_Panduan[4],Xuhao_Panduan_Out[4];
uchar code Xuhao_SQL[]={
0x93,0XCC,0X5E,0X1C, // 蓝色卡1
//0xF3,0X1A,0XFA,0X1D, // 蓝色卡2
0X43,0X10,0X3A,0XA7, // 白色卡1
0X93,0X4F,0X4F,0X94, // 白色卡2
};
char code StuName[4][15]={
"***", //制作人姓名
//" 张三xFD", //三字出现乱码,乱码的字需要在对应字后面加xFD
//" 赵六",
" 李四",
" 王五",
};
char code StuNumber[4][15]={
"201802010001",
// "201802010002",
"201802010003",
"201802010004",
};
#define PRICE 2 //小时价格
typedef struct {
FlagState is_start;
uchar stayTime;
uchar stayPrice;
uchar leftMoney;
}STRUCT_messageStay;
STRUCT_messageStay mSt_Structure[4];
/************* 本地函数声明 **************/
uchar Xuhao_Check(void);
uchar rc522Read(void);
uchar Xuhao_Check_Out();
uchar rc522Read_Out(void);
/************* 外部函数和变量声明 *****************/
/******************* IO配置函数 *******************/
void GPIO_config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //结构定义
GPIO_InitStructure.Pin = GPIO_Pin_2 | GPIO_Pin_3; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P0,&GPIO_InitStructure); //初始化
GPIO_InitStructure.Pin = GPIO_Pin_0 | GPIO_Pin_1; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P0,&GPIO_InitStructure); //初始化
GPIO_InitStructure.Pin = GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_6 |GPIO_Pin_7; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P1,&GPIO_InitStructure); //初始化
GPIO_InitStructure.Pin = GPIO_Pin_4; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P1,&GPIO_InitStructure); //初始化
}
/*************** 串口初始化函数 *****************/
//与以往单片机不同的是,串口也要初始化GPIO!不然不工作哦!
void UART_config(void)
{
COMx_InitDefine COMx_InitStructure; //结构定义
COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
COMx_InitStructure.UART_BRT_Use = BRT_Timer4; //选择波特率发生器, BRT_Timer2, BRT_Timer4 (注意: 串口2固定使用BRT_Timer2)
// COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200
COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200
COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
COMx_InitStructure.UART_Interrupt = ENABLE; //中断允许, ENABLE或DISABLE
COMx_InitStructure.UART_Priority = Priority_0; //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
COMx_InitStructure.UART_P_SW = UART4_SW_P02_P03; //切换端口, UART4_SW_P02_P03,UART4_SW_P52_P53
UART_Configuration(UART4, &COMx_InitStructure); //初始化串口4 UART1,UART2,UART3,UART4
// PrintString4("STC8 UART4 Test Programme!rn"); //UART4发送一个字符串
COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
COMx_InitStructure.UART_BRT_Use = BRT_Timer3; //选择波特率发生器, BRT_Timer2, BRT_Timer3 (注意: 串口2固定使用BRT_Timer2)
// COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200
COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200
COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
COMx_InitStructure.UART_Interrupt = ENABLE; //中断允许, ENABLE或DISABLE
COMx_InitStructure.UART_Priority = Priority_0; //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
COMx_InitStructure.UART_P_SW = UART3_SW_P00_P01; //切换端口,
UART_Configuration(UART3, &COMx_InitStructure); //初始化串口3 UART1,UART2,UART3,UART4
COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
COMx_InitStructure.UART_BRT_Use = BRT_Timer2; //选择波特率发生器, BRT_Timer2, BRT_Timer4 (注意: 串口2固定使用BRT_Timer2)
// COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200
COMx_InitStructure.UART_BaudRate = 9600; //波特率, 110 ~ 115200
COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
COMx_InitStructure.UART_Interrupt = ENABLE; //中断允许, ENABLE或DISABLE
COMx_InitStructure.UART_Priority = Priority_0; //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
COMx_InitStructure.UART_P_SW = UART2_SW_P10_P11; //切换端口, UART4_SW_P02_P03,UART4_SW_P52_P53
UART_Configuration(UART2, &COMx_InitStructure); //初始化串口4 UART1,UART2,UART3,UART4
}
/************************ 定时器配置 ****************************/
void Timer_config(void)
{
TIM_InitTypeDef TIM_InitStructure; //结构定义
TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask 16位自动重装.
TIM_InitStructure.TIM_Priority = Priority_0; //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
TIM_InitStructure.TIM_Interrupt = ENABLE; //中断是否允许, ENABLE或DISABLE
TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_12T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
TIM_InitStructure.TIM_Value = 47104UL; //初值,//47104UL@20毫秒@11.0592MHz@12T时钟 28672UL@20毫秒@22.1184MHz@12T时钟
TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLE
Timer_Inilize(Timer0,&TIM_InitStructure); //初始化Timer0 Timer0,Timer1,Timer2,Timer3,Timer4
TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
TIM_InitStructure.TIM_Priority = Priority_0; //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
TIM_InitStructure.TIM_Interrupt = ENABLE; //中断是否允许, ENABLE或DISABLE
TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
// TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 10000); //初值, 中断频率为10000HZ,时钟 24MHz
TIM_InitStructure.TIM_Value = 60006UL; //初值,60006UL@500微秒@11.0592MHz 54477UL@500微秒@22.1184MHz
TIM_InitStructure.TIM_Run = DISABLE; //是否初始化后启动定时器, ENABLE或DISABLE
Timer_Inilize(Timer1,&TIM_InitStructure); //初始化Timer1 Timer0,Timer1,Timer2,Timer3,Timer4
}
/*************************************************************************
主函数
**************************************************************************/
sbit KEY_IN = P1^6;
sbit KEY_OUT = P1^7;
void KeyScan(void)
{
if(KEY_IN==0)
{
delay_ms(20);
if(KEY_IN==0)
{
if(SG90_Structure.num01_angleX == ANGLE_0)
{
SG90_Control(1,ANGLE_90);
}
else
{
SG90_Control(1,ANGLE_0);
}
}
while(!KEY_IN);
}
if(KEY_OUT==0)
{
delay_ms(20);
if(KEY_OUT==0)
{
if(SG90_Structure.num02_angleX == ANGLE_0)
{
SG90_Control(2,ANGLE_90);
}
else
{
SG90_Control(2,ANGLE_0);
}
}
while(!KEY_OUT);
}
}
void ClearData(void)
{
u8 i;
for(i=0;i<4;i++)
{
mSt_Structure[i].is_start = FALSE;
mSt_Structure[i].stayTime = 0;
mSt_Structure[i].stayPrice = 0;
mSt_Structure[i].leftMoney = 100;
}
}
void InitEPROM_Dis(void)
{
memset(LCD_DisBuff,0,LCDNUMBERMAX); //IN口屏幕
sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(93,32,'EEPROM',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV24(0,79,'源数据:',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV24(0,143,'读数据:',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
}
void EPROMData_Init(void)
{
u8 i,leftMoney[4];
// InitEPROM_Dis();
for(i=0;i<4;i++)
{
leftMoney[i] = mSt_Structure[i].leftMoney;
}
// printf("DCV24(79,79,'%bu,%bu,%bu,%bu',%burn",leftMoney[0],leftMoney[1],leftMoney[2],leftMoney[3],LCD_TextColor);
// LCD_CheckBusy();
if(IapReadByte(IAP_ADDRESS)==IAP_ADDRESS_VALUE) //已有金额数据
{
for(i=0;i<4;i++)
{
mSt_Structure[i].leftMoney = IapReadByte(USER_ADDRESS+i);
leftMoney[i] = mSt_Structure[i].leftMoney;
}
// printf("DCV24(79,143,'%bu,%bu,%bu,%bu',%burn",leftMoney[0],leftMoney[1],leftMoney[2],leftMoney[3],LCD_TextColor);
// LCD_CheckBusy();
//
// printf("DCV24(109,193,'读取成功',%burn",LCD_TextColor);
// LCD_CheckBusy();
//
// SYN_FrameInfo(3,"余额已读出");
}
else
{
/* 擦除 要修改/写入 的扇区 */
IapEraseSector(IAP_ADDRESS);
IapProgramByte(IAP_ADDRESS, IAP_ADDRESS_VALUE);
IapIdle();
if(sequential_write_flash_in_one_sector(USER_ADDRESS,4,leftMoney))
{
// SYN_FrameInfo(3,"余额已写入成功");
}
else
{
// SYN_FrameInfo(3,"余额写入失败");
}
for(i=0;i<4;i++)
{
mSt_Structure[i].leftMoney = IapReadByte(USER_ADDRESS+i);
leftMoney[i] = mSt_Structure[i].leftMoney;
}
// printf("DCV24(79,143,'%bu,%bu,%bu,%bu',%burn",leftMoney[0],leftMoney[1],leftMoney[2],leftMoney[3],LCD_TextColor);
// LCD_CheckBusy();
//
// printf("DCV24(109,193,'读取失败',%burn",LCD_TextColor);
// LCD_CheckBusy();
}
// delay_ms(5000);
// memset(LCD_DisBuff,0,LCDNUMBERMAX);
// sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
// PrintString3(LCD_DisBuff);
//
// memset(LCD_DisBuff,0,LCDNUMBERMAX);
// sprintf(LCD_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
// PrintString3(LCD_DisBuff);
// LCD_CheckBusy();
//
// memset(LCD_DisBuff,0,LCDNUMBERMAX);
// sprintf(LCD_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); // 51程序中,格式化输入个数不能大于3,否则就出错,很无语!
// PrintString3(LCD_DisBuff);
// LCD_CheckBusy();
// memset(LCD_DisBuff,0,LCDNUMBERMAX);
// sprintf(LCD_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]);
// PrintString3(LCD_DisBuff);
// LCD_CheckBusy();
//
// memset(LCD_DisBuff,0,LCDNUMBERMAX);
// sprintf(LCD_DisBuff,"DCV32(5,97,'本车库总车位:100个',%burn",LCD_TextColor);
// PrintString3(LCD_DisBuff);
// LCD_CheckBusy();
// memset(LCD_DisBuff,0,LCDNUMBERMAX);
// sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:100个',%burn",LCD_TextColor);
// PrintString3(LCD_DisBuff);
// LCD_CheckBusy();
// memset(LCD_DisBuff,0,LCDNUMBERMAX);
// sprintf(LCD_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%burn",LCD_TextColor);
// PrintString3(LCD_DisBuff);
// LCD_CheckBusy();
}
void main (void)
{
u8 E2rom_leftMoney[4],cnt=0;
u8 count_gd_last=0;
u8 check_time=0;
gd_GPIO_Init();
ClearData();
GPIO_config();
UART_config();
EA = 1;
delay_ms(1000);//上电等待 1 秒是串口屏模块正常工作的前提,如果没有足够的等待时间模块有可能无法正常的接收指令而导致系统出错。
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(16,31,'欢迎使用智慧停车库',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(64,97,'****大学',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(48,163,'制作人:***',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD02_BackColor,LCD02_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(16,31,'欢迎使用智慧停车库',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(64,97,'****',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(48,163,'制作人:***',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
delay_ms(1000);
YS_SYN_Init();
SYN_FrameInfo(3,"欢迎使用由***制作的停车计费系统");
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
//FSIMG (2097152,0,0,240,320,1);
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(82,1,'2022年03月18日',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(99,49,'16时32分50秒',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(5,97,'本车库总车位:100个',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:100个',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD02_BackColor,LCD02_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
Init_Ds1302(date1302);
Read_NowTime_Ds1302(date1302);
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); // 51程序中,格式化输入个数不能大于3,否则就出错,很无语!
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
// memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
// sprintf(LCD02_DisBuff,"DCV32(82,1,'2022年03月18日',%burn",LCD02_TextColor);
// PrintString4(LCD02_DisBuff);
// LCD02_CheckBusy();
// memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
// sprintf(LCD02_DisBuff,"DCV32(99,49,'16时32分50秒',%burn",LCD02_TextColor);
// PrintString4(LCD02_DisBuff);
// LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(5,97,'本车库总车位:100个',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(5,145,'当前可用车位:100个',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
Timer_config();
SG90_Init();
// SG90_Control(1,ANGLE_90);
// delay_ms(1000);
// SG90_Control(2,ANGLE_90);
// delay_ms(1000);
// SG90_Control(1,ANGLE_0);
// delay_ms(1000);
// SG90_Control(2,ANGLE_0);
// delay_ms(1000);
InitRC522();
InitRC522_Out();
EPROMData_Init();
while (1) //主循环
{
KeyScan();
gd_scan(); //检测车位
if(count_gd_last != gd_Structure.count_gd)
{
count_gd_last = gd_Structure.count_gd;
if(gd_Structure.count_gd == GD_MAXNUM)
{
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:000个',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
}
else
{
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%burn",100-gd_Structure.count_gd,LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%burn",100-gd_Structure.count_gd,LCD_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
}
}
Client = rc522Read(); //指纹读取最好在所有检测的最后。!
if(flag_ReceiveCard == TRUE)
{
flag_ReceiveCard = FALSE;
if(Client != NONEClient)
{
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(102,0,'****',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(150,47,'停车场',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(16,95,'%s 欢迎到来',%burn",StuName[Client-1],LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
if(gd_Structure.count_gd == GD_MAXNUM)
{
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(16,143,'很抱歉,本停车场车',%burn",LCD_WarningColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(16,193,'位已满,无法进入!',%burn",LCD_WarningColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(YuYin_PlayBuff,0,PLAYNUMBERMAX);
sprintf(YuYin_PlayBuff,"很抱歉,本停车场车位已满,无法进入!");
SYN_FrameInfo(8,YuYin_PlayBuff);
}
else
{
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(22,145,'距离您最近的车位',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(92,193,'%02bu排%02bu号',%burn",gd_Structure.label_pai,gd_Structure.label_hao,LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
SG90_Control(1,ANGLE_90);
memset(YuYin_PlayBuff,0,PLAYNUMBERMAX);
sprintf(YuYin_PlayBuff,"欢迎%s来到****大学",StuName[Client-1]);
SYN_FrameInfo(6,YuYin_PlayBuff);
memset(YuYin_PlayBuff,0,PLAYNUMBERMAX);
sprintf(YuYin_PlayBuff,"距离您最近的车位是%bu排%bu号",gd_Structure.label_pai,gd_Structure.label_hao);
SYN_FrameInfo(6,YuYin_PlayBuff);
delay_ms(2000);
mSt_Structure[Client-1].is_start = TRUE;
mSt_Structure[Client-1].stayTime = 0;
SG90_Control(1,ANGLE_0);
}
}
else
{
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(102,0,'****大学',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(150,47,'停车场',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(16,111,'抱歉,您非本停车场',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(0,175,'注册用户,请先登记!',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
SYN_FrameInfo(5,"抱歉,您的卡已失效,请先去登记");
delay_ms(2000);
}
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); // 51程序中,格式化输入个数不能大于3,否则就出错,很无语!
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(5,97,'本车库总车位:100个',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%burn",100-gd_Structure.count_gd,LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%burn",LCD_TextColor);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
}
Client_Out = rc522Read_Out(); //指纹读取最好在所有检测的最后。!
if(flag_ReceiveCard_Out == TRUE)
{
flag_ReceiveCard_Out = FALSE;
if(Client_Out != NONEClient)
{
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD02_BackColor,LCD02_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(102,0,'****',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(150,47,'停车场',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(26,95,'%s 一路顺风',%burn",StuName[Client_Out-1],LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
SG90_Control(2,ANGLE_90);
if(mSt_Structure[Client_Out-1].is_start)
{
if(mSt_Structure[Client_Out-1].stayTime<=1)
{
mSt_Structure[Client_Out-1].stayPrice=3;
}
else
{
mSt_Structure[Client_Out-1].stayPrice=3+(mSt_Structure[Client_Out-1].stayTime-1)*2;
if(mSt_Structure[Client_Out-1].stayPrice >24)
{
mSt_Structure[Client_Out-1].stayPrice=24;
}
}
if(mSt_Structure[Client_Out-1].leftMoney > mSt_Structure[Client_Out-1].stayPrice)
mSt_Structure[Client_Out-1].leftMoney = mSt_Structure[Client_Out-1].leftMoney - mSt_Structure[Client_Out-1].stayPrice;
else
mSt_Structure[Client_Out-1].leftMoney = 0;
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(22,145,'本次停车:%02bu小时',%burn",mSt_Structure[Client_Out-1].stayTime,LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(0,189,'收费:%02bu元 余额:%03bu元',%burn",mSt_Structure[Client_Out-1].stayPrice,mSt_Structure[Client_Out-1].leftMoney,LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(YuYin_PlayBuff,0,PLAYNUMBERMAX);
sprintf(YuYin_PlayBuff,"%s再见。您本次停车%bu小时,",StuName[Client_Out-1],mSt_Structure[Client_Out-1].stayTime,mSt_Structure[Client_Out-1].stayPrice);
SYN_FrameInfo(7,YuYin_PlayBuff);
memset(YuYin_PlayBuff,0,PLAYNUMBERMAX);
sprintf(YuYin_PlayBuff,"收费:%bu元,期待您的下次光临",mSt_Structure[Client_Out-1].stayPrice);
SYN_FrameInfo(7,YuYin_PlayBuff);
// sprintf(YuYin_PlayBuff,"余额:%bu元,期待您的下次光临",mSt_Structure[Client_Out-1].leftMoney);
// SYN_FrameInfo(7,YuYin_PlayBuff);
mSt_Structure[Client_Out-1].is_start = FALSE;
mSt_Structure[Client_Out-1].stayTime = 0;
mSt_Structure[Client_Out-1].stayPrice = 0;
for(cnt=0;cnt<4;cnt++)
{
E2rom_leftMoney[cnt] = mSt_Structure[cnt].leftMoney;
}
if(sequential_write_flash_in_one_sector(USER_ADDRESS,4,E2rom_leftMoney))
{}
else{}
}
delay_ms(2000);
SG90_Control(2,ANGLE_0);
}
else
{
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD02_BackColor,LCD02_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(102,0,'****',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(150,47,'停车场',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(16,111,'抱歉,卡已失效!',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(38,175,'请重新进行登记!',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
SYN_FrameInfo(5,"抱歉,您的卡已失效,请先去登记");
delay_ms(2000);
}
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD02_BackColor,LCD02_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗)
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); // 51程序中,格式化输入个数不能大于3,否则就出错,很无语!
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(5,97,'本车库总车位:100个',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%burn",100-gd_Structure.count_gd,LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%burn",LCD02_TextColor);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
}
if(checkTime1000Ms())
{
Read_NowTime_Ds1302(date1302); // 时钟不能时刻读取,读取速度太快,影响其它进程,尤其是RFID!!!
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); // 51程序中,格式化输入个数不能大于3,否则就出错,很无语!
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD_DisBuff,0,LCDNUMBERMAX);
sprintf(LCD_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]);
PrintString3(LCD_DisBuff);
LCD_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
sprintf(LCD02_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]);
PrintString4(LCD02_DisBuff);
LCD02_CheckBusy();
}
if(checkTime6000Ms())
{
for(check_time=0;check_time<4;check_time++)
{
if(mSt_Structure[check_time].is_start)
{
mSt_Structure[check_time].stayTime ++;
if(mSt_Structure[check_time].stayTime > 99)
{
mSt_Structure[check_time].stayTime = 99;
}
}
}
}
}
}
uchar rc522Read(void)
{
unsigned char i=0;
uchar rcID = NONEClient; //先清空,再判断卡有没有匹配到存储的人
uint v_LinShi=0;
static uint rcCountTime=0;
static char status=0;
if(rcCountTime == 0)
status = PcdRequest(PICC_REQALL, g_ucTempbuf);//寻卡
rcCountTime ++;
if(rcCountTime == RCREADTIME)
{
rcCountTime =0;
for(i=0;i<4;i++) //卡序列号
{
Xuhao_Panduan[i]=0;
}
if(status == MI_OK ) //若得到卡,则进行判断卡序号
{
status = PcdAnticoll(g_ucTempbuf);//防冲撞
if (status != MI_OK)
{ }
for(i=0;i<4;i++) //卡序列号 显示
{
Xuhao_Panduan[i]=g_ucTempbuf[i];
// v_LinShi = 129+40*i;
// memset(LCD_DisBuff,0,LCDNUMBERMAX);
// sprintf(LCD_DisBuff,"DCV32(%u,97,'%bx',%burn",v_LinShi,Xuhao_Panduan[i],LCD02_TextColor);
// PrintString3(LCD_DisBuff);
// LCD_CheckBusy();
//
// memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
// sprintf(LCD02_DisBuff,"DCV32(%u,97,'%bx',%burn",v_LinShi,Xuhao_Panduan[i],LCD02_TextColor);
// PrintString4(LCD02_DisBuff);
// LCD02_CheckBusy();
}
flag_ReceiveCard = TRUE;
delay_ms(1000); //防抖动--稳定下来后再判断
rcID=Xuhao_Check();
}
else //如果没有得到卡,则重启PCD
{
PcdReset();
PcdAntennaOff();
delay_ms(2);
PcdAntennaOn();
flag_ReceiveCard = FALSE;
}
}
return rcID;
}
uchar Xuhao_Check()
{
uchar i=0;
for(i=0;i<4;i++)
{
if(Xuhao_Panduan[i]==Xuhao_SQL[i])
continue;
else
break;
}
if(i==4)
{
return 1; //识别出为客户1 :绿色卡1
}
for(i=0;i<4;i++)
{
if(Xuhao_Panduan[i]==Xuhao_SQL[i+4])
continue;
else
break;
}
if(i==4)
{
return 2; //识别出为客户2 :绿色卡2
}
for(i=0;i<4;i++)
{
if(Xuhao_Panduan[i]==Xuhao_SQL[i+8])
continue;
else
break;
}
if(i==4)
{
return 3; //识别出为客户3 :白色卡1
}
for(i=0;i<4;i++)
{
if(Xuhao_Panduan[i]==Xuhao_SQL[i+12])
continue;
else
break;
}
if(i==4)
{
return 4; //识别出为客户4 :白色卡2
}
else
{
return NONEClient; //不在数据库内
}
}
uchar rc522Read_Out(void)
{
unsigned char i=0;
uchar rcID_Out = NONEClient; //先清空,再判断卡有没有匹配到存储的人
uint v_LinShi_Out=0;
static uint rcCountTime_Out=0;
static char status_Out=0;
if(rcCountTime_Out == 0)
status_Out = PcdRequest_Out(PICC_REQALL, g_ucTempbuf_Out);//寻卡
rcCountTime_Out ++;
if(rcCountTime_Out >= RCREADTIME)
{
rcCountTime_Out =0;
for(i=0;i<4;i++) //卡序列号
{
Xuhao_Panduan_Out[i]=0;
}
if(status_Out == MI_OK ) //若得到卡,则进行判断卡序号
{
status_Out = PcdAnticoll_Out(g_ucTempbuf_Out);//防冲撞
if (status_Out != MI_OK)
{ }
for(i=0;i<4;i++) //卡序列号 显示
{
Xuhao_Panduan_Out[i]=g_ucTempbuf_Out[i];
// v_LinShi_Out = 129+40*i;
// memset(LCD_DisBuff,0,LCDNUMBERMAX);
// sprintf(LCD_DisBuff,"DCV32(%u,97,'%bx',%burn",v_LinShi_Out,Xuhao_Panduan_Out[i],LCD02_TextColor);
// PrintString3(LCD_DisBuff);
// LCD_CheckBusy();
//
// memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
// sprintf(LCD02_DisBuff,"DCV32(%u,97,'%bx',%burn",v_LinShi_Out,Xuhao_Panduan_Out[i],LCD02_TextColor);
// PrintString4(LCD02_DisBuff);
// LCD02_CheckBusy();
}
flag_ReceiveCard_Out = TRUE;
delay_ms(1000); //防抖动--稳定下来后再判断
rcID_Out=Xuhao_Check_Out();
}
else //如果没有得到卡,则重启PCD
{
PcdReset_Out();
PcdAntennaOff_Out();
delay_ms(2);
PcdAntennaOn_Out();
flag_ReceiveCard_Out = FALSE;
}
}
return rcID_Out;
}
uchar Xuhao_Check_Out()
{
uchar i=0;
for(i=0;i<4;i++)
{
if(Xuhao_Panduan_Out[i]==Xuhao_SQL[i])
continue;
else
break;
}
if(i==4)
{
return 1; //识别出为客户1 :绿色卡1
}
for(i=0;i<4;i++)
{
if(Xuhao_Panduan_Out[i]==Xuhao_SQL[i+4])
continue;
else
break;
}
if(i==4)
{
return 2; //识别出为客户2 :绿色卡2
}
for(i=0;i<4;i++)
{
if(Xuhao_Panduan_Out[i]==Xuhao_SQL[i+8])
continue;
else
break;
}
if(i==4)
{
return 3; //识别出为客户3 :白色卡1
}
for(i=0;i<4;i++)
{
if(Xuhao_Panduan_Out[i]==Xuhao_SQL[i+12])
continue;
else
break;
}
if(i==4)
{
return 4; //识别出为客户4 :白色卡2
}
else
{
return NONEClient; //不在数据库内
}
}
/*******************************************************************/
最后
以上就是矮小斑马为你收集整理的B47 - 基于51单片机的RFID停车计费系统任务摘要实物原理图系统架构模块讲解源代码的全部内容,希望文章能够帮你解决B47 - 基于51单片机的RFID停车计费系统任务摘要实物原理图系统架构模块讲解源代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复