任务摘要
当今社会,交通压力不断增加,智能停车场管理系统是人们对便捷高效交通的一种追求。本智能停车场管理系统运用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中文语音合成芯片,其可以接受待合成的文本数据,实现文本到语音的转换,语音合成效果较好。语音播报模块电路如图所示。语音模块使用串口进行数据通信,将要发送的数据使用串口发送给模块即可命令模块进行播放,但要注意发送字节长度有限。
驱动程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30/***************************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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104/***************************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); }
光电检测模块
光电检测逻辑:
驱动程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68#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显示屏上看到系统的时间、总停车位、剩余停车位以及卡片信息等内容。
驱动程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42#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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53#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驱动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154#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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326#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文件就是对于各个驱动的综合调用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047/******************************************************************************* * 文件名称:基于51单片机的RFID停车计费系统 * 实验目的:1. * 2. * 程序说明:完整程序Q:277 227 2579;@: itworkstation@ hotmail.com * 日期版本:本项目分享关键细节,熟悉使用单片机的可做参考代码。完整讲解+源代码工程可联系获取,可定制。 *******************************************************************************/ #include "config.h" #include "UART.h" #include "lcdUart.h" #include "lcdUart02.h" #include "SYN6288.h" #include "ds1302.h" #include "timer.h" #include "SG90.h" #include "RC522.h" #include "RC522OUT.h" #include "guangdian.h" #include "eeprom.h" /************* 本地常量声明 **************/ /*******************测试串口格式化输出方式,51的C是改动版本*********************** unsigned char a = 10; char b = -15 ; unsigned short c = 20; short d = -25; unsigned int e = 65535; int f = -32765; sprintf(LCD_DisBuff,"DCV16(92,50,'欢迎使用基于STM32单片机的自动视力检测仪a=%bu b=%bd c=%hu d=%hd e=%hu f=%hd',%burn",a,b,c,d,e,f,LCD_TextColor); ********************************************************************************/ /************* 本地变量声明 **************/ #define LCDNUMBERMAX 120 char LCD_DisBuff[LCDNUMBERMAX]; #define LCD02NUMBERMAX 120 char LCD02_DisBuff[LCDNUMBERMAX]; #define PLAYNUMBERMAX 120 char YuYin_PlayBuff[PLAYNUMBERMAX]; uchar date1302[]={22,5,8,13,21,0}; #define RCREADTIME 2000 #define NONEClient 0 #define NONECARD 0xff bit flag_ReceiveCard = FALSE,flag_ReceiveCard_Out = FALSE; uchar Client=NONEClient,Client_Out=NONEClient; unsigned char xdata g_ucTempbuf[20],g_ucTempbuf_Out[20]; uchar xdata Xuhao_Panduan[4],Xuhao_Panduan_Out[4]; uchar code Xuhao_SQL[]={ 0x93,0XCC,0X5E,0X1C, // 蓝色卡1 //0xF3,0X1A,0XFA,0X1D, // 蓝色卡2 0X43,0X10,0X3A,0XA7, // 白色卡1 0X93,0X4F,0X4F,0X94, // 白色卡2 }; char code StuName[4][15]={ "***", //制作人姓名 //" 张三xFD", //三字出现乱码,乱码的字需要在对应字后面加xFD //" 赵六", " 李四", " 王五", }; char code StuNumber[4][15]={ "201802010001", // "201802010002", "201802010003", "201802010004", }; #define PRICE 2 //小时价格 typedef struct { FlagState is_start; uchar stayTime; uchar stayPrice; uchar leftMoney; }STRUCT_messageStay; STRUCT_messageStay mSt_Structure[4]; /************* 本地函数声明 **************/ uchar Xuhao_Check(void); uchar rc522Read(void); uchar Xuhao_Check_Out(); uchar rc522Read_Out(void); /************* 外部函数和变量声明 *****************/ /******************* IO配置函数 *******************/ void GPIO_config(void) { GPIO_InitTypeDef GPIO_InitStructure; //结构定义 GPIO_InitStructure.Pin = GPIO_Pin_2 | GPIO_Pin_3; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7 GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP GPIO_Inilize(GPIO_P0,&GPIO_InitStructure); //初始化 GPIO_InitStructure.Pin = GPIO_Pin_0 | GPIO_Pin_1; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7 GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP GPIO_Inilize(GPIO_P0,&GPIO_InitStructure); //初始化 GPIO_InitStructure.Pin = GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_6 |GPIO_Pin_7; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7 GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP GPIO_Inilize(GPIO_P1,&GPIO_InitStructure); //初始化 GPIO_InitStructure.Pin = GPIO_Pin_4; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7 GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP GPIO_Inilize(GPIO_P1,&GPIO_InitStructure); //初始化 } /*************** 串口初始化函数 *****************/ //与以往单片机不同的是,串口也要初始化GPIO!不然不工作哦! void UART_config(void) { COMx_InitDefine COMx_InitStructure; //结构定义 COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx COMx_InitStructure.UART_BRT_Use = BRT_Timer4; //选择波特率发生器, BRT_Timer2, BRT_Timer4 (注意: 串口2固定使用BRT_Timer2) // COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200 COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200 COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE COMx_InitStructure.UART_Interrupt = ENABLE; //中断允许, ENABLE或DISABLE COMx_InitStructure.UART_Priority = Priority_0; //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3 COMx_InitStructure.UART_P_SW = UART4_SW_P02_P03; //切换端口, UART4_SW_P02_P03,UART4_SW_P52_P53 UART_Configuration(UART4, &COMx_InitStructure); //初始化串口4 UART1,UART2,UART3,UART4 // PrintString4("STC8 UART4 Test Programme!rn"); //UART4发送一个字符串 COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx COMx_InitStructure.UART_BRT_Use = BRT_Timer3; //选择波特率发生器, BRT_Timer2, BRT_Timer3 (注意: 串口2固定使用BRT_Timer2) // COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200 COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200 COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE COMx_InitStructure.UART_Interrupt = ENABLE; //中断允许, ENABLE或DISABLE COMx_InitStructure.UART_Priority = Priority_0; //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3 COMx_InitStructure.UART_P_SW = UART3_SW_P00_P01; //切换端口, UART_Configuration(UART3, &COMx_InitStructure); //初始化串口3 UART1,UART2,UART3,UART4 COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx COMx_InitStructure.UART_BRT_Use = BRT_Timer2; //选择波特率发生器, BRT_Timer2, BRT_Timer4 (注意: 串口2固定使用BRT_Timer2) // COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 110 ~ 115200 COMx_InitStructure.UART_BaudRate = 9600; //波特率, 110 ~ 115200 COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE COMx_InitStructure.UART_Interrupt = ENABLE; //中断允许, ENABLE或DISABLE COMx_InitStructure.UART_Priority = Priority_0; //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3 COMx_InitStructure.UART_P_SW = UART2_SW_P10_P11; //切换端口, UART4_SW_P02_P03,UART4_SW_P52_P53 UART_Configuration(UART2, &COMx_InitStructure); //初始化串口4 UART1,UART2,UART3,UART4 } /************************ 定时器配置 ****************************/ void Timer_config(void) { TIM_InitTypeDef TIM_InitStructure; //结构定义 TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask 16位自动重装. TIM_InitStructure.TIM_Priority = Priority_0; //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3 TIM_InitStructure.TIM_Interrupt = ENABLE; //中断是否允许, ENABLE或DISABLE TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_12T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE TIM_InitStructure.TIM_Value = 47104UL; //初值,//47104UL@20毫秒@11.0592MHz@12T时钟 28672UL@20毫秒@22.1184MHz@12T时钟 TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLE Timer_Inilize(Timer0,&TIM_InitStructure); //初始化Timer0 Timer0,Timer1,Timer2,Timer3,Timer4 TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask TIM_InitStructure.TIM_Priority = Priority_0; //指定中断优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3 TIM_InitStructure.TIM_Interrupt = ENABLE; //中断是否允许, ENABLE或DISABLE TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE // TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 10000); //初值, 中断频率为10000HZ,时钟 24MHz TIM_InitStructure.TIM_Value = 60006UL; //初值,60006UL@500微秒@11.0592MHz 54477UL@500微秒@22.1184MHz TIM_InitStructure.TIM_Run = DISABLE; //是否初始化后启动定时器, ENABLE或DISABLE Timer_Inilize(Timer1,&TIM_InitStructure); //初始化Timer1 Timer0,Timer1,Timer2,Timer3,Timer4 } /************************************************************************* 主函数 **************************************************************************/ sbit KEY_IN = P1^6; sbit KEY_OUT = P1^7; void KeyScan(void) { if(KEY_IN==0) { delay_ms(20); if(KEY_IN==0) { if(SG90_Structure.num01_angleX == ANGLE_0) { SG90_Control(1,ANGLE_90); } else { SG90_Control(1,ANGLE_0); } } while(!KEY_IN); } if(KEY_OUT==0) { delay_ms(20); if(KEY_OUT==0) { if(SG90_Structure.num02_angleX == ANGLE_0) { SG90_Control(2,ANGLE_90); } else { SG90_Control(2,ANGLE_0); } } while(!KEY_OUT); } } void ClearData(void) { u8 i; for(i=0;i<4;i++) { mSt_Structure[i].is_start = FALSE; mSt_Structure[i].stayTime = 0; mSt_Structure[i].stayPrice = 0; mSt_Structure[i].leftMoney = 100; } } void InitEPROM_Dis(void) { memset(LCD_DisBuff,0,LCDNUMBERMAX); //IN口屏幕 sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(93,32,'EEPROM',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV24(0,79,'源数据:',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV24(0,143,'读数据:',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); } void EPROMData_Init(void) { u8 i,leftMoney[4]; // InitEPROM_Dis(); for(i=0;i<4;i++) { leftMoney[i] = mSt_Structure[i].leftMoney; } // printf("DCV24(79,79,'%bu,%bu,%bu,%bu',%burn",leftMoney[0],leftMoney[1],leftMoney[2],leftMoney[3],LCD_TextColor); // LCD_CheckBusy(); if(IapReadByte(IAP_ADDRESS)==IAP_ADDRESS_VALUE) //已有金额数据 { for(i=0;i<4;i++) { mSt_Structure[i].leftMoney = IapReadByte(USER_ADDRESS+i); leftMoney[i] = mSt_Structure[i].leftMoney; } // printf("DCV24(79,143,'%bu,%bu,%bu,%bu',%burn",leftMoney[0],leftMoney[1],leftMoney[2],leftMoney[3],LCD_TextColor); // LCD_CheckBusy(); // // printf("DCV24(109,193,'读取成功',%burn",LCD_TextColor); // LCD_CheckBusy(); // // SYN_FrameInfo(3,"余额已读出"); } else { /* 擦除 要修改/写入 的扇区 */ IapEraseSector(IAP_ADDRESS); IapProgramByte(IAP_ADDRESS, IAP_ADDRESS_VALUE); IapIdle(); if(sequential_write_flash_in_one_sector(USER_ADDRESS,4,leftMoney)) { // SYN_FrameInfo(3,"余额已写入成功"); } else { // SYN_FrameInfo(3,"余额写入失败"); } for(i=0;i<4;i++) { mSt_Structure[i].leftMoney = IapReadByte(USER_ADDRESS+i); leftMoney[i] = mSt_Structure[i].leftMoney; } // printf("DCV24(79,143,'%bu,%bu,%bu,%bu',%burn",leftMoney[0],leftMoney[1],leftMoney[2],leftMoney[3],LCD_TextColor); // LCD_CheckBusy(); // // printf("DCV24(109,193,'读取失败',%burn",LCD_TextColor); // LCD_CheckBusy(); } // delay_ms(5000); // memset(LCD_DisBuff,0,LCDNUMBERMAX); // sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) // PrintString3(LCD_DisBuff); // // memset(LCD_DisBuff,0,LCDNUMBERMAX); // sprintf(LCD_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) // PrintString3(LCD_DisBuff); // LCD_CheckBusy(); // // memset(LCD_DisBuff,0,LCDNUMBERMAX); // sprintf(LCD_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); // 51程序中,格式化输入个数不能大于3,否则就出错,很无语! // PrintString3(LCD_DisBuff); // LCD_CheckBusy(); // memset(LCD_DisBuff,0,LCDNUMBERMAX); // sprintf(LCD_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]); // PrintString3(LCD_DisBuff); // LCD_CheckBusy(); // // memset(LCD_DisBuff,0,LCDNUMBERMAX); // sprintf(LCD_DisBuff,"DCV32(5,97,'本车库总车位:100个',%burn",LCD_TextColor); // PrintString3(LCD_DisBuff); // LCD_CheckBusy(); // memset(LCD_DisBuff,0,LCDNUMBERMAX); // sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:100个',%burn",LCD_TextColor); // PrintString3(LCD_DisBuff); // LCD_CheckBusy(); // memset(LCD_DisBuff,0,LCDNUMBERMAX); // sprintf(LCD_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%burn",LCD_TextColor); // PrintString3(LCD_DisBuff); // LCD_CheckBusy(); } void main (void) { u8 E2rom_leftMoney[4],cnt=0; u8 count_gd_last=0; u8 check_time=0; gd_GPIO_Init(); ClearData(); GPIO_config(); UART_config(); EA = 1; delay_ms(1000);//上电等待 1 秒是串口屏模块正常工作的前提,如果没有足够的等待时间模块有可能无法正常的接收指令而导致系统出错。 memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(16,31,'欢迎使用智慧停车库',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(64,97,'****大学',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(48,163,'制作人:***',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD02_BackColor,LCD02_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(16,31,'欢迎使用智慧停车库',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(64,97,'****',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(48,163,'制作人:***',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); delay_ms(1000); YS_SYN_Init(); SYN_FrameInfo(3,"欢迎使用由***制作的停车计费系统"); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString3(LCD_DisBuff); LCD_CheckBusy(); //FSIMG (2097152,0,0,240,320,1); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(82,1,'2022年03月18日',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(99,49,'16时32分50秒',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(5,97,'本车库总车位:100个',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:100个',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD02_BackColor,LCD02_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); Init_Ds1302(date1302); Read_NowTime_Ds1302(date1302); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); // 51程序中,格式化输入个数不能大于3,否则就出错,很无语! PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); // memset(LCD02_DisBuff,0,LCD02NUMBERMAX); // sprintf(LCD02_DisBuff,"DCV32(82,1,'2022年03月18日',%burn",LCD02_TextColor); // PrintString4(LCD02_DisBuff); // LCD02_CheckBusy(); // memset(LCD02_DisBuff,0,LCD02NUMBERMAX); // sprintf(LCD02_DisBuff,"DCV32(99,49,'16时32分50秒',%burn",LCD02_TextColor); // PrintString4(LCD02_DisBuff); // LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(5,97,'本车库总车位:100个',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(5,145,'当前可用车位:100个',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); Timer_config(); SG90_Init(); // SG90_Control(1,ANGLE_90); // delay_ms(1000); // SG90_Control(2,ANGLE_90); // delay_ms(1000); // SG90_Control(1,ANGLE_0); // delay_ms(1000); // SG90_Control(2,ANGLE_0); // delay_ms(1000); InitRC522(); InitRC522_Out(); EPROMData_Init(); while (1) //主循环 { KeyScan(); gd_scan(); //检测车位 if(count_gd_last != gd_Structure.count_gd) { count_gd_last = gd_Structure.count_gd; if(gd_Structure.count_gd == GD_MAXNUM) { memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:000个',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); } else { memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%burn",100-gd_Structure.count_gd,LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%burn",100-gd_Structure.count_gd,LCD_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); } } Client = rc522Read(); //指纹读取最好在所有检测的最后。! if(flag_ReceiveCard == TRUE) { flag_ReceiveCard = FALSE; if(Client != NONEClient) { memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(102,0,'****',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(150,47,'停车场',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(16,95,'%s 欢迎到来',%burn",StuName[Client-1],LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); if(gd_Structure.count_gd == GD_MAXNUM) { memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(16,143,'很抱歉,本停车场车',%burn",LCD_WarningColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(16,193,'位已满,无法进入!',%burn",LCD_WarningColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(YuYin_PlayBuff,0,PLAYNUMBERMAX); sprintf(YuYin_PlayBuff,"很抱歉,本停车场车位已满,无法进入!"); SYN_FrameInfo(8,YuYin_PlayBuff); } else { memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(22,145,'距离您最近的车位',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(92,193,'%02bu排%02bu号',%burn",gd_Structure.label_pai,gd_Structure.label_hao,LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); SG90_Control(1,ANGLE_90); memset(YuYin_PlayBuff,0,PLAYNUMBERMAX); sprintf(YuYin_PlayBuff,"欢迎%s来到****大学",StuName[Client-1]); SYN_FrameInfo(6,YuYin_PlayBuff); memset(YuYin_PlayBuff,0,PLAYNUMBERMAX); sprintf(YuYin_PlayBuff,"距离您最近的车位是%bu排%bu号",gd_Structure.label_pai,gd_Structure.label_hao); SYN_FrameInfo(6,YuYin_PlayBuff); delay_ms(2000); mSt_Structure[Client-1].is_start = TRUE; mSt_Structure[Client-1].stayTime = 0; SG90_Control(1,ANGLE_0); } } else { memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(102,0,'****大学',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(150,47,'停车场',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(16,111,'抱歉,您非本停车场',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(0,175,'注册用户,请先登记!',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); SYN_FrameInfo(5,"抱歉,您的卡已失效,请先去登记"); delay_ms(2000); } memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD_BackColor,LCD_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); // 51程序中,格式化输入个数不能大于3,否则就出错,很无语! PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(5,97,'本车库总车位:100个',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%burn",100-gd_Structure.count_gd,LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%burn",LCD_TextColor); PrintString3(LCD_DisBuff); LCD_CheckBusy(); } Client_Out = rc522Read_Out(); //指纹读取最好在所有检测的最后。! if(flag_ReceiveCard_Out == TRUE) { flag_ReceiveCard_Out = FALSE; if(Client_Out != NONEClient) { memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD02_BackColor,LCD02_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(102,0,'****',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(150,47,'停车场',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(26,95,'%s 一路顺风',%burn",StuName[Client_Out-1],LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); SG90_Control(2,ANGLE_90); if(mSt_Structure[Client_Out-1].is_start) { if(mSt_Structure[Client_Out-1].stayTime<=1) { mSt_Structure[Client_Out-1].stayPrice=3; } else { mSt_Structure[Client_Out-1].stayPrice=3+(mSt_Structure[Client_Out-1].stayTime-1)*2; if(mSt_Structure[Client_Out-1].stayPrice >24) { mSt_Structure[Client_Out-1].stayPrice=24; } } if(mSt_Structure[Client_Out-1].leftMoney > mSt_Structure[Client_Out-1].stayPrice) mSt_Structure[Client_Out-1].leftMoney = mSt_Structure[Client_Out-1].leftMoney - mSt_Structure[Client_Out-1].stayPrice; else mSt_Structure[Client_Out-1].leftMoney = 0; memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(22,145,'本次停车:%02bu小时',%burn",mSt_Structure[Client_Out-1].stayTime,LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(0,189,'收费:%02bu元 余额:%03bu元',%burn",mSt_Structure[Client_Out-1].stayPrice,mSt_Structure[Client_Out-1].leftMoney,LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(YuYin_PlayBuff,0,PLAYNUMBERMAX); sprintf(YuYin_PlayBuff,"%s再见。您本次停车%bu小时,",StuName[Client_Out-1],mSt_Structure[Client_Out-1].stayTime,mSt_Structure[Client_Out-1].stayPrice); SYN_FrameInfo(7,YuYin_PlayBuff); memset(YuYin_PlayBuff,0,PLAYNUMBERMAX); sprintf(YuYin_PlayBuff,"收费:%bu元,期待您的下次光临",mSt_Structure[Client_Out-1].stayPrice); SYN_FrameInfo(7,YuYin_PlayBuff); // sprintf(YuYin_PlayBuff,"余额:%bu元,期待您的下次光临",mSt_Structure[Client_Out-1].leftMoney); // SYN_FrameInfo(7,YuYin_PlayBuff); mSt_Structure[Client_Out-1].is_start = FALSE; mSt_Structure[Client_Out-1].stayTime = 0; mSt_Structure[Client_Out-1].stayPrice = 0; for(cnt=0;cnt<4;cnt++) { E2rom_leftMoney[cnt] = mSt_Structure[cnt].leftMoney; } if(sequential_write_flash_in_one_sector(USER_ADDRESS,4,E2rom_leftMoney)) {} else{} } delay_ms(2000); SG90_Control(2,ANGLE_0); } else { memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD02_BackColor,LCD02_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(102,0,'****',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(150,47,'停车场',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(16,111,'抱歉,卡已失效!',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(38,175,'请重新进行登记!',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); SYN_FrameInfo(5,"抱歉,您的卡已失效,请先去登记"); delay_ms(2000); } memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"CLR(%bu);DIR(3);BL(%bu);rn",LCD02_BackColor,LCD02_Light); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"FSIMG(2097152,0,6,80,80,0);rn"); //CLR(16);DIR(1);BL(10); //白色,横屏,背光10(0-255:最亮:最暗) PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); // 51程序中,格式化输入个数不能大于3,否则就出错,很无语! PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(5,97,'本车库总车位:100个',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(5,145,'当前可用车位:%03bu个',%burn",100-gd_Structure.count_gd,LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(0,193,'本停车场实行刷卡进出',%burn",LCD02_TextColor); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); } if(checkTime1000Ms()) { Read_NowTime_Ds1302(date1302); // 时钟不能时刻读取,读取速度太快,影响其它进程,尤其是RFID!!! memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); // 51程序中,格式化输入个数不能大于3,否则就出错,很无语! PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD_DisBuff,0,LCDNUMBERMAX); sprintf(LCD_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]); PrintString3(LCD_DisBuff); LCD_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(82,1,'20%02bu年%02bu月%02bu日',6rn",(u8)date1302[0],(u8)date1302[1],(u8)date1302[2]); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); memset(LCD02_DisBuff,0,LCD02NUMBERMAX); sprintf(LCD02_DisBuff,"DCV32(99,49,'%02bu时%02bu分%02bu秒',6rn",(u8)date1302[3],(u8)date1302[4],(u8)date1302[5]); PrintString4(LCD02_DisBuff); LCD02_CheckBusy(); } if(checkTime6000Ms()) { for(check_time=0;check_time<4;check_time++) { if(mSt_Structure[check_time].is_start) { mSt_Structure[check_time].stayTime ++; if(mSt_Structure[check_time].stayTime > 99) { mSt_Structure[check_time].stayTime = 99; } } } } } } uchar rc522Read(void) { unsigned char i=0; uchar rcID = NONEClient; //先清空,再判断卡有没有匹配到存储的人 uint v_LinShi=0; static uint rcCountTime=0; static char status=0; if(rcCountTime == 0) status = PcdRequest(PICC_REQALL, g_ucTempbuf);//寻卡 rcCountTime ++; if(rcCountTime == RCREADTIME) { rcCountTime =0; for(i=0;i<4;i++) //卡序列号 { Xuhao_Panduan[i]=0; } if(status == MI_OK ) //若得到卡,则进行判断卡序号 { status = PcdAnticoll(g_ucTempbuf);//防冲撞 if (status != MI_OK) { } for(i=0;i<4;i++) //卡序列号 显示 { Xuhao_Panduan[i]=g_ucTempbuf[i]; // v_LinShi = 129+40*i; // memset(LCD_DisBuff,0,LCDNUMBERMAX); // sprintf(LCD_DisBuff,"DCV32(%u,97,'%bx',%burn",v_LinShi,Xuhao_Panduan[i],LCD02_TextColor); // PrintString3(LCD_DisBuff); // LCD_CheckBusy(); // // memset(LCD02_DisBuff,0,LCD02NUMBERMAX); // sprintf(LCD02_DisBuff,"DCV32(%u,97,'%bx',%burn",v_LinShi,Xuhao_Panduan[i],LCD02_TextColor); // PrintString4(LCD02_DisBuff); // LCD02_CheckBusy(); } flag_ReceiveCard = TRUE; delay_ms(1000); //防抖动--稳定下来后再判断 rcID=Xuhao_Check(); } else //如果没有得到卡,则重启PCD { PcdReset(); PcdAntennaOff(); delay_ms(2); PcdAntennaOn(); flag_ReceiveCard = FALSE; } } return rcID; } uchar Xuhao_Check() { uchar i=0; for(i=0;i<4;i++) { if(Xuhao_Panduan[i]==Xuhao_SQL[i]) continue; else break; } if(i==4) { return 1; //识别出为客户1 :绿色卡1 } for(i=0;i<4;i++) { if(Xuhao_Panduan[i]==Xuhao_SQL[i+4]) continue; else break; } if(i==4) { return 2; //识别出为客户2 :绿色卡2 } for(i=0;i<4;i++) { if(Xuhao_Panduan[i]==Xuhao_SQL[i+8]) continue; else break; } if(i==4) { return 3; //识别出为客户3 :白色卡1 } for(i=0;i<4;i++) { if(Xuhao_Panduan[i]==Xuhao_SQL[i+12]) continue; else break; } if(i==4) { return 4; //识别出为客户4 :白色卡2 } else { return NONEClient; //不在数据库内 } } uchar rc522Read_Out(void) { unsigned char i=0; uchar rcID_Out = NONEClient; //先清空,再判断卡有没有匹配到存储的人 uint v_LinShi_Out=0; static uint rcCountTime_Out=0; static char status_Out=0; if(rcCountTime_Out == 0) status_Out = PcdRequest_Out(PICC_REQALL, g_ucTempbuf_Out);//寻卡 rcCountTime_Out ++; if(rcCountTime_Out >= RCREADTIME) { rcCountTime_Out =0; for(i=0;i<4;i++) //卡序列号 { Xuhao_Panduan_Out[i]=0; } if(status_Out == MI_OK ) //若得到卡,则进行判断卡序号 { status_Out = PcdAnticoll_Out(g_ucTempbuf_Out);//防冲撞 if (status_Out != MI_OK) { } for(i=0;i<4;i++) //卡序列号 显示 { Xuhao_Panduan_Out[i]=g_ucTempbuf_Out[i]; // v_LinShi_Out = 129+40*i; // memset(LCD_DisBuff,0,LCDNUMBERMAX); // sprintf(LCD_DisBuff,"DCV32(%u,97,'%bx',%burn",v_LinShi_Out,Xuhao_Panduan_Out[i],LCD02_TextColor); // PrintString3(LCD_DisBuff); // LCD_CheckBusy(); // // memset(LCD02_DisBuff,0,LCD02NUMBERMAX); // sprintf(LCD02_DisBuff,"DCV32(%u,97,'%bx',%burn",v_LinShi_Out,Xuhao_Panduan_Out[i],LCD02_TextColor); // PrintString4(LCD02_DisBuff); // LCD02_CheckBusy(); } flag_ReceiveCard_Out = TRUE; delay_ms(1000); //防抖动--稳定下来后再判断 rcID_Out=Xuhao_Check_Out(); } else //如果没有得到卡,则重启PCD { PcdReset_Out(); PcdAntennaOff_Out(); delay_ms(2); PcdAntennaOn_Out(); flag_ReceiveCard_Out = FALSE; } } return rcID_Out; } uchar Xuhao_Check_Out() { uchar i=0; for(i=0;i<4;i++) { if(Xuhao_Panduan_Out[i]==Xuhao_SQL[i]) continue; else break; } if(i==4) { return 1; //识别出为客户1 :绿色卡1 } for(i=0;i<4;i++) { if(Xuhao_Panduan_Out[i]==Xuhao_SQL[i+4]) continue; else break; } if(i==4) { return 2; //识别出为客户2 :绿色卡2 } for(i=0;i<4;i++) { if(Xuhao_Panduan_Out[i]==Xuhao_SQL[i+8]) continue; else break; } if(i==4) { return 3; //识别出为客户3 :白色卡1 } for(i=0;i<4;i++) { if(Xuhao_Panduan_Out[i]==Xuhao_SQL[i+12]) continue; else break; } if(i==4) { return 4; //识别出为客户4 :白色卡2 } else { return NONEClient; //不在数据库内 } } /*******************************************************************/
最后
以上就是矮小斑马最近收集整理的关于B47 - 基于51单片机的RFID停车计费系统任务摘要实物原理图系统架构模块讲解源代码的全部内容,更多相关B47内容请搜索靠谱客的其他文章。
发表评论 取消回复