智能停车场设计 - 图文

更新时间:2024-05-12 12:47:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

齐齐哈尔大学

题 目: 智能停车场系统的设计

作者姓名: 敖 健

学 号: 2012131071

单 位: 通信与电子工程学院

指导教师: 张 劲 松

2015年5月 20日

创新杯(论文)

目 录

1. 引 言 ................................................. 1 2. 相关背景 .............................................. 1

2.1 停车场管理系统概述 ......................................... 1 2.2 研究意义以及前景 ........................................... 2

3. 方案论证 .............................................. 2

3.1 总体论证 ................................................... 2

3.1.1 设计要求 ............................................ 2 3.1.2实现方案 ............................................ 2 3.2 方案分析 ................................................... 2

3.2.1检测探头的选用 ...................................... 2 3.2.2从机微处理器的选用 .................................. 2 3.2.3从机显示模块选择 .................................... 3

4. 系统设计 .............................................. 3

4.1 硬件设计 ................................................... 3

4.1.1系统模型 ............................................ 3 4.1.2硬件简介 ............................................ 3

5. 结 论 ................................................. 5 附 录 ................................................... 7

1

摘 要

本文将介绍基于51单片机的智能停车场系统设计,重点是方案论证、系统设计及优化几个方面。

整个智能停车场系统,分为四大模块:IC读卡器控制模块、12864液晶显示模块、步进电机控制模块、红外线控制模块。12864液晶显示模块以微控制器51单片机为核心,采集各停车位车辆的信息指导车主停车;IC读卡器控制模块通过读取IC卡信息实现身份验证、门控等功能;

关键词:智能停车场系统;IC读卡;51单片机;12864液晶显示屏

2

智能停车场管理系统

1. 引 言

随着科学技术的不断发展和人们生活水平的提高,汽车数量迅速增加,车位日益紧张,给人们日常停车带来了诸多麻烦,迫切需要高级停车场和智能的停车管理系统。

然而目前大部分停车场不仅规模小且相对分散,停车管理存在以下弊端: 1、人们不能及时掌握各停车场的信息 2、在进入停车场时更不能及时找到空车位 3、服务质量不高,车辆进出混乱

该智能停车场管理系统将会克服上述不足,设计更智能化、人性化。不仅给车主停车和管理停车场带来了方便,更能充分利用车位资源,减少了拥堵,改善了交通秩序。

2. 相关背景

随着中国现代化进程的加快,各停车场车流量日渐增多,单单依靠人工管理,其日常保安与管理工作也日渐繁重。现代企业和政府管理部门为树立良好的形象,对所辖小区进行规范的现代化管理,已广泛地采用智能停车场,对出入车辆的进行高效管制。

2.1 停车场管理系统概述

智能停车场管理系统是一种高效快捷、公正准确、科学经济的停车场管理手段,是停车场对于车辆实行动态和静态管理的综合。从用户的角度看,其服务高效;从管理者的角度看,其易于操作维护、动化程度高、大大减轻管理者的劳动强度。

采用先进的单片机控制,从高标准、高可靠、高安全的设备,利用了高度自动化的机电和微机设备对停车场进行安全、有效的管理,包括、保安、监控、防盗等。

1

2.2 研究意义以及前景

随着科技的进步和人类文明的发展,大型停车场在住宅小区、大厦、机关单位的应用越来越普遍。而人们对停车场管理的要求也越来越高,智能化程度也越来越高,使用更加方便快捷,也给人类的生活带来了方便和快乐。不仅提高了现代人类的工作效率,也大大的节约了人力物力,价低了公司的运营成本,并使得整个停车场安全可靠,因此该智能停车场管理系统将会得到极大的推广。

3. 方案论证

3.1 总体论证 3.1.1 设计要求

设计一款具备停车指导,安全监控的智能停车场管理系统。 3.1.2实现方案

为了实现以上功能从大的方面有以下三个方案可供选择:

方案一:采用高端CPU利用Internet网络进行信息传输和远程监控。 方案二:采用廉价51单片机对各个车位进行信息采集同时利用电力线载波通信技术或无线网络技术进行信息传输和控制,并将信息提交的主控单片机进行。

方案三:采用廉价 51单片机对各个车位进行信息采集并提供给将寻找车位的车主。

比较:方案一该设计智能化程度高、控制相当准确,便于与网络连接;但是施工工程量很大,费用高;方案二避免了布线安装施工的困难,但成本高,网络性能一般;方案三不仅技术成熟、成本低廉而且通信性能高布线简单,易于实现。

