B47 - RFID Parking Billing System Based on 51 MCU

task summary

In today's society, the traffic pressure is increasing, and the intelligent parking lot management system is people's pursuit of convenient and efficient transportation. This intelligent parking lot management system uses RFID technology, adopts STC8H8K64U single-chip microcomputer, RC522, serial port screen, and photoelectric sensor to realize the basic functional requirements of system design. Use photoelectric sensor to detect parking space signal; use RC522 to realize card reading, obtain card information, and check card validity; use LCD serial port screen to display system time and date, cardholder name, total parking space, available parking space, nearest parking space, parking time And charge and card invalid reminder; use the single-chip microcomputer to control the rotation of the steering gear, which means the lifting and falling of the railing; use the single-chip microcomputer to realize automatic deduction from the card, and use voice reminders when vehicles enter and exit. This design is mainly used in residential areas, schools and other places to provide people with convenient and efficient parking services.

When designing the intelligent parking lot management system, software and hardware knowledge are used, including the design of the principle, the connection of each module, the use of RC522 module, the program design of single-chip microcomputer, and the design of display screen interface. After design, adjustment and debugging, this design roughly completed the following indicators:
(1) realized the photoelectric sensor to detect the parking space signal;
(2) realized the RC522 to read the card and detect the validity of the card;
(3) realized the LCD serial port screen Display system time and date, name of cardholder, total parking space, available parking space, nearest parking space, parking time and charge, and card invalidation reminder; (4) Realize voice broadcast reminder
when vehicles enter and exit;
(5) Realize The single-chip microcomputer controls the rotation of the steering gear;
(6) Realizes the automatic deduction of fees from the card by the single-chip microcomputer.

insert image description here

in kind

This system uses a photoelectric sensor for parking space detection, which is small in size, low in cost, easy to use, and suitable for designs with limited IO pins.
Comparative analysis, although the ultrasonic sensor has high precision, but the installation position is fixed, ultrasonic scattering and emission are easy to cause misjudgment and detection error, while the photoelectric sensor is not as accurate as the ultrasonic sensor, but its stability is better, and it is affected by the environment in the indoor parking lot. The influence of factors is small, so under comprehensive consideration, a photoelectric sensor is used.

insert image description here

insert image description here
insert image description here

screen display:
insert image description here

insert image description here
The smallest system board of single-chip microcomputer:
STC8H8V64U single-chip microcomputer is used as the core board of the intelligent parking lot management system. STC8H8V64U has 64 I/O ports and has an ultra-high-speed 8051 core. Since the system uses fewer I/O ports, if the STM32 single-chip microcomputer is used as the core board, the cost performance will not be reflected, resulting in a waste of resources. STC8H8V64U does not require an external crystal oscillator and operates at a frequency of 45MHZ. Therefore, in terms of comprehensive functional requirements and cost performance, this design chooses to use the STC8H8V64U single-chip microcomputer with high cost performance as the core board.

insert image description here

schematic diagram

insert image description here

system structure

The intelligent parking lot management system designed in this system is mainly composed of STC8H8K64U single-chip microcomputer, photoelectric sensor, LCD serial port screen, RC522 radio frequency module, voice broadcast module, DS1302 clock module, steering gear and corresponding drive board and other components. The general block diagram is shown in the figure shown. In this design, the steering gear is used as a railing, and the photoelectric sensor is used to replace the parking space. In this design, 100 parking spaces are virtually set, but due to the limitation of the design area, 9 photoelectric sensors are actually used instead.
insert image description here

Module explanation

voice module

The speech module uses the SYN6288 Chinese speech synthesis chip, which can accept the text data to be synthesized and realize the conversion from text to speech, and the speech synthesis effect is better. The voice broadcast module circuit is shown in the figure. The voice module uses the serial port for data communication. Send the data to be sent to the module through the serial port to order the module to play, but pay attention to the limited length of the sent byte.
insert image description here
driver:

