B47 - 基于51单片机的RFID停车计费系统

任务摘要

当今社会,交通压力不断增加,智能停车场管理系统是人们对便捷高效交通的一种追求。本智能停车场管理系统运用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',%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; //不在数据库内
	}
}
/*******************************************************************/

猜你喜欢

转载自blog.csdn.net/qq_20467929/article/details/126139970