通过以上比较决定采用方案三。 3.2 方案分析

3.2.1检测探头的选用

红外检测原理实现简单、成本低廉,利用红外线控制模块检测车辆不仅抗干扰性强、检测距离远,提高智能化程度,故在停车位选用红外控制模块检测,在停车场门口选用IC读卡控制模块控制车辆出入。

3.2.2从机微处理器的选用

单片机选用深圳宏晶的STC89C52。此单片机与AT89C52完全兼容,而且

2

STC89C52功能更强、更稳定,特别的一点是STC系列单片机支持串口在线编程功能,且价格与AT89C52相当,故选用STC89C52为控制核心。

3.2.3从机显示模块选择

选用12864液晶显示器,功耗低,显示功能强大。

4. 系统设计

4.1 硬件设计 4.1.1系统模型

图1系统整体模型图

使相对分散的停车场形成一个统一的整体,便于调度和协调。停车场内部自成独立的系统适用于小型停车场和独立停车场,扩大了适用范围,此外本系统具有良好的扩展性,便于和监控系统的对接,使其更具有推广应用价值。

4.1.2硬件简介 (1)单片机STC89C52

STC89C52单片机是深圳宏晶科技代理美国一家高科技公司的产品,它具有无法解密、超低功耗、高速高可靠、抗静电抗干扰的众多优点。而且STC89C52向下完全兼容ATMEL公司的AT89C52,其中STC89C52支持串口在线编程的功

3

能给实验者带来了很大的方便。内置8K的FLASH程序存储器更是能够反复擦鞋10000次,使实验者不必担心FLASH存储器的老化。

下面是STC89C52的引脚定义:

(2)IC读卡器模块

RFID系列的rc522射频读卡器,是采用先进的射频接收线路设计及嵌入式微控制器,结合高效解码算法,完成对64bits Read-Only EM4100兼容式ID卡的接收,具有接收灵敏度高,工作电流小,单直流电源供电,低价位高性能等特点,适用于门禁,巡更等各种射频应用领域。有效距离10cm以上,在有效距离内数据接收时间小于100ms,单直流电源+5V供电,工作电流小于70mA。

接口描述:

IC读卡器接口定义

4

5. 结 论

本设计利用微型计算机作上位机提供友好的人机界面、语音服务、网络服务,对停车场的管理和监控更加人性化、智能化、合理化,真正实现了对停车场的综合控制管理。而且本系统利用性能可靠、价格廉价的51单片机作从机微处理器降低了系统成本,便于普通小区普及应用。

系统参数: 工作电压: 磁卡有效距离:

220V,50Hz 10cm

红外检测探头: 3cm

5

致 谢

本设计的顺利完成得到了院系领导老师的大力支持和帮助,尤其是我的张劲松老师在百忙之中抽出宝贵的休息时间,仔细耐心地指导我、鼓励我、让我有了解决问题的信心,使设计得以顺利的完成。

本设计的过程中曾多次与同学探讨问题,通过探讨使自己的想法更完善。另外,我院学生创新实验室的全体师生,也为本设计提供了很大的帮助,在模型的制作中我的女朋友也参与其中帮助我完成了模型制作。在此,对他们表示由衷的感谢!

电子信息技术日新月异地飞速发展,人们总是处在不断学习阶段,再加上我水平有限,所以本设计肯定存在许多不尽如人意的地方,欢迎广大老师和同学批评指正。

最后,我在这里要感谢系里的所有老师,是他们精心的栽培与悉心指导为我以后的学习、工作打下了坚实的基础。

谢谢通信与电子信息工程学院所有老师。

6

附 录

实物图:

7

智能停车场管理系统程序:

12864液晶显示程序: #ifndef __LCD12864_H #define __LCD12864_H

//---包含头文件---// #include\

//---重定义关键词---// #ifndef uchar

#define uchar unsigned char #endif

#ifndef uint

#define uint unsigned int #endif

//---如果使用画图模式定义这个---//

//#define LCD12864_PICTURE

//---定义使用的IO口---//

#define LCD12864_DATAPORT P1

sbit LCD12864_RS = P0^7; //(数据命令)寄存器选择输入 sbit LCD12864_RW = P0^6; //液晶读/写控制 sbit LCD12864_EN = P0^5; //液晶使能控制 sbit LCD12864_PSB = P3^5; //串/并方式控制 sbit LCD12864_RST = P3^4;