/***************************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);
}





Photoelectric detection module

Photodetection Logic:
insert image description here
Driver:

#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++; 	
	}
}
 

Serial screen

This design uses a 2.4-inch LCD serial port display with a dot matrix resolution of 240*320, which can display pictures and arbitrary graphics at any position on the screen. This module mainly receives and sends data through asynchronous communication through RXD and TXD. In this design, the display module mainly receives data instructions given by the single-chip microcomputer STC8H. The LCD display module is used to realize the display of some data by the single-chip microcomputer. The intelligent parking lot management system can directly see the system time, total parking spaces, remaining parking spaces and card information on the LCD display.
insert image description here

driver:

#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 driver

#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);
}



source code

The main program main.c file is a comprehensive call for each driver.

/*******************************************************************************

\* 文件名称:基于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',%bu\r\n",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!\r\n");	//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);\r\n",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',%bu\r\n",LCD_TextColor);
	PrintString3(LCD_DisBuff);
	LCD_CheckBusy(); 
	
	memset(LCD_DisBuff,0,LCDNUMBERMAX);
	sprintf(LCD_DisBuff,"DCV24(0,79,'源数据:',%bu\r\n",LCD_TextColor);
	PrintString3(LCD_DisBuff);
	LCD_CheckBusy(); 
	
	memset(LCD_DisBuff,0,LCDNUMBERMAX);
	sprintf(LCD_DisBuff,"DCV24(0,143,'读数据:',%bu\r\n",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',%bu\r\n",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',%bu\r\n",leftMoney[0],leftMoney[1],leftMoney[2],leftMoney[3],LCD_TextColor);
//		LCD_CheckBusy(); 
//		
//		printf("DCV24(109,193,'读取成功',%bu\r\n",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',%bu\r\n",leftMoney[0],leftMoney[1],leftMoney[2],leftMoney[3],LCD_TextColor);
//		LCD_CheckBusy(); 
//		
//		printf("DCV24(109,193,'读取失败',%bu\r\n",LCD_TextColor);
//		LCD_CheckBusy(); 
	}
//	delay_ms(5000);
//	memset(LCD_DisBuff,0,LCDNUMBERMAX);
//	sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);\r\n",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);\r\n"); //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日',6\r\n",(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秒',6\r\n",(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个',%bu\r\n",LCD_TextColor);
//	PrintString3(LCD_DisBuff);
//	LCD_CheckBusy(); 
//	memset(LCD_DisBuff,0,LCDNUMBERMAX);
//	sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:100个',%bu\r\n",LCD_TextColor);
//	PrintString3(LCD_DisBuff);
//	LCD_CheckBusy(); 
//	memset(LCD_DisBuff,0,LCDNUMBERMAX);
//	sprintf(LCD_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%bu\r\n",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);\r\n",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,'欢迎使用智慧停车库',%bu\r\n",LCD_TextColor);
	PrintString3(LCD_DisBuff);
	LCD_CheckBusy(); 
	memset(LCD_DisBuff,0,LCDNUMBERMAX);
	sprintf(LCD_DisBuff,"DCV32(64,97,'****大学',%bu\r\n",LCD_TextColor);
	PrintString3(LCD_DisBuff);
	LCD_CheckBusy(); 
	memset(LCD_DisBuff,0,LCDNUMBERMAX);
	sprintf(LCD_DisBuff,"DCV32(48,163,'制作人:***',%bu\r\n",LCD_TextColor);
	PrintString3(LCD_DisBuff);
	LCD_CheckBusy(); 
	
	memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
	sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);\r\n",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,'欢迎使用智慧停车库',%bu\r\n",LCD02_TextColor);
	PrintString4(LCD02_DisBuff);
	LCD02_CheckBusy(); 
	memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
	sprintf(LCD02_DisBuff,"DCV32(64,97,'****',%bu\r\n",LCD02_TextColor);
	PrintString4(LCD02_DisBuff);
	LCD02_CheckBusy(); 
	memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
	sprintf(LCD02_DisBuff,"DCV32(48,163,'制作人:***',%bu\r\n",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);\r\n",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);\r\n"); //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日',%bu\r\n",LCD_TextColor);
	PrintString3(LCD_DisBuff);
	LCD_CheckBusy(); 
	memset(LCD_DisBuff,0,LCDNUMBERMAX);
	sprintf(LCD_DisBuff,"DCV32(99,49,'16时32分50秒',%bu\r\n",LCD_TextColor);
	PrintString3(LCD_DisBuff);
	LCD_CheckBusy(); 
	memset(LCD_DisBuff,0,LCDNUMBERMAX);
	sprintf(LCD_DisBuff,"DCV32(5,97,'本车库总车位:100个',%bu\r\n",LCD_TextColor);
	PrintString3(LCD_DisBuff);
	LCD_CheckBusy(); 
	memset(LCD_DisBuff,0,LCDNUMBERMAX);
	sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:100个',%bu\r\n",LCD_TextColor);
	PrintString3(LCD_DisBuff);
	LCD_CheckBusy(); 
	memset(LCD_DisBuff,0,LCDNUMBERMAX);
	sprintf(LCD_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%bu\r\n",LCD_TextColor);
	PrintString3(LCD_DisBuff);
	LCD_CheckBusy(); 
	
	memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
	sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);\r\n",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);\r\n"); //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日',6\r\n",(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秒',6\r\n",(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日',6\r\n",(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秒',6\r\n",(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日',%bu\r\n",LCD02_TextColor);
//	PrintString4(LCD02_DisBuff);
//	LCD02_CheckBusy(); 
//	memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
//	sprintf(LCD02_DisBuff,"DCV32(99,49,'16时32分50秒',%bu\r\n",LCD02_TextColor);
//	PrintString4(LCD02_DisBuff);
//	LCD02_CheckBusy(); 

	memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
	sprintf(LCD02_DisBuff,"DCV32(5,97,'本车库总车位:100个',%bu\r\n",LCD02_TextColor);
	PrintString4(LCD02_DisBuff);
	LCD02_CheckBusy(); 
	memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
	sprintf(LCD02_DisBuff,"DCV32(5,145,'当前可用车位:100个',%bu\r\n",LCD02_TextColor);
	PrintString4(LCD02_DisBuff);
	LCD02_CheckBusy(); 
	memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
	sprintf(LCD02_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%bu\r\n",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个',%bu\r\n",LCD_TextColor);
					PrintString3(LCD_DisBuff);
					LCD_CheckBusy(); 
				}
				else
				{
    
    
					memset(LCD_DisBuff,0,LCDNUMBERMAX);
					sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%bu\r\n",100-gd_Structure.count_gd,LCD_TextColor);
					PrintString3(LCD_DisBuff);
					LCD_CheckBusy(); 
					
					memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
					sprintf(LCD02_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%bu\r\n",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);\r\n",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);\r\n"); //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,'****',%bu\r\n",LCD_TextColor);
					PrintString3(LCD_DisBuff);
					LCD_CheckBusy(); 
					memset(LCD_DisBuff,0,LCDNUMBERMAX);
					sprintf(LCD_DisBuff,"DCV32(150,47,'停车场',%bu\r\n",LCD_TextColor);
					PrintString3(LCD_DisBuff);
					LCD_CheckBusy(); 
					memset(LCD_DisBuff,0,LCDNUMBERMAX);
					sprintf(LCD_DisBuff,"DCV32(16,95,'%s    欢迎到来',%bu\r\n",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,'很抱歉,本停车场车',%bu\r\n",LCD_WarningColor);
						PrintString3(LCD_DisBuff);
						LCD_CheckBusy();
						
						memset(LCD_DisBuff,0,LCDNUMBERMAX);
						sprintf(LCD_DisBuff,"DCV32(16,193,'位已满,无法进入!',%bu\r\n",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,'距离您最近的车位',%bu\r\n",LCD_TextColor);
						PrintString3(LCD_DisBuff);
						LCD_CheckBusy(); 
						memset(LCD_DisBuff,0,LCDNUMBERMAX);
						sprintf(LCD_DisBuff,"DCV32(92,193,'%02bu排%02bu号',%bu\r\n",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);\r\n",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);\r\n"); //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,'****大学',%bu\r\n",LCD_TextColor);
					PrintString3(LCD_DisBuff);
					LCD_CheckBusy(); 
					memset(LCD_DisBuff,0,LCDNUMBERMAX);
					sprintf(LCD_DisBuff,"DCV32(150,47,'停车场',%bu\r\n",LCD_TextColor);
					PrintString3(LCD_DisBuff);
					LCD_CheckBusy(); 
					memset(LCD_DisBuff,0,LCDNUMBERMAX);
					sprintf(LCD_DisBuff,"DCV32(16,111,'抱歉,您非本停车场',%bu\r\n",LCD_TextColor);
					PrintString3(LCD_DisBuff);
					LCD_CheckBusy(); 
					memset(LCD_DisBuff,0,LCDNUMBERMAX);
					sprintf(LCD_DisBuff,"DCV32(0,175,'注册用户,请先登记!',%bu\r\n",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);\r\n",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);\r\n"); //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日',6\r\n",(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秒',6\r\n",(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个',%bu\r\n",LCD_TextColor);
				PrintString3(LCD_DisBuff);
				LCD_CheckBusy(); 
				memset(LCD_DisBuff,0,LCDNUMBERMAX);
				sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%bu\r\n",100-gd_Structure.count_gd,LCD_TextColor);
				PrintString3(LCD_DisBuff);
				LCD_CheckBusy(); 
				memset(LCD_DisBuff,0,LCDNUMBERMAX);
				sprintf(LCD_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%bu\r\n",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);\r\n",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,'****',%bu\r\n",LCD02_TextColor);
					PrintString4(LCD02_DisBuff);
					LCD02_CheckBusy(); 
					memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
					sprintf(LCD02_DisBuff,"DCV32(150,47,'停车场',%bu\r\n",LCD02_TextColor);
					PrintString4(LCD02_DisBuff);
					LCD02_CheckBusy(); 
					memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
					sprintf(LCD02_DisBuff,"DCV32(26,95,'%s    一路顺风',%bu\r\n",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小时',%bu\r\n",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元',%bu\r\n",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);\r\n",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);\r\n"); //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,'****',%bu\r\n",LCD02_TextColor);
					PrintString4(LCD02_DisBuff);
					LCD02_CheckBusy(); 
					memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
					sprintf(LCD02_DisBuff,"DCV32(150,47,'停车场',%bu\r\n",LCD02_TextColor);
					PrintString4(LCD02_DisBuff);
					LCD02_CheckBusy(); 
					memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
					sprintf(LCD02_DisBuff,"DCV32(16,111,'抱歉,卡已失效!',%bu\r\n",LCD02_TextColor);
					PrintString4(LCD02_DisBuff);
					LCD02_CheckBusy(); 
					memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
					sprintf(LCD02_DisBuff,"DCV32(38,175,'请重新进行登记!',%bu\r\n",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);\r\n",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);\r\n"); //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日',6\r\n",(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秒',6\r\n",(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个',%bu\r\n",LCD02_TextColor);
				PrintString4(LCD02_DisBuff);
				LCD02_CheckBusy(); 
				memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
				sprintf(LCD02_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%bu\r\n",100-gd_Structure.count_gd,LCD02_TextColor);
				PrintString4(LCD02_DisBuff);
				LCD02_CheckBusy(); 
				memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
				sprintf(LCD02_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%bu\r\n",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日',6\r\n",(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秒',6\r\n",(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日',6\r\n",(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秒',6\r\n",(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',%bu\r\n",v_LinShi,Xuhao_Panduan[i],LCD02_TextColor);
//				PrintString3(LCD_DisBuff);
//				LCD_CheckBusy(); 
//							
//				memset(LCD02_DisBuff,0,LCD02NUMBERMAX);
//				sprintf(LCD02_DisBuff,"DCV32(%u,97,'%bx',%bu\r\n",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',%bu\r\n",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',%bu\r\n",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; //不在数据库内
	}
}
/*******************************************************************/

Guess you like

Origin blog.csdn.net/qq_20467929/article/details/126139970