《RFID课程设计报告》
学生姓名 **
指导教师 **
学 院 信息科学与工程学院
专业班级 物联网1202班
学 号 **
完成时间 20**年4月28日
停车收费系统
1、通过课程设计,加深对《RFID》这一课程所学内容的进一步理解与巩固。
2、通过课程设计,加深对结构化设计思想的理解,能对系统功能进行分析,并设计合理的模块化结构。
3、通过课程设计,提高程序开发功能,能运用合理的控制流程编写清晰高效的程序。
4、通过课程设计,训练C++程序调试能力,能将一个中小型各级组织系统联调通过。
5、通过课程设计,开发一个中小型系统,掌握系统研发全过程。
6、通话课程设计,培养分析问题、解决实际问题的能力。
7、了解超高频读写器的基本设置,熟悉超高频读写器的设置与使用。通过本 实验,了解超高频读写器和标签参数的含义和设置方法。
1.RFID实验箱
2.计算机一台
3. 超高频RFID标签一只
1.了解和设置读写器参数;
2.RFID标签主要用于存储数据;本试验通过读写器控制软件控制RFID读写器对超高频RFID标签进行读取操作,同时对EPC数据进行改写操作。
1.打开RFID实验箱,使用读写器试验箱上的USB连接线连接实验箱和电脑,启动电源。
2.在电脑上安装USB转串口驱动程序、读写器控制软件。安装方法见实验箱软件安装文档。
3.在电脑上打开读写器控制软件,进入主界面,点击主菜单“control”,选择下拉菜单中“Add UHF Reader”。如图1-1示:
4.选择串口(弹出的显示值即对应串口),如图1-2示,点击ok,进入超高频读写器选择界面,如图1-3示:
5.主界面上显示读写器基本信息,鼠标选中该读写器,鼠标右击、选中“Reader Settings and Diagnostics”,进入读写器参数设置界面。如图1-4示:
6.读写器参数的了解和设置
1)Inventory Delay 参数,用于设置读写器读取标签的频率,例如:其值设置10ms表示读写器每间隔10ms读取一次标签信息。读写器读取标签的次数在主界面上实时动态显示
2)Tag Model参数,选择协议类型,具体有Gen2(ISO16000C)、Gen2+RSSI、ISO 6B(ISO16000B)。目前,市场上大部分标签都遵守Gen2协议。Gen2+RSSI表示主界面上将同时动态显示读写器读取标签的次数和返回的射频信号强度
3)Output level 参数和 Sensitivity参数,两者分别用于调节读写器读取功率和灵敏度。功率设置值越大,读写器读取标签的有效距离越长;灵敏度设置值越小,读写器读取标签的灵敏度越高。
4)Frequencies中有八项参数,其中Profile参数表示全球不同国家和地区对UHF频段设置的不同标准,包括USA、Europe、Japan、Chin***.625、Chin***.125、Korea等,一旦选择某一标准,其余的七项参数也随即确
定
了解各项参数实际功用和意义后,也可对这些参数进行自定义设置。
5)Gen2 Setting中的4项参数是对协议本身进行参数的设定,此项内容设置方法可以参考ISO18000-6C协议等资料。
7.修改标签EPC信息
在图2-3界面上点击Set EPC按钮,出现EPC修改界面如图2-4示,输入EPC长度和新的EPC,点击ok:
1.设置标签密码
类似步骤5,在图2-3界面中点击Set Password按钮,可对标签的访问密码进行设置。
此停车场管理系统是在一个狭长的通道上的,而且只有一个大门可以供车辆进出,并且要实现停车场内某辆车要离开时,在它之后进入停车场的车都必须先退出停车场为它让路,待其开出停车场后,这些辆再依原来的次序进场的功能,就可以设计两个堆栈,其中一个堆栈用来模拟停车场,另一个堆栈用来模拟临时停车场,该临时停车场用来存放当有车辆离开时,原来停车场内为其让路的车辆。至于当停车场已满时,需要停放车辆的通道可以用一个链队列来实现。当停车场内开走一辆车时,通道上便有一辆车进入停车场,此时只需要改变通道上车辆结点的连接方式就可以了,使通道上第一辆车进入停车场这个堆栈,并且使通道上原来的第二辆车成为通道上的第一辆车,此时只需将模拟通道的链队列的头结点连到原来的第二辆车上就可以了。
对于此停车场管理系统的实现,就是用两个堆栈来分别模拟停车场以及停车场内车辆为其它车辆让路时退出停车的临时停放地点。至于通道上车辆的停放则用一个链队列来实现,此时,通道上车辆的离开或者进入停车场只需改变此链队列上的结点而已。对于要对停车场内的车辆根据其停放时间收取相应的停车费用,可以记录下车辆进入以及离开停车场的时间,再用时间差乘以相应的单价并且打印出最后的费用就可以实现了。
此停车场管理系统,主要分为以下若干模块:
首先定义用来模拟停车场的堆栈以及用来模拟通道的链队列为全局变量,然后编写主函数,在此主函数中实现对其它各个模块的调用。在主函数中首先出现欢迎用户使用的主界面,然后提示用户进入此停车场管理系统后,再出现一个供用户选择的界面,在用户的选择过程中,程序又分别调用车辆的到达、车辆的离开、停车场内停放车辆的信息以及退出程序这四个函数模块。其中,在车辆的离开那个模块函数中又调用了打印离开车辆信息的函数,在停车场内停放车辆信息的那个模块函数中,又分别调用了显示停车场上车辆信息的函数以及显示便道上车辆信息的函数。最后,从调鼐的这四个函数中回到主函数结束整个程序的运行。
(1) 调试过程中的主要问题
由于此停车场管理系统是分模块设计的,而且在程序的实现过程中又使用了清屏函数,所以,运行时用户选择任务并且执行完任务后,又会回到供用户选择功能的主界面,因此整个程序从整体上来讲结构清晰,使用方便。本程序的调试运行,总体上情况良好,但中间也出现了一些小问题。其中比较有代表性的主要问题有:
当停车场已经达到最大容量,但仍有车辆进入停车场的时候,运行界面上没有出现或者说出现了但又跳掉了“停车场已满,该车辆需在便道上等待!”的提示信息。我们小组成员经过反复商量讨论,并且在查阅了多种资料后,在那一个printf语句后加了一个getch(),此时,程序运行结果就符合要求了。
测试结果的分析与讨论:
#include "time.h"
#include "lfreader.h"
#include "hfreader.h"
#include "CommandLib.h"
#include <cstdio>
#include "string.h"
//#include "iostream"
//#include "timer.h"
#include <windows.h>
#include <dbt.h>
#include<iostream>
#include<string>
using namespace std;
#define MAX 2 //停车场车位数
#define price 0.05 //每分钟收取的费用
typedef struct time
{
int hour;
int min;
}Time;//定义时间结点
typedef struct node
{
string num;
Time reach;
Time leave;
}CarNode;//定义每辆车的牌号,进入时刻,开出时刻
typedef struct NODE
{
CarNode *stack[MAX+1];
int top;
}SeqStackCar;//用栈定义,构造停车场
typedef struct car
{
CarNode *data;
struct car *next;
}QueueNode;//用队列结点定义,构造停车场外的单个等候车辆
typedef struct Node
{
QueueNode *head;
QueueNode *rear;
}LinkQueueCar;//用队列定义,构造停车场外的等候便道
void InitStack(SeqStackCar *); //初始化堆栈函数声明
int InitQueue(LinkQueueCar *); //初始化队列头结点函数声明
int Arrival(SeqStackCar *,LinkQueueCar *); //车辆进入时登记函数声明
void Leave(SeqStackCar *,SeqStackCar *,LinkQueueCar *);//车辆离开时函数声明
void List(SeqStackCar,LinkQueueCar); /*查看停车场内车辆情况及
便道上车辆情况的函数声明*/
//using namespace std;
double opacity;
void LFtest();
void HFtest();
void UHFtest();
void pay();
void find();
void add();
int main(int argc, char *argv[])
{
//LFtest();
//HFtest();
// UHFtest();
SeqStackCar Enter,Temp;//初始栈,中转栈
LinkQueueCar Wait;//便道队列
int a;
InitStack(&Enter);
InitStack(&Temp);
InitQueue(&Wait);//初始化
while(1)
{
cout<<"********************************************************************"<<endl;
cout<<" 欢迎光临停车场!";
cout<<"(*^__^*) !"<<endl;
cout<<"车辆到达登记->请按 1"<<endl;
cout<<"车辆离开登记->请按 2"<<endl;
cout<<"车辆停靠查询->请按 3"<<endl;
cout<<"余额查询 ->请按4 "<<endl;
cout<<"账户充值 ->请按5 "<<endl;
cout<<"消 费 ->请按6 "<<endl;
cout<<"退出系统->请按 7"<<endl;//系统选项设置
cout<<"********************************************************************"<<endl;
while(1)
{
cin>>a;
if(a>=1&&a<=7) break;
else cout<<endl<<"请选择: 1~7.";
}
switch(a)
{
case 1:Arrival(&Enter,&Wait);break;//调用入停车场函数
case 2:Leave(&Enter,&Temp,&Wait);break;//调用出停车场函数
case 3:List(Enter,Wait);break;//调用查看函数
case 4:find();break;
case 5:add();break;
case 6:pay();break;
case 7:exit(0);
default: break;
}
}
return 0;
}
void LFtest(){
/**低频示例程序 注意:低频卡每次扫描都需要从读卡器上拿下来后再放回去扫描*/
LFReader lfreader("COM5");
unsigned char *cardID;
int len = 7;
lfreader.startScan();
while(1)
{
while(!lfreader.scan(cardID,len));
for(int i=0;i<len;i++){
printf("%.2x ",cardID[i]);
}
cout<<endl;
}
}
void find(){
CommandLib UHFreader("COM7");
unsigned char lenc = 0;
unsigned char *tagInfo;
unsigned char** EPC;
unsigned char begAdd=0;
int tagNum;
int* EPCLen;
int ret=1;
while(!UHFreader.getInventory(EPC, tagNum, EPCLen));
if(UHFreader.selectTag(EPC[0],EPCLen[0]))
{
ret=UHFreader.readUser(lenc,tagInfo,begAdd);
unsigned int money=256*tagInfo[0]+tagInfo[1];
cout<<"当前账户余额为:"<<endl;
printf("%d ",money);
printf("\n");
}
}
void add(){
CommandLib UHFreader("COM7");
unsigned char lenc = 0;
unsigned char *tagInfo;
unsigned char** EPC;
unsigned char begAdd=0;
unsigned char* psw;
unsigned char* data;
int tagNum;
int* EPCLen;
int ret=1;
while(!UHFreader.getInventory(EPC, tagNum, EPCLen));
if(UHFreader.selectTag(EPC[0],EPCLen[0]))
{
ret=UHFreader.readUser(lenc,tagInfo,begAdd);
unsigned int num;
unsigned char psw[4]={0x00,0x00,0x00,0x00};
unsigned int money=256*tagInfo[0]+tagInfo[1];
printf("%d ",money);
printf("请输入要充的钱数:");
cin>>num;
money=money+num;
tagInfo[0]=money/256;
tagInfo[1]=money%256;
printf("充值后账户余额为:%d ",money);
unsigned char data[2]={tagInfo[0],tagInfo[1]};
unsigned char begAdd=0x00;
unsigned char *data2=data;
UHFreader.setUser(begAdd,psw,data2);
}
cout<<endl;
}
void pay(){
CommandLib UHFreader("COM7");
unsigned char lenc = 0;
unsigned char *tagInfo;
unsigned char** EPC;
unsigned char begAdd=0;
unsigned char* psw;
unsigned char* data;
int tagNum;
int* EPCLen;
int ret=1;
while(!UHFreader.getInventory(EPC, tagNum, EPCLen));
if(UHFreader.selectTag(EPC[0],EPCLen[0]))
{
ret=UHFreader.readUser(lenc,tagInfo,begAdd);
unsigned int num;
unsigned char psw[4]={0x00,0x00,0x00,0x00};
unsigned int money=256*tagInfo[0]+tagInfo[1];
printf("%d ",money);
printf("请输入要花费的钱数:");
cin>>num;
money=money-num;
tagInfo[0]=money/256;
tagInfo[1]=money%256;
printf("账户余额为:%d ",money);
unsigned char data[2]={tagInfo[0],tagInfo[1]};
unsigned char begAdd=0x00;
unsigned char *data2=data;
UHFreader.setUser(begAdd,psw,data2);
}
cout<<endl;
}
void InitStack(SeqStackCar *s) //堆栈初始化
{
s->top=0;
s->stack[s->top]=NULL;
}
int InitQueue(LinkQueueCar *Q)//队列初始化
{
Q->head=new QueueNode ;
if(Q->head!=NULL)
{
Q->head->next=NULL;
Q->rear=Q->head;
return 1;
}
else return -1;
}
void PRINT(CarNode *p,int room) //输出离开停车场的车辆情况
{
int A,B,C,D;
cout<<"\n车辆离开的时间:";
cin>>p->leave.hour>>p->leave.min;
cout<<"离开车辆的车牌号为:";
cout<<p->num;
cout<<endl<<"其到达时间为: "<<p->reach.hour<<":"<<p->reach.min;
cout<<"离开时间为: "<<p->leave.hour<<":"<<p->leave.min;
A=p->reach.hour;
B=p->reach.min;
C=p->leave.hour;
D=p->leave.min;
cout<<endl<<"应交费用为: "<<((C-A)*60+(D-B))*price<<"元"<<endl;
cout<<"车辆离开登记完毕!"<<endl;
cout<<"*********************************************************************"<<endl;
delete p;
}
int Arrival(SeqStackCar *Enter,LinkQueueCar *W)
{
CarNode *p;
QueueNode *t;
p=new CarNode;
cout<<"********************************************************************"<<endl;
cout<<"车辆到达登记开始:"<<endl;
cout<<endl<<"请输入车牌号:";
cin>>p->num;
if(Enter->top<MAX)//如果车位未满则进停车场内
{
Enter->top++;
cout<<endl<<"车辆在车场第"<<Enter->top<<"位置.";
cout<<endl<<"车辆到达时间:";
cin>>p->reach.hour>>p->reach.min;
cout<<endl<<"车辆到达登记完毕!"<<endl;
cout<<"*********************************************************************"<<endl;
Enter->stack[Enter->top]=p;
return 1;
}
else //如果车位已满,则停靠在便道上
{
cout<<"*********************************************************************"<<endl;
cout<<endl<<"该车须在便道等待!有车位时进入车场"<<endl;
t=new QueueNode ;
t->data=p;
t->next=NULL;
W->rear->next=t;
W->rear=t;
return 1;
}
}
void Leave(SeqStackCar *Enter,SeqStackCar *Temp,LinkQueueCar *W)
{
int room;
CarNode *p,*t;
QueueNode *q;
if(Enter->top>0)
{
while(1)
{
cout<<"*********************************************************************"<<endl;
cout<<"车辆离开登记开始:"<<endl;
cout<<endl<<"请输入车在车场的位置/1--"<<Enter->top<<"/:";
cin>>room;
if(room>=1&&room<=Enter->top) break;
}
while(Enter->top>room)//从停车场堆栈向中转堆栈移动车辆,直到要离开车辆的位置停止
{
Temp->top++;
Temp->stack[Temp->top]=Enter->stack[Enter->top];
Enter->stack[Enter->top]=NULL;
Enter->top--;
}
p=Enter->stack[Enter->top];
Enter->stack[Enter->top]=NULL;
Enter->top--;
while(Temp->top>=1)//将中转堆栈中的车辆移回停车场堆栈
{
Enter->top++;
Enter->stack[Enter->top]=Temp->stack[Temp->top];
Temp->stack[Temp->top]=NULL;
Temp->top--;
}
cout<<"*********************************************************************"<<endl;
cout<<"车辆离开登记结算:"<<endl;
PRINT(p,room);
if((W->head!=W->rear)&&Enter->top<MAX)
{
q=W->head->next;
t=q->data;
Enter->top++;
cout<<endl<<"便道的"<<t->num<<"号车进入车场第";
cout<<Enter->top<<"位置."<<endl;
cout<<"请输入"<<t->num<<"号车进入车场的时间:";
cin>>t->reach.hour>>t->reach.min;
W->head->next=q->next;
if(q==W->rear) W->rear=W->head;
Enter->stack[Enter->top]=t;
delete q;
}
else cout<<endl<<"便道里没有车"<<endl;
}
else cout<<endl<<"车场里没有车."<<endl;
}
void List1(SeqStackCar *S) //查看停车场内车辆情况的函数定义
{
int i;
if(S->top>0)
{
cout<<"********************************************************************"<<endl;
cout<<endl<<"车场内部车辆停靠情况:"<<endl;
cout<<endl<<"位置 到达时间 车牌号"<<endl;
for(i=1;i<=S->top;i++)
{
cout<<i;
cout<<" "<<S->stack[i]->reach.hour<<":"<<S->stack[i]->reach.min;
cout<<" "<<S->stack[i]->num<<endl;
}
}
else cout<<endl<<"车场里没有车"<<endl;
cout<<"********************************************************************"<<endl;
}
void List2(LinkQueueCar *W) //查看便道上停靠车辆情况的函数定义
{
QueueNode *p;
p=W->head->next;
if(W->head!=W->rear)
{
cout<<"********************************************************************"<<endl;
cout<<endl<<"便道停靠车辆情况:"<<endl;
while(p!=NULL)
{
cout<<endl<<"车辆牌号:";
cout<<p->data->num<<endl;
p=p->next;
}
}
else cout<<endl<<"便道里没有车."<<endl;
cout<<"********************************************************************"<<endl;
}
void List(SeqStackCar S,LinkQueueCar W) //车辆列表显示函数
{
int flag,tag;
flag=1;
while(flag)
{
cout<<"********************************************************************"<<endl;
cout<<"车辆停靠查询开始:"<<endl;
cout<<endl<<"请选择 1|2|3:"<<endl;
cout<<"1.车场列表"<<endl<<"2.便道列表"<<endl<<"3.返回主菜单"<<endl;
while(1)
{
cin>>tag;
if(tag>=1||tag<=3) break;
else cout<<endl;
cout<<"请选择 1~3:";
}
switch(tag)
{
case 1:List1(&S);
cout<<"车辆停靠查询结束!"<<endl;break;
case 2:List2(&W);
cout<<"车辆停靠查询结束!"<<endl;break;
case 3:flag=0;break;
default: break;
}
}
cout<<"********************************************************************"<<endl;
}
void HFtest(){
/**高频示例程序*/
BYTE *type = new BYTE[2];
HFReader hfcReader("COM6",9600);
cout<<"return :"<<hfcReader.ISO1443A_REQ(0x00,type)<<endl;
printf("卡类型为:%.2x%.2x\n",type[0],type[1]);
BYTE *tmp = new BYTE[7];
BYTE *key ;
key =tmp;
cout<<"密钥为:";
for(int i=0;i<6;i++)
{
key[i]=0xff;
printf("%x ",key[i]);
}
BYTE *buffer = new BYTE[64];
if(hfcReader.ISO1443A_Read(0x01,0,4,key,buffer)==0)
{
cout<<"\n读卡成功!\n卡号为:";
for(int i=0;i<4;i++)
{
printf("%.2x ",key[i]);
}
for(int i=0;i<64;i++)
{
if(i%4==0)cout<<" ";
if(i%16==0)cout<<endl;
printf("%.2x ",buffer[i]);
}
cout<<endl;
}
else{
cout<<"\n读卡失败"<<endl;
}
system("pause");
}
void UHFtest(){
CommandLib UHFreader("COM7");
unsigned char lenc = 0;
unsigned char *tagInfo;
unsigned char** EPC;
int tagNum;
int* EPCLen;
int ret=1;
while(1)
{
//system("pause");
Sleep(1000);
system("cls");
while(!UHFreader.getInventory(EPC, tagNum, EPCLen));
cout<<"读到"<<tagNum<<"张卡..."<<endl;
for(int i=0;i<tagNum;i++)
{
cout<<"第"<<i+1<<"张卡EPC号为: ";
for(int j=0;j<EPCLen[i];j++)
printf("%.2x ",EPC[i][j]);
cout<<endl;
}
if(UHFreader.selectTag(EPC[0],EPCLen[0]))
{
ret=UHFreader.readReserved(lenc,tagInfo);
cout<<ret<<"读到reserved区数据为:"<<endl;
for(int i=0;i<lenc;i++)
{
printf("%.2x ",tagInfo[i]);
}
printf("\n");
}
cout<<endl;
}
}
通过这一周的课程设计,加深了我对C++这门课程所学内容的进一步的理解与掌握;同时,通过对停车场管理系统的开发,使得我将计算机课程所学知识与实际问题很好地相联接在了一起。在这次课程设计中,不仅培养了我开发一个中小型程序的能力,而且也培养了我的设计能力。在这次对停车场管理系统的开发过程中,在这次课程设计中,使得我很好地了解了在开发程序过程中合作的重要性。
在这周课程设计中,我所开发的停车场管理系统,基本上可以完成每一项功能。汽车进入停车场的信息、离开停车场的信息以及通道上的信息都可以在程序上一一实现。但是,该程序也有不足的地方。主要表现在车辆的车牌号上,现实中的车牌号是一串字符,可是,在这个程序中,为了简便起见,我们就车牌号定义为了整型,这个与现实是有些不符的。还有一个可以改进的地方就是记录车辆进入停车场以及离开停车场的时间,应该精确到小时以及分钟的,可是在程序中,为了简便起见,我们只是设置成了一个时刻,所以,在这方面还是有待改进的。改进的程序中,还应该增加时间的判断功能,即停车场内有可能有车辆停放的时间超过一天。
还有一个很重要的问题,对于停车场内可以停放的最多车辆数,为了测试数据的方便,我在程序中,定为了2,在实际使用中,可以改变程度开头的宏定义以增加停车场的容量。
总之,在这周的课程设计中,我以及我们这组的收获还是挺大的,不仅对于专业课有了更好的认识,而且在合作的过程中更加了解了团队精神的重要性。
主 要 参 考 资 料 |
[1]谭浩强. C语言程序设计(第三版)[M]. 北京:清华大学出版社,2005 [2]廖雷、罗代忠. C语言程序设计基础实验教程[M]. 北京:高等教育出版社,2005 [3]谭浩强. C程序设计解题与上机指导(第三版) [M]. 北京:清华大学出版社,2005 [4]廖雷等. C语言程序设计基础[M]. 北京:高等教育出版社,2004 [5]谭浩强,张基温,唐永炎. C语言程序设计教程. 北京: 高等教育出版社,2003 |
1课程设计目的课程设计是船舶设计原理课程重要的实践性教学环节是培养学生掌握船舶设计基本原理和能力的技术基础主尺度论证与总布置设计是…
一设计目的1强化上机动手能力在理论和实践的基础上进一步巩固数据结构课程学习的内容掌握工程化软件设计的基本方法2掌握图的创建和应用3…
中国计量学院信息工程学院课程设计报告课程设计名称系统设计与仿真课程计二级学院信息工程学院专业班级10电信2班学姓成绩号名10003…
信息科学与工程学院高级语言程序设计课程设计报告学生成绩管理系统学科专业计算机科学与技术班级1301学号指导教师唐郑熠讲师学生二零年…
扬州大学数据结构课程设计报告课题名称姓名学院系科班级指导老师日期自来水管架设问题广陵学院陈宏建1一课程设计的题目自来水管理架设问题…
宁波大学机械工程与力学学院工业工程系课程设计报告20XX20XX学年第1学期课程名称:现代物流设施与规划设计题目:RFID射频识别…
RFID课程设计学院:信息科学与工程学院班级:学号:导师:前言目前,很多企业仓库管理还是停留在手工操作的基础上,这样的传统的仓库管…
武汉理工大学华夏学院武汉理工大学华夏学院课程设计报告课程名称射频识别基础课程设计题目高频数据块写入专业信息工程系班级学号姓名成绩指…
工程论文参考文献参考3篇工程论文参考文献参考一1王仁祥电力新技术概论M北京中国电力出版社20xx2戈东方电力工程电气设计手册第1册…
RFID原理及技术课程设计设计方案题目基于RFID的个人身份识别系统系别计算机与信息工程学院班级13物联网20xx061101学号…