//---声明全局函数---//

void LCD12864_Delay1ms(uint c); uchar LCD12864_Busy(void);

void LCD12864_WriteCmd(uchar cmd); void LCD12864_WriteData(uchar dat); void LCD12864_Init();

void LCD12864_ClearScreen(void);

void LCD12864_SetWindow(uchar x, uchar y); #endif

//复位端

//数据IO口

8

#include\

/******************************************************************************* * 函 数 名 : LCD12864_Delay1ms * 函数功能

* 输 入 : c * 输 出 : 无

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

void LCD12864_Delay1ms(uint c) {

uchar a,b; }

/******************************************************************************* * 函 数 名 : LCD12864_Busy * 函数功能

* 输 入 : 无

* 输 出 : 1或0(1表示不忙,0表示忙)

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

uchar LCD12864_Busy(void) {

while((LCD12864_DATAPORT & 0x80) == 0x80) {

i++; if(i > 100) {

LCD12864_EN = 0;

return 0; //超过等待时间返回0表示//检测读取到的值

LCD12864_EN = 1; LCD12864_Delay1ms(1); LCD12864_RS = 0; LCD12864_RW = 1;

//选择命令 //选择读取

uchar i = 0;

: 检测LCD是否忙

for(; c>0; c--) {

for(b=199; b>0; b--)

for(a=1; a>0; a--); }

} {

: 延时1MS

9

失败 }

/******************************************************************************* * 函 数 名 : LCD12864_WriteCmd * 函数功能

* 输 入 : cmd * 输 出 : 无

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

void LCD12864_WriteCmd(uchar cmd) { }

/******************************************************************************* * 函 数 名 : LCD12864_WriteData * 函数功能

* 输 入 : dat

: 写数据

LCD12864_EN = 1; LCD12864_Delay1ms(5); LCD12864_EN = 0;

//写时序

LCD12864_DATAPORT = cmd; //放置数据 uchar i; i = 0;

while( LCD12864_Busy() == 0) { }

LCD12864_RS = 0; //选择命令 LCD12864_RW = 0; //选择写入 LCD12864_EN = 0; //初始化使能端

LCD12864_Delay1ms(1); i++; if( i>100) {

return; //超过等待退出 }

: 写命令

return 1; LCD12864_EN = 0; }

}

10

* 输 出 : 无

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

void LCD12864_WriteData(uchar dat) { }

/******************************************************************************* * 函 数 名 : LCD12864_ReadData * 函数功能

* 输 入 : 无

* 输 出 : 读取到的8位数据

*******************************************************************************/ #ifdef LCD12864_PICTURE

uchar LCD12864_ReadData(void) {

i = 0;

while( LCD12864_Busy() == 0) {

LCD12864_Delay1ms(1); i++;

uchar i, readValue;

: 读取数据

LCD12864_EN = 1; LCD12864_Delay1ms(5); LCD12864_EN = 0;

//写时序

LCD12864_DATAPORT = dat; //放置数据 LCD12864_RS = 1; //选择数据 LCD12864_RW = 0; //选择写入 LCD12864_EN = 0; //初始化使能端 uchar i; i = 0;

while( LCD12864_Busy() == 0) { }

LCD12864_Delay1ms(1); i++; if( i>100) {

return; //超过等待退出 }

11

} #endif

/******************************************************************************* * 函 数 名 : LCD12864_Init * 函数功能

* 输 入 : 无 * 输 出 : 无

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

void LCD12864_Init() { }

/******************************************************************************* * 函 数 名 : LCD12864_SetWindow * 函数功能

标。注意:x是设置行,y是设置列 * 输 入 : x, y * 输 出 : 无

: 设置在基本指令模式下设置显示坐

LCD12864_WriteCmd(0x30); //选择基本指令操作 LCD12864_WriteCmd(0x0c); //显示开,关光标

LCD12864_WriteCmd(0x01); //清除LCD12864的显示内容 LCD12864_PSB = 1; LCD12864_RST = 1;

//选择并行输入 //复位

: 初始化LCD12864

return readValue; LCD12864_EN = 1; LCD12864_Delay1ms(1);

readValue = LCD12864_DATAPORT; LCD12864_EN = 0;

LCD12864_RS = 1; //选择命令 LCD12864_RW = 1; LCD12864_EN = 0;

LCD12864_Delay1ms(1); //等待 }

if( i>100) {

return 0; //超过等待退出 }

12

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

void LCD12864_SetWindow(uchar x, uchar y) { }

RC522射频读卡器程序: #include \#include \#include \

#define MAXRLEN 18

sbit MF522_NSS = P0^0; sbit MF522_SCK = P0^1;

sbit MF522_SI = P0^2; //MOSI sbit MF522_SO = P0^3; //MISO sbit MF522_RST = P0^4;

///////////////////////////////////////////////////////////////////// //功 能:寻卡

//SDA

if(x == 0) { }

else if(x == 1) //第二行的地址是90H { }

else if(x == 2) //第三行的地址是88H { }

else if(x == 3) { }

pos = x + y;

LCD12864_WriteCmd(pos);

x = 0x98; x = 0x88; x = 0x90;

x = 0x80;

// 第一行的地址是80H

uchar pos;

13

//说明参数: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

///////////////////////////////////////////////////////////////////// PICC_REQIDL char PcdRequest(unsigned char req_code,unsigned char *pTagType) {

char status; unsigned int unLen;

unsigned char 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

/////////////////////////////////////////////////////////////////////

}

//idata

//idata

//idata

14

char PcdAnticoll(unsigned char *pSnr) {

char status;

unsigned char i,snr_check=0; unsigned int unLen;

unsigned char 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; }

///////////////////////////////////////////////////////////////////// //功 能:选定卡片

//参数说明: pSnr[IN]:卡片序列号 4字节 //返 回:成功返回MI_OK

///////////////////////////////////////////////////////////////////// char PcdSelect(unsigned char *pSnr) {

char status; unsigned char i; unsigned int unLen;

unsigned char ucComMF522Buf[MAXRLEN];

//idata //idata //idata //idata

15

ucComMF522Buf[0] = PICC_ANTICOLL1; ucComMF522Buf[1] = 0x70; ucComMF522Buf[6] = 0; for (i=0; i<4; i++) {

ucComMF522Buf[i+2] = *(pSnr+i); ucComMF522Buf[6] ^= *(pSnr+i); }

CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);

ClearBitMask(Status2Reg,0x08);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);

if ((status == MI_OK) && (unLen == 0x18)) { status = MI_OK; } else

{ status = MI_ERR; }

return status; }

///////////////////////////////////////////////////////////////////// //功 能:验证卡片密码

//参数说明: auth_mode[IN]:密码验证模式 // 0x60 = 验证A秘钥 // 0x61 = 验证B秘钥 // addr[IN]:块地址 // pKey[IN]:密码

// pSnr[IN]:卡片序列号 4字节 //返 回: 成功返回MI_OK

/////////////////////////////////////////////////////////////////////

char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr) {

char status;

unsigned int unLen; unsigned char i ;

unsigned char ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = auth_mode; ucComMF522Buf[1] = addr; for (i=0; i<6; i++)

{ ucComMF522Buf[i+2] = *(pKey+i); } for (i=0; i<6; i++)

{ ucComMF522Buf[i+8] = *(pSnr+i); } // memcpy(&ucComMF522Buf[2], pKey, 6);

//idata //idata

//idata

16

// memcpy(&ucComMF522Buf[8], pSnr, 4);

status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen); if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))) { status = MI_ERR; }

return status; }

///////////////////////////////////////////////////////////////////// //功能:读取MI卡一块数据 //参数说明: addr[IN]:块地址·

// pData[OUT]:读出的数据,16数据 //返回:成功返回MI_OK

///////////////////////////////////////////////////////////////////// char PcdRead(unsigned char addr,unsigned char *pData) {

char status;

unsigned int unLen; //idata unsigned char i;

unsigned char ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = PICC_READ; ucComMF522Buf[1] = addr;

CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); if ((status == MI_OK) && (unLen == 0x90)) // { memcpy(pData, ucComMF522Buf, 16); } {

for (i=0; i<16; i++)

{ *(pData+i) = ucComMF522Buf[i];} } else

{ status = MI_ERR; }

return status; }

//idata //idata

///////////////////////////////////////////////////////////////////// //功 能:写数据到MI卡一块 //参数说明: addr[IN]:块地址

// pData[IN]:写入数据 16字节 //返 回: 成功返回MI_OK

///////////////////////////////////////////////////////////////////// char PcdWrite(unsigned char addr, unsigned char *pData)

17

{

char status;

unsigned int unLen;

unsigned char i,ucComMF522Buf[MAXRLEN];

ucComMF522Buf[0] = PICC_WRITE; ucComMF522Buf[1] = addr;

CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; }

if (status == MI_OK) {

//memcpy(ucComMF522Buf, pData, 16); for (i=0; i<16; i++)

{ ucComMF522Buf[i] = *(pData+i); }

CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen); if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; } }

return status; }

//功 能:扣款和充值

//参数说明: dd_mode[IN]命令字 // 0xC0 = 扣款 // 0xC1 = 充值 // addr[IN]:钱包地址

// pValue[IN]4字节增(减)值,低位在前 //返 回: 成功返回MI_OK

///////////////////////////////////////////////////////////////////// char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue) {

char status;

unsigned int unLen;

unsigned char i,ucComMF522Buf[MAXRLEN];

ucComMF522Buf[0] = dd_mode; ucComMF522Buf[1] = addr;

/////////////////////////////////////////////////////////////////////

18

CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; }

if (status == MI_OK) {

// memcpy(ucComMF522Buf, pValue, 4); for (i=0; i<16; i++)

{ ucComMF522Buf[i] = *(pValue+i);}

CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]); unLen = 0;

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen); if (status != MI_ERR) { status = MI_OK; } }

if (status == MI_OK) {

ucComMF522Buf[0] = PICC_TRANSFER; ucComMF522Buf[1] = addr;

CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; } }

return status; }

///////////////////////////////////////////////////////////////////// //用MF522计算crc16函数

/////////////////////////////////////////////////////////////////////

void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData) {

unsigned char i,n;

ClearBitMask(DivIrqReg,0x04); WriteRawRC(CommandReg,PCD_IDLE); SetBitMask(FIFOLevelReg,0x80); for (i=0; i

{ WriteRawRC(FIFODataReg, *(pIndata+i)); } WriteRawRC(CommandReg, PCD_CALCCRC); i = 0xFF;

19

do {

n = ReadRawRC(DivIrqReg); i--; }

while ((i!=0) && !(n&0x04));

pOutData[0] = ReadRawRC(CRCResultRegL); pOutData[1] = ReadRawRC(CRCResultRegM); }

///////////////////////////////////////////////////////////////////// //功 能:复位RC522 //返 回: 成功返回MI_OK

///////////////////////////////////////////////////////////////////// char PcdReset(void) {

MF522_RST=0;

MF522_RST=1;

_nop_();

_nop_();

_nop_();

_nop_();

//unsigned char i; MF522_RST=1;

WriteRawRC(CommandReg,PCD_RESETPHASE);

WriteRawRC(ModeReg,0x3D); //oíMifare?¨í¨??£?CRC3?ê??μ0x6363 WriteRawRC(TReloadRegL,30); WriteRawRC(TReloadRegH,0); WriteRawRC(TModeReg,0x8D); WriteRawRC(TPrescalerReg,0x3E); WriteRawRC(TxAutoReg,0x40); return MI_OK; }

///////////////////////////////////////////////////////////////////// //功 能:读RC632寄存器

20

//参数说明: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);

21

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 }

/////////////////////////////////////////////////////////////////////

22

//功 能:通过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

{ WriteRawRC(FIFODataReg, pInData[i]); } WriteRawRC(CommandReg, Command);

if (Command == PCD_TRANSCEIVE)

{ SetBitMask(BitFramingReg,0x80); }

23

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) {

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

{ pOutData[i] = ReadRawRC(FIFODataReg); } } } else

{ status = MI_ERR; } }

SetBitMask(ControlReg,0x80); // stop timer now WriteRawRC(CommandReg,PCD_IDLE); return status; }

n = ReadRawRC(FIFOLevelReg);

lastBits = ReadRawRC(ControlReg) & 0x07;

24

///////////////////////////////////////////////////////////////////// // 开启天线

//每次启动或关闭天线发射之间应至少有1ms的间隔

///////////////////////////////////////////////////////////////////// void PcdAntennaOn() {

unsigned char i;

i = ReadRawRC(TxControlReg); if (!(i & 0x03)) {

SetBitMask(TxControlReg, 0x03); } }

///////////////////////////////////////////////////////////////////// //关闭天线

///////////////////////////////////////////////////////////////////// void PcdAntennaOff() {

ClearBitMask(TxControlReg, 0x03); }

25

本文来源:https://www.bwwdw.com/article/xi3g.html

Top