排队叫号系统(带源程序)
- 格式:doc
- 大小:203.00 KB
- 文档页数:12
宁夏回族自治区保健局排队叫号子系统用户使用说明书一、系统所需配置及要求为确保排队叫号系统业务的正常进行,避免因计算机问题导致业务不能正常办理的情况发生。
在此针对医院的客户端计算机、网络配置及管理提出以下要求,望请遵照执行。
1.1计算机基本配置要求硬件环境:Intel Pentium PC机或兼容机,可以连接到Internet,至少256M 内存,建议屏幕区域设为1024 × 768象素小字体。
软件环境:Windows 9x 、Windows 2000、Windows XP或更新版本操作系统。
1.2相关硬件设备及网络基本配置要求相关硬件配置:可视体检卡:反复擦写卡表面信息(文字、图片),高对比度、高解析度,黑色字体,清晰度高,可重复擦写打印500次以上,不需耗材,超强的抗磁性,卡片可循环再用。
专用读卡器:USB口转接供电,可读写13.56Mhz ISO14443 TypeA 系列射频卡,输出格式:USB/RS232,读卡距离:5—10cm,提供RS232测试软件、dll动态库和开发包,提供C/VB/DP/PB示范程序。
专用读写机:USB2.0连接线,热敏打印面积:562*320,点点距:垂直0121毫米,横向0.125毫米。
单字节节符24点*12点,双字节字符24点*24点。
送卡速度每秒300毫米+/-10%;打印速度:每秒30毫米+/-10%。
LED显示屏:3.75mm单行10汉字, 912mmX145mmX35mm。
心理健康检查系统自主答题机:Intel Pentium PC机或兼容机,至少256M 内存。
网络设备配置:局域网安装防火墙(路由器等其他网络设备)的相关管理单位,必须开放9080端口。
1.3人员管理基本要求排队叫号系统客户端计算机实行专管员专机专用,并设置开机密码。
排队叫号系统专管员应妥善保管和使用用户名和密码,并对使用该用户名和密码进行的一切操作负责。
排队叫号系统客户端计算机不得用于聊天工具、玩网络游戏、下载插件以及登陆不良网站等与挂号管理业务无关的事项。
2011年至2012年第一学期《银行排队叫号系统设计》课程设计班级1006402指导教师涂立、李旎学生人数 3设计份数 12011年12月23日银行排队叫号系统设计报告一.设计时间2011年12月 19日——---12月23日二.设计地点湖南城市学院实验楼计算机机房三.设计目的1.进一步熟悉和掌握单片机的结构及工作原理。
2.掌握单片机的接口技术及相关外围芯片的外特性,控制方法。
3.通过课程设计,掌握以单片机核心的电路设计的基本方法和技术,详细使用Protel软件绘制原理图的过程.4.通过实际程序设计和调试,逐步掌握模块化程序设计方法和调试技术。
四.实验成员及分工五。
指导老师涂立副教授、李旎讲师.六.设计课题设计一个银行排队叫号系统。
理由: 1、系统原理容易理解,更贴近我们的生活。
2、怎个系统简洁明了,适于初学者。
3、能提高我们的综合应用能力。
七.基本思路及关键问题的解决方法用八个二极管表示客户取号的号码和营业员准备给那位客户办理业务的号码,用二进制表示,亮的二极管表示0,灭的二极管表示为1 。
开关KEY为客户取号码是所用,KEY闭合时八个二极管的亮灭顺序就是客户的号码。
开关KEY1,KEY2,KEY3,KEY4是分别在四个营业窗口,其中任意一个按下,八个二极管的亮灭会显示一个号码,此号码对应要办理业务客户的号码,与此同时蜂鸣器也会提醒客户。
八.算法及流程图算法:程序利用循环结构检测整个系统中的客户端和叫号端是否有按键被按下,如果检测到有按下的信号,首先判断按下按键的端口的类型,然后相应的计数变量加一,并把计数变量的信息以二进制的形式传送到相应的端口;如果没检测到按下信号,程序则跳入下一个循环继续检测按键信息。
表1 元件清单芯片晶振发光二级管电容电源按键蜂鸣器导线P87C52X2BN11.0592MHZLED10uf、30pf5V非自锁式1183181若干图1。
银行排队叫号系统原理图图2. 银行排队叫号系统流程图九、调试过程中出现的问题及相应解决办法1.开打keil软件,建立一个新工程单击【Project】在下拉菜单中找到【New project。
排队叫号系统的设计与实现毕业设计排队叫号系统的设计与实现毕业设计导言排队叫号系统在各个行业中广泛应用,如医院、银行、餐厅等。
它的设计和实现涉及到多个方面,例如用户体验、系统稳定性等。
本文将从深度和广度两个方面对排队叫号系统的设计与实现进行全面评估,并给出个人观点和理解。
一、排队叫号系统概述1.1 什么是排队叫号系统排队叫号系统是一种通过电子化方式管理和控制人群排队顺序的系统。
其主要功能包括叫号、排队管理、叫号记录等。
这个系统通常由硬件设备和软件程序组成,用户通过取号机或手机APP进行取号,然后等待被叫号。
1.2 排队叫号系统的重要性排队叫号系统不仅提高了服务效率,还提升了用户体验和工作效率。
通过系统化地管理排队顺序,可以避免客户等待时间过长以及拥挤的人群场景。
这个系统对于后台的数据统计和分析也提供了便利,可以更好地优化工作流程和资源分配。
二、排队叫号系统的设计与实现2.1 用户需求分析在设计排队叫号系统之前,需要对用户需求进行详细分析。
不同行业的用户需求可能有所不同,如医院用户需求主要是等待时间减少和服务效率提高,而银行用户则更关注服务质量和系统稳定性。
根据不同行业和用户需求的差异,可以调整系统的设计和功能。
2.2 系统架构设计排队叫号系统的系统架构设计要考虑到系统的稳定性和扩展性。
一个良好的系统架构设计可以提高系统的性能和容错能力。
可以采用分布式架构,将排队管理和数据存储分离,在高并发情况下,有效提高系统的处理能力。
2.3 界面设计与用户体验用户体验是排队叫号系统设计中非常重要的一环。
界面设计要简洁明了,方便用户操作和理解。
可以提供多种语言版本和主题以满足不同用户群体的需求。
用户操作流程要简化,减少用户等待时间和操作步骤。
2.4 数据管理与分析排队叫号系统会产生大量的数据,包括用户叫号信息、等待时间、服务时长等。
这些数据可以用于后期的数据分析和服务优化。
可以采用大数据分析技术,对用户等待时间、服务质量等进行统计和分析,以便优化服务流程和资源分配。
本科毕业论文(设计)题目银行排队叫号系统设计学院 XXXXXXXXXXX学院专业 XXXXXXXXXX 年级 XXXXX 级学号 XXXXXXXXXXXXXXX 姓名 XXXX 指导教师 XXXXXXXX _ 成绩 ________ ____ __ __XXXX年 XX月XX日目录摘要 (1)关键字 (1)Abstract (1)Key Words (1)引言 (2)1 硬件设计 (3)1.1 主要器件 (3)1.1.1 微处理器介绍 (3)1.1.2 液晶LCD12864介绍 (5)1.1.3 语音模块介绍 (7)1.2 硬件电路 (8)1.2.1 单片机最小系统 (8)1.2.2 液晶显示电路 (10)1.2.3 声音提示电路 (10)1.3 系统硬件总电路图 (11)2 软件设计 (11)2.1 主要程序设计 (12)2.1.1 取号模块程序设计 (12)2.1.2 叫号模块程序设计 (13)2.1.3 语音模块程序设计 (14)2.2 系统源程序 (15)3 系统调试及仿真 (15)3.1 系统仿真 (15)3.2 系统调试 (17)3.3 硬件实物系统运行的效果图 (17)4 结束语 (20)参考文献 (21)致谢 (22)附录A 原理图 (23)附录B 程序 (24)·银行排队叫号系统摘要:本排队叫号系统由一个叫号系统和一个抽号系统组成,客户利用抽号系统抽取号码,客服人员通过叫号系统呼叫客户;利用液晶LCD12864显示器和WT588D语音芯片分别能及时显示出当前所呼叫号数并发出语音提示,客户就能够及时了解当前排队信息。
使用该排队叫号系统,解决了当下排队拥挤混乱状况,极大的提高了排队等侯效率,从而实现排队自动化、规范化,同时也适应科技的发展。
为实现上述功能,该系统采用AT89C51单片机进行控制,通过按键取号、叫号,利用LCD12864显示信息,再通过WT588D语音芯片提示,实现排队管理系统的模拟化,设计出一个具有控制灵活、使用方便、成本低、性价高等特点的系统。
课程设计任务书课程名称:课程设计1(数据结构)设计题目:银行排队叫号系统1.问题描述:目前,在以银行营业大厅为代表的窗口行业,大量客户的拥挤排队已成为了这些企事业单位改善服务品质、提升营业形象的主要障碍。
排队(叫号)系统的使用将成为改变这种状况的有力手段。
排队系统完全模拟了人群排队全过程,通过取票进队、排队等待、叫号服务等功能,代替了人们站队的辛苦,把顾客排队等待的烦恼变成一段难得的休闲时光,使客户拥有了一个自由的空间和一份美好的心情。
排队叫号软件的具体操作流程为:●顾客取服务序号。
当顾客抵达服务大厅时,前往放置在入口处旁的取号机,并按一下其上的相应服务按钮,取号机会自动打印出一张服务单。
单上显示服务号及该服务号前面正在等待服务的人数。
●银行职员呼叫顾客,顾客的服务号就会按顺序的显示在显示屏上。
当一位顾客办事完毕后,柜台银行职员只需按呼叫器相应键,即可自动呼叫下一位顾客。
2. 功能要求:1)使用数组或链表以及C#接口和范型技术实现通用的队列功能;2)编写算法,利用队列模拟银行排队系统;3)利用多窗口分别模拟顾客取服务号、银行窗口服务顾客。
3.界面要求:用户界面设计不做统一规定,但应做到界面友好,易于操作。
4. 技术要求:要求利用面向对象的方法以及队列数据结构来完成系统的设计;在设计的过程中,建立清晰的类层次;在系统设计中要分析和定义各个类,每个类中要有各自的属性和方法;要求运用面向对象的机制来实现系统功能。
5.创新要求在基本要求达到后,可以进行创新设计(包括界面、功能、数据结构)。
6. 课程设计时间:1周(18课时)7. 课程设计的考核方式及评分方法1)考核方式⏹课程设计结束时,在机房当场验收。
⏹教师提供测试数据,检查运行结果是否正确。
⏹回答教师提出的问题。
⏹学生提交课程设计文档(A4纸打印)2)评分方法上机检查及答辩: 书面报告: 学习态度= 6 : 3 : 1,没有通过上机检查的其成绩直接记录不及格。
学号:0121011360701课程设计题目银行叫号排队系统学院自动化学院专业自动化专业班级自动化1007班姓名董晨指导教师刘永红2013 年7 月9 日能力拓展训练任务书学生姓名:董晨专业班级: 1007 班指导教师:刘永红工作单位:自动化学院题目:银行叫号排队系统的设计初始条件:1)实地调研,了解银行叫号过程;(2)画出一个实例的状态转移图;(3)程序设计,用单片机实现。
(汇编语言或C语言)要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1. 题目内容:根据实际情况,制定可行的技术路线,满足客户要求。
(如,等待时间最短;VIP优先;老人优先(专柜);“飞号”不清除等。
飞号是指叫了该号3次后,而该号人没出现服务窗口,就不再呼叫,该号被清除了,该号就称之为飞号。
可用户又回来了,只好再取一个新号。
)2. 课程设计说明书应包括:a)设计任务及要求b)方案比较及认证c)程序设计基本思想,程序流程图,部分源程序及注解d)调试记录及结果分析e)参考资料f)附录:全部源程序清单g)总结时间安排:2013年 7 月 1-2 日选题、查阅资料和方案设计2013年 7 月 3 日编程2013年 7 月 4-5 日调试程序,改进与提高2013年 7 月 6-8 日撰写设计报告(有调试过程及结果的截屏)2013年 7 月 9 日答辩和交课程设计报告指导教师签名: 2013 年月日系主任(或责任教师)签名:2013 年月日摘要排队叫号管理系统是针对银行、工商、税务、通讯、政府机构等部门的大厅工作流程设计的,是利用电脑的科学管理客户排队的系统,很好地解决了客户在服务机构办理业务时所遇到的各种排队、拥挤和混乱现象,为客户办理业务带来莫大的方便和愉悦。
该题研究的目的是研制一款无人排队的排队叫号机,它主要由主控制器、键盘、显示电路、蜂鸣器电路等部分构成。
系统利用单片机进行控制,通过串行通信方式传输处理数据;通过按键取号,在LCDLM016L上显示排队的号码以及当前正在等待的人数;通过按键叫号,在LCDLM016L上显示叫到的号码,由扬声器发出声音提示客户。
排队叫号系统程序流程设计下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。
文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor. I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!排队叫号系统程序流程设计一、引言排队叫号系统是一种用于管理排队等待的系统,它可以提高服务效率,减少顾客等待时间,提升顾客满意度。
毕业论文基于单片机的排队叫号系统设计毕业设计(论文)原创性声明和使用授权说明原创性声明本人郑重承诺:所呈交的毕业设计(论文),是我个人在指导教师的指导下进行的研究工作及取得的成果。
尽我所知,除文中特别加以标注和致谢的地方外,不包含其他人或组织已经发表或公布过的研究成果,也不包含我为获得及其它教育机构的学位或学历而使用过的材料。
对本研究提供过帮助和做出过贡献的个人或集体,均已在文中作了明确的说明并表示了谢意。
作者签名:日期:指导教师签名:日期:使用授权说明本人完全了解大学关于收集、保存、使用毕业设计(论文)的规定,即:按照学校要求提交毕业设计(论文)的印刷本和电子版本;学校有权保存毕业设计(论文)的印刷本和电子版,并提供目录检索与阅览服务;学校可以采用影印、缩印、数字化或其它复制手段保存论文;在不以赢利为目的前提下,学校可以公布论文的部分或全部内容。
作者签名:日期:学位论文原创性声明本人郑重声明:所呈交的论文是本人在导师的指导下独立进行研究所取得的研究成果。
除了文中特别加以标注引用的内容外,本论文不包含任何其他个人或集体已经发表或撰写的成果作品。
对本文的研究做出重要贡献的个人和集体,均已在文中以明确方式标明。
本人完全意识到本声明的法律后果由本人承担。
作者签名:日期:年月日学位论文版权使用授权书本学位论文作者完全了解学校有关保留、使用学位论文的规定,同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。
本人授权大学可以将本学位论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。
涉密论文按学校规定处理。
作者签名:日期:年月日导师签名:日期:年月日指导教师评阅书评阅教师评阅书教研室(或答辩小组)及教学系意见毕业设计(论文)任务书毕业设计(论文)题目:基于单片机的排队叫号系统设计毕业设计(论文)内容:本课题是以单片机为主控器设计排队叫号系统,具体要求如下:1、可以通过按键取号,并在LCD上显示排队的号码以及当前等待的人数;2、通过按键叫号,在LCD上显示被叫号码,并通过扬声器发声提示客户;课题包含硬件设计和软件设计两大部分,其中硬件部分要完成原理电路图的设计及制作,确定整个系统所用元器件的参数或型号规格,给出元器件明细表;软件部分包括的单片机程序设计,最后完成整机的调试运行,并做出模型进行演示。
主函数:#include "stdafx.h"#include "Queue.h"#include "stdio.h"int main(int argc, char* argv[]){Queue s;s.q[0] = 0; // 让入队的第一个数取数值1int a=1, b=0 ,d=1 ,e=0;char c;while(a) // 运用switch实现选择{printf("顾客要号请输入A \n要提示下一位下一位顾客的号码请输入B \n 要显示等待的人数请输入C\n结束循环请输入D \n ");c= getchar();while(getchar()!='\n') continue ;switch(c){case 'A':;case 'a':// 顾客要号之后让元素入队s.addQ();b = s.getQ();printf("顾客要的号码为:%d\n", b);break;case 'B ': ;case'b':// 删除队首元素即显示要来办理业务的顾客d = s.delQ();printf("请%d号客户前来柜台办理业务\n", d);case 'C ':;case 'c':// 显示等待的人数e = s.number();printf("等待的总人数为:%d\n", e);break;case 'D' :;case 'd':// 结束循环c=0;break;default:printf("输入错误!\n");}}printf("Hello World!\n");return 0;}队列的建立:(类)Queue.h#if !defined(AFX_QUEUE_H__BA389AF8_C207_4C3E_8A7F_99499FBBA143__I NCLUDED_)#defineAFX_QUEUE_H__BA389AF8_C207_4C3E_8A7F_99499FBBA143__INCLUDED _#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#define M 1000class Queue // 定义队列名{public:Queue();void initialQ();int emptyQ (); // 定义队空int getQ(); // 取队首元素int addQ(); // 入队int delQ(); // 出队int number(); // 统计队列元素数目int q[M]; // 定义数组qint front; //定义队首元素int rear ; //定义队尾元素virtual ~Queue();};#endif// !defined(AFX_QUEUE_H__BA389AF8_C207_4C3E_8A7F_99499FBBA143__I NCLUDED_)Queue.cpp:// Queue.cpp: implementation of the Queue class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "Queue.h"#define M 1000//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////Queue::Queue(){front = 0;rear = 0;}int Queue::emptyQ() //初始化队列{return front == rear;}int Queue::getQ() // 取队首元素{if(rear+1==front)return 0;else{int item;item=q[rear];return item;}}int Queue::addQ() // 入队{if((rear+1)%M==front)return 0;else{q[rear+1] = q[rear] + 1 ; // 每次入队依次使入队元素的值加1,即表示顾客叫号依次递增rear ++; //实现循环return 1;}}int Queue::delQ() //删除队首元素{if((front ==rear))return 0;else{int item;front=(front+1)%M;item=q[front];return item;}}int Queue:: number() // 统计队列元素的数目{int item;item = q[rear] - q[front];return item;}Queue::~Queue(){}。
Linux操作系统课程设计题目:进程通信与进程同步机制实践(银行叫号排队模拟系统)所在学院:所在班级:学生姓名:学生学号:指导教师:一、题目某银行提供5个服务窗口(3个对私服务窗口,1个对公服务窗口,1个理财服务窗口)和10个供顾客等待的座位。
顾客到达银行时,若有空座位,则到取号机上领取一个号,等待叫号;若没有空座位,则在门外等待或离开.取号机每次仅允许一位顾客使用,有对公、对私和理财三类号,每位顾客只能选取其中一个.当营业员空闲时,通过叫号选取一位顾客,并为其服务。
请用P、V操作写出进程的同步算法。
二、目的1、掌握基本的同步与互斥算法。
2、学习使用 Linux 中基本的同步对象,掌握相关 API 的使用方法。
3、了解 Linux 中多任务的并发执行机制,实现进程的同步与互斥。
三、实验环境Linux CentOS、Ubuntu、Fedora等Linux系统编译器GCC编程语言 C语言四、要求1、当有顾客取号的时候,不允许其他顾客取号。
2、当服务窗口满的情况下,其他人必须等待.3、当没有顾客的情况下,服务窗口必须等待。
4、打印:A、初始状态B、中间变化的状态信息C、以及最终状态信息。
五、原理及算法本程序中设计6个信号量,其中signal_A、signal_B和signal_C分别是对私、对公、理财窗口的同步信号量。
若信号量值的等于0,说明当前没有空闲空口,顾客需要等待。
另设置一个signal_seat同步信号量,记录当前的座位情况,若该信号量等于0,说明当前没有空座位,顾客需要等待。
另有一个signal_customer同步信号量用于记录当前已经取过票的总人数,用于生成票号信息。
还有一个mutex互斥信号量,用于实现各进程在对信号量进行操作时的互斥。
顾客进入银行之后,先看通过一个依据系统时间的随机数来确定自己是需要对私、对公还是理财服务(在本程序中分别对应于A类顾客,B类顾客和C类顾客),这三个类型的顾客的比例为3:1:1.然后顾客根据自己需要的服务类型,查看提供相应类型服务的窗口是否空闲,若窗口有空闲,则系统直接按照signal_customer记录的信息,生成票面信息;若窗口没有空闲,则再去查看signal_seat信号量看看是否有空座位,若有空座位,则根据signal_customer 记录的信息,生成票面信息;若没有空座位,则通过一个以系统时间为种子的随机数生成器生成一个随机数,帮助顾客确定是要继续等待还是离开,这两种情况的比例为1:1.若顾客选择离开,则相应的进程退出.当顾客取到票后,便开始查看对应类型的窗口是否有空闲,如果有空闲,则上前办理业务。
摘要本文设计了一套排队叫号系统。
该系统是以排队抽号顺序为核心,客户利用客户端抽号,工作人员利用叫号端叫号;通过显示器及时显示当前所叫号数,客户及时了解排队信息,通过合理的程序结构来执行排队抽号。
以提高排队等待效率,解决排队秩序混乱,前拥后挤等现象,实现排队自动化,规范化。
通过该系统的使用,客户不必为排队浪费大量精力,便于管理排队秩序,同时适应信息时代管理数字化的要求,提高服务水平与质量。
关键词:单片机排队叫号系统开发目录1.引言 (1)2.系统功能分析及设计要求 (2)3.系统框图 (3)4.主要应用器件及技术原理 (4)4.1 微处理器介绍 (4)4.1.1、MCS-51单片机的特点 (4)4.1 2、MCS-51 单片机的结构 (4)4.2液晶LCD1602的介绍 (5)4.2.1 字符型液晶显示器的显示原理 (5)4.2.2 液晶LCD1602的简介 (5)5.系统硬件电路设计 (8)5.1晶振电路 (8)5.2液晶显示电路 (9)5.3声音提示电路 (10)6.系统测试 (11)7.系统软件设计 (10)7.1系统软件流程图....................................................... 错误!未定义书签。
7.2系统程序设计........................................................... 错误!未定义书签。
7.2.1 主程序........................................................... 错误!未定义书签。
7.2.2 液晶LCD1602显示处理程序..................... 错误!未定义书签。
7.2.3 按键检测程序...........................................................................错误!未定义书签。
c语言课程设计排队叫号系统一、教学目标本课程的教学目标是使学生掌握C语言的基本语法,能够运用C语言设计简单的排队叫号系统。
通过本课程的学习,学生将能够理解C语言的基本数据类型、运算符、控制结构、函数等知识,具备一定的编程能力,能够运用C语言解决实际问题。
具体来说,知识目标包括:1.掌握C语言的基本数据类型和运算符。
2.理解控制结构,如if语句、循环语句等。
3.了解函数的定义和调用。
技能目标包括:1.能够使用C语言编写简单的程序。
2.能够运用控制结构解决实际问题。
3.能够编写和调用函数。
情感态度价值观目标包括:1.培养学生的编程兴趣,提高学生的自主学习能力。
2.培养学生的团队协作意识,提高学生的沟通表达能力。
3.使学生认识到编程在实际生活中的重要性,培养学生的创新思维。
二、教学内容根据课程目标,本课程的教学内容主要包括C语言的基本语法、数据类型、运算符、控制结构、函数等。
具体安排如下:1.第一章:C语言概述。
介绍C语言的历史、特点和基本语法。
2.第二章:数据类型和运算符。
讲解C语言的基本数据类型和运算符。
3.第三章:控制结构。
讲解if语句、for循环、while循环等控制结构。
4.第四章:函数。
讲解函数的定义、声明和调用。
5.第五章:排队叫号系统设计。
运用所学知识设计一个简单的排队叫号系统。
三、教学方法为了激发学生的学习兴趣和主动性,本课程将采用多种教学方法,如讲授法、讨论法、案例分析法、实验法等。
1.讲授法:用于讲解C语言的基本语法、数据类型、运算符、控制结构、函数等知识点。
2.讨论法:通过小组讨论,让学生相互学习,共同解决问题。
3.案例分析法:分析实际案例,让学生学会将所学知识运用到实际问题中。
4.实验法:让学生动手编写程序,培养学生的编程能力。
四、教学资源为了支持教学内容和教学方法的实施,丰富学生的学习体验,我们将选择和准备以下教学资源:1.教材:《C语言程序设计》。
2.参考书:《C语言编程实例解析》。
#include <iostream>#include <queue>#include <stdlib.h>#include <stdio.h>#include <time.h>#include <ctime>#include "windows.h"using namespace std;int AverageTime;//平均时间void DisplayWindows(int presenttime,int seringtime, int unittime){cout<<"************模拟银行叫号系统*************"<<endl;cout<<"***********银行服务时间0--"<<seringtime<<"************"<<endl;cout<<"**该叫号系统每隔"<<unittime<<"单位时间显示窗口信息****"<<endl;cout<<"当前时间为"<<presenttime<<""<<endl;}class Customer/*顾客信息*/{public:Customer(){SerTime=0;enterTime=0;startTime=0;cID=0;endTime=0;}void Reset(){SerTime=0;enterTime=0;startTime=0;cID=0;endTime=0;}Customer(const Customer& anthercustomer)//复制构造函数{enterTime=anthercustomer.enterTime;startTime=anthercustomer.startTime;servDurance=anthercustomer.servDurance;SerTime=anthercustomer.SerTime;cID=anthercustomer.cID;endTime=anthercustomer.endTime; }void SetSevTime(int serT){SerTime=serT;}int GetID(){return cID;}int GetEndTime(){return endTime;}int GetStartTime(){return startTime;}int GetSerDurance()//顾客等待时间{return (startTime-enterTime);}int GetSerTime(){return SerTime;}void SetEnterTime(int enterT){enterTime=enterT;}void SetEndTime(int endT){endTime=endT;}void SetID(int ID){cID=ID;}void SetSartTime(int startT){startTime=startT;}int enterTime,startTime,SerTime,servDurance,cID,endTime;};class Bank{public:void ResetBank(){while(!servingcustomer.empty())servingcustomer.pop();while(!waitingcustomer.empty())waitingcustomer.pop();}bool Assign(Customer customer)//判断服务窗口有没有完成服务{if(customer.GetEndTime()-customer.GetStartTime()==customer.GetSerTime())return true;elsereturn false;}void DisplayWaitingTime(queue<Customer> quecus){AverageTime=0;cout<<"顾客及等待时间:"<<endl;while(!quecus.empty()){cout<<"顾客"<<quecus.front().GetID()<<": "<<quecus.front().GetSerDurance()<<" ";AverageTime+=quecus.front().GetSerDurance();quecus.pop();}cout<<endl;}queue<Customer> GetCustomerQueue(queue<Customer> queuec){queue<Customer> temp;while(!queuec.empty()){temp.push(queuec.front());queuec.pop();}return temp;queue<Customer> servingcustomer;queue<Customer> waitingcustomer;};int main(){Bank Bank1;Bank1.ResetBank();queue<Customer> CustomerTrack;queue<Customer> CustomerTrack2;Customer ser1,ser2,ser3,ser4,ser5;int num[5]={0};srand((unsigned) time(0));//播种子const int TimeSlot=100;//假设服务时间段为0-100const int UnitTime=10;//单位时间为10const int ServTime=7;//服务时间为1-7const int UnitTimePeo=10;//单位时间进来的人数为0-9const int StopEnterTime=80;//为了保证所有顾客能完成服务,顾客进入的时间为0-80 int PresentTime=0;//初始化当前时间为0int PerTime=5;//每隔5秒显示一次窗口信息int NumberOfCustomer=0;int TimeOfServing=0;int IDtrack=0;while(PresentTime<TimeSlot){Customer tempCustomer;NumberOfCustomer=rand()%UnitTimePeo;for(int j=0; j<NumberOfCustomer;j++){tempCustomer.SetID(++IDtrack);TimeOfServing=1+rand()%ServTime;tempCustomer.SetSevTime(TimeOfServing);tempCustomer.SetEnterTime(PresentTime);Bank1.waitingcustomer.push(tempCustomer);}int nnn=0;for(int t=0;t<UnitTime+nnn;t++){if(Bank1.Assign(ser1))//窗口1完成{if(ser1.GetID()!=0)CustomerTrack.push(ser1);ser1.Reset();if(!Bank1.waitingcustomer.empty()){ser1=Bank1.waitingcustomer.front();ser1.SetSartTime(PresentTime);ser1.SetEndTime(PresentTime);Bank1.waitingcustomer.pop();Bank1.servingcustomer.push(ser1);num[0]++;}}else{ser1.SetEndTime(PresentTime);}if(Bank1.Assign(ser2))//窗口2完成{if(ser2.GetID()!=0)CustomerTrack.push(ser2);ser2.Reset();if(!Bank1.waitingcustomer.empty()){ser2=Bank1.waitingcustomer.front();ser2.SetSartTime(PresentTime);ser2.SetEndTime(PresentTime);Bank1.waitingcustomer.pop();Bank1.servingcustomer.push(ser2);num[1]++;}}else{ser2.SetEndTime(PresentTime);}if(Bank1.Assign(ser3))//窗口3完成{if(ser3.GetID()!=0)CustomerTrack.push(ser3);ser3.Reset();if(!Bank1.waitingcustomer.empty()){ser3=Bank1.waitingcustomer.front();ser3.SetSartTime(PresentTime);ser3.SetEndTime(PresentTime);Bank1.waitingcustomer.pop();Bank1.servingcustomer.push(ser3);num[2]++;}}else{ser3.SetEndTime(PresentTime);}if(Bank1.Assign(ser4))//窗口4完成{if(ser4.GetID()!=0)CustomerTrack.push(ser4);ser4.Reset();if(!Bank1.waitingcustomer.empty()){ser4=Bank1.waitingcustomer.front();ser4.SetSartTime(PresentTime);ser4.SetEndTime(PresentTime);Bank1.waitingcustomer.pop();Bank1.servingcustomer.push(ser4);num[3]++;}}else{ser4.SetEndTime(PresentTime);}if(Bank1.Assign(ser5))//窗口5完成{if(ser5.GetID()!=0)CustomerTrack.push(ser5);ser5.Reset();if(!Bank1.waitingcustomer.empty()){ser5=Bank1.waitingcustomer.front();ser5.SetSartTime(PresentTime);ser5.SetEndTime(PresentTime);Bank1.waitingcustomer.pop();Bank1.servingcustomer.push(ser5);num[4]++;}}else{ser5.SetEndTime(PresentTime);}if(PresentTime%PerTime==0){CustomerTrack2=Bank1.GetCustomerQueue(Bank1.servingcustomer);system("cls");DisplayWindows(PresentTime,TimeSlot,PerTime);/*显示窗口1-5的服务ID*/cout<<endl;cout<<"**当前时间窗口服务的顾客的ID,0为没有顾客**"<<endl;cout<<"窗口1的ID:"<<ser1.GetID()<<" ";cout<<"窗口2的ID:"<<ser2.GetID()<<" ";cout<<"窗口3的ID:"<<ser3.GetID()<<" ";cout<<"窗口4的ID:"<<ser4.GetID()<<" ";cout<<"窗口5的ID:"<<ser5.GetID()<<endl;/*显示正在等待的顾客的数量*/cout<<"正在等待的顾客的数量:"<<Bank1.waitingcustomer.size()<<endl;cout<<endl;Bank1.DisplayWaitingTime(CustomerTrack2);Sleep(2000);}PresentTime++;if(PresentTime==80)nnn=20;}}int TotalNum=0;for(int rr=0;rr<5;rr++){cout<<"窗口"<<rr+1<<"服务顾客数量:"<<num[rr]<<endl;TotalNum+=num[rr];}cout<<"顾客平均等待时间为:"<<static_cast<double>(AverageTime)/static_cast<double>(TotalNum)<<endl;system("pause");return 0;}。
综合性设计性实验报告专业:软件工程班级:*** 组别: ***——***学年第 2 学期课程名称Unix高级编程指导教师***Weibo昵称:年年有余事事顺利本组成员学号姓名实验地点逸夫楼A实验时间***-06-08实验类型实践课实验名称银行排队叫号模拟系统实验环境: VMware虚拟机实验内容:编程实现一个“银行排队模拟系统”1)该程序模拟客户到银行取号-排队-被叫号-被服务的过程;2)程序执行流程如下:Step1: 客户到达银行,并从取号机取号;Step2: 如果大厅中有空闲座位,则座下等待,否则,在大厅外等待;Step3: 银行职员如果发现有客户等待,则依次叫号服务,否则休息;Step4: step1-step4重复执行3)大厅中座椅数量为20个;4)服务窗口为2个;5)“客户到来”通过命令行输入客户名字模拟;6)为了模拟实际情况,每个客户服务时间不小于20秒,可随机确定;7)程序顺序列出不同窗口服务客户的:名称,窗口号,服务时间2、提示1)需一个主控进程,随时监控客户到来,并为之创建进程;2)取号机应视为互斥型临界资源3)座椅应视为临界资源4)客户等待及被叫号应视为进程间同步过程实验目的与要求:掌握常用IPC方法能够应用IPC方法解决实际编程问题设计思路:(设计原理、设计方案及流程等)设计原理:“银行排队模拟系统”由于进程之间通信需要进行相应进程通信机制实现,进程通信机制很多,比如信号量、管道、消息队列、套接字等通过我们组的讨论决定用信号量机制的函数来实现,因此通过我们组的讨论决定以这样的方式来进行设计:通过信号量机制<signal.h>创建子进程fork()的过程来实现设计方案:主控进程即服务进程需完成以下任务:1.创建信号量集,并为之初始化2.监督客户的到来(实时循环)3.客户输入名字后,为客户创建子进程。
4.子进程进行相关操作。
实现与主进程的同步。
5.服务进程等待有人(p操作)(P(S3))p成功,显示窗口信息6.服务进程叫号(v操作)(V(S4))7.v成功,则进行服务子进程完成的操作:1.取号(因互斥有对取号的互斥信号量S1初值1)2.申请椅子(有资源信号量S2 初值20)(P(S2))3.唤醒柜员(告知柜员有人故有同步信号量S3,初值为0) (V(S3))4.等待叫号(故有同步信号量S4,初值为0,S3,S4实现父子进程的同步) (P(S4))5.4通过,输出客户名字5.4通过,则释放椅子(V(S2))8.显示服务时间(不少于20s)程序流程:Step1: 客户到达银行,并从取号机取号;Step2: 如果大厅中有空闲座位,则座下等待,否则,在大厅外等待;Step3: 银行职员如果发现有客户等待,则依次叫号服务,否则休息;Step4: step1-step4重复执行大厅中座椅数量为20个;服务窗口为2个;“客户到来”通过命令行输入客户名字模拟;为了模拟实际情况,每个客户服务时间不小于20秒,可随机确定;程序顺序列出不同窗口服务客户的:名称,窗口号,服务时间提示:需一个主控进程,随时监控客户到来,并为之创建进程;取号机应视为互斥型临界资源座椅应视为临界资源客户等待及被叫号应视为进程间同步过程关键技术分析:1)使用信号量机制-int crt_sig(key_t key,int nsems)2)创建一个子进程 pid_t crt_child()3)使用消息队列-int msg_stat(int msqid,structmsqid_ds msg_info)4)使用sem-op函数来设置程序的申请与释放,sem_op>0对应相应进程要释放sem_op数目的共享资源;sem_op=0可以用于对共享资源是否已用完的测试; sem_op<0相当于进程要申请-sem_op个共享资源5)利用函数void srand()和rand()来获取系统的服务时间等实验步骤:编写程序:源代码为:#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/wait.h>#include<time.h>#include<sys/sem.h>#include<signal.h>#include<errno.h>#define N_SEC 20static union semun{int val;struct semid_ds *buf;unsigned short * array;struct seminfo *__buf;}arg;int BeginWaiter(int sems,int num) {int id=-1;if(!(id=fork()))//child{while(1){struct sembuf op={2,-1,0};if(-1==semop(sems,&op,1))exit(0);op.sem_num=3;op.sem_op=1;if(-1==semop(sems,&op,1))exit(0);///serviceint random=1+(int)(20.0*rand()/(RAND_MAX*1.0));printf("\n********\n%d is on duty,serve time=%d\n***********\n",num,20+random);sleep(10+random);}}elsereturn id;}int main(int argc, char *argv[]){printf("parent id=%d\n",getpid());int sems=semget(IPC_PRIVATE,5,0666);union semun arg;unsigned short init_v[5]={1,20,0,0,0};arg.array=init_v;semctl(sems,0,SETALL,arg);char custom[100]="";////////////////////////srand(0);int s1=BeginWaiter(sems,0);int s2=BeginWaiter(sems,1);printf("Waiters are:%d,%d",s1,s2);//////////////while(1){printf("Welcome!please input you name:");scanf("%s",custom);if(!strcmp(custom,"exit")){semctl(sems,0,IPC_RMID,arg);kill(SIGKILL,s1);kill(SIGKILL,s2);exit(0);}if(!fork())//child{struct sembuf ops={0,-1,0};semop(sems,&ops,1);//p mutex,alternativeops.sem_num=4,ops.sem_op=1;semop(sems,&ops/*(struct sembuf*)&{4,1,0}*/,1);//get ticketops.sem_num=0;ops.sem_op=1;semop(sems,&ops/*(struct sembuf*)&{0,1,0}*/,1);//V mutex.alternative/////////////////////ops.sem_num=1;ops.sem_op=-1;semop(sems,&ops/*(struct sembuf*)&{1,-1,0}*/,1);//compete for seatint seats=semctl(sems,1,GETVAL,arg);printf("\nThere are %d seates remained\n",seats);////////////////ops.sem_num=2;ops.sem_op=1;semop(sems,&ops/*(struct sembuf*)&{2,1,0}*/,1);//wake waiter upops.sem_num=3;ops.sem_op=-1;semop(sems,&ops/*(struct sembuf*)&{3,-1,0}*/,1);//wait for called forops.sem_num=1;ops.sem_op=1;semop(sems,&ops/*(struct sembuf*)&{1,1,0}*/,1);//release seat;//get serviceprintf("\n**********\ncustom:%s\n**************\n",custom);exit(0);}}}运行结果如下:实验分析:明确题意 ----要求的是编写小程序,非传统意义上的系统。
DeskDriver[i].enable=1; //开启允许无线发送DeskDriver[i].sendCount=0 /初始值 0 表示发送次数为 0,发送一次加 1 DeskDriver[i].sendOK=0; //初始值 0 表示没发送成功}}}#endifif(RCVCOMP_ID==1)//task1接收完成,发送数据{IO1CLR=IO1CLR|LED1;DelayNS(20);IO1SET=IO1SET|LED1;DelayNS(20);IO1CLR=IO1CLR|LED1;DelayNS(20);IO1SET=IO1SET|LED1;RCVCOMP_ID=0;UART0_SendBuf();UART0_SendBufEx(RcvBuf,RCV_LEN1+2); RcvBuf[0]=0x05;RFSendPacket((char*)RcvBuf,17);}if(SCAN_ID==1){SCAN_ID=0;KeyScan();}//task3发送柜台号if(SendDesk_ID==1){SendDesk_Pro();SendDesk_ID=0;}#ifdef WATCHDOGIRQDisable();WDFEED = 0xAA;WDFEED = 0x55;IRQEnable();#endif}return 0;}void DelayNS (uint32 dly)//从机地址//task2按键扫描//看门狗喂狗//关中断//第一次喂狗启动 WDT//喂狗序列//开中断{uint32 i;for ( ; dly>0; dly--)for (i=0; i<50000; i++);}//短延时子程序void delay(uint8 t){ uint8 i,j;for(i=0;i<t;i++)for(j=0;j<10;j++);}void VAR_Init(void){uint8 i;set.datab= 8; //串口数据位set.stopb= 1; //串口住手位set.parity = rcv_new = 0; RSMCHR=0; RSMCHR=0; RSSMS_ID=0; ;/串口校验位//串口接收完数据标志//接收数据暂存变量//判断接收数据用标志//直接接收数据标志RCVCOMP_ID=0; SCAN_ID=1; INPUT1=0; INPUT1_ID=1; Desk_NUM=0x5 0;SendDesk_ID=0; timerCount=0;//接收完成标志//按键扫描定时标志//按键扫描去颤动计数//按键按下放开标志//柜台号,初始值为无效柜台号//发送柜台号标志//定时器计数变量for(i=0;i<MaxDeskNum;i++){DeskDriver[i].allow10s=1; //初始值 1 为 10 秒已经过去,可以接受按键柜台号DeskDriver[i].keyScaned=0;//初始值 0 表示还没有按键柜台号被接受DeskDriver[i].sendCount=0;//初始值 0 表示发送次数为 0,发送一次加 1DeskDriver[i].sendOK=0; //初始值 0 表示没发送成功DeskDriver[i].timeCnt=0; //初始值 0,定时计数为 0,每秒加 1DeskDriver[i].enable=1; //初始值 1 表示允许发送}}void IO_Init(void){PINSEL0 = 0x00000005; //设置 I/O连接到 UART0PINSEL0 =PINSEL0 |0x00050000 ; //配置 UART1 引脚功能PINSEL0 =PINSEL0 |0x00005500 ; /置 SPI 总线引脚 0.4sck 0.5miso 0.6mosi0.7SSELPINSEL1 = 0x00000001; //配置 p0.16 TI_CC_GDO0_PIN 为外部中断引脚IO0DIR = 0x00000000;IO1DIR = 0x00000000;IO1DIR = IO1DIR|IO1DIR|LED1|LED2|LED3|LED4; //连 LED 的引脚配置为输出引脚IO0DIR=IO0DIR|KEY_R1 | KEY_R2| KEY_R3| KEY_R4; //行线引脚配置为出输出引脚IO0DIR=IO0DIR|MOSI0|SCLK0|TI_CC_CSn_PIN; //配置 SPI 的 cs 片选为输出MOSI0|SCLK0|EXTMODE=0x01; EXTPOLAR=0x00; }void TC0_Init(void) //EINT0使用边沿激活//下降沿或者低电平有效{T0TC T0PR T0M CRT0MR0T0TCR = 0;= 0;= 0x03; =Fpclk / 50; =0x01;//定时器设置为 0//时钟不分频//设置 T0MR0 匹配后复位 T0TC ,并产生中断标志//20毫秒 100 则 10ms 定时,修改定时间隔只需修改除数//启动定时器}void __irq IRQ_Timer0 (void){timerCount++;if(timerCount>20) //0.4秒计数{timerCount=0;#ifdef WIRLTESTTimerSend_ID=1;#endifif(IO1PIN&LED2) IO1CLR=IO1CLR|LED2;else IO1SET=IO1SET|LED2;time1sCount++;if(time1sCount>=3){time1sCount=0;UpdataDesk();} sendDeskNum();}SCAN_ID=1;T0IR = 0x01; VICVectAddr = 0x00; }//1.6秒执行一次//更新柜台号结构体的信息//发送柜台号给 pc 端//开启按键扫描//清除中断标志,并复位中断//通知 VIC 中断处理结束void UpdataDesk(void) {uint8 i;for(i=0;i<MaxDeskNum;i++){if(DeskDriver[i].allow10s==0) //按键按下还没有过 10s 限定时间{DeskDriver[i].timeCnt++;if((DeskDriver[i].timeCnt==2) | (DeskDriver[i].timeCnt==4) | (DeskDriver[i].timeCnt==5)) { DeskDriver[i].enable=1; //每隔 3 秒允许发送}if(DeskDriver[i].timeCnt>=7/超过限定时间,开启允许接收按键,并更新整个结构体{DeskDriver[i].allow10s=1;DeskDriver[i].keyScaned=0;//初始值 0 表示还没有按键柜台号被接受DeskDriver[i].sendCount=0;//初始值 0 表示发送次数为 0,发送一次加 1DeskDriver[i].sendOK=0;DeskDriver[i].timeCnt=0;DeskDriver[i].enable=1;}}}}//初始值 0 表示没发送成功//初始值 0,定时计数为 0,每秒加 1 //初始值 1 表示允许发送//end forvoid sendDeskNum(void){uint8 i;for(i=0;i<MaxDeskNum;i++) //论询所有柜台结构,看是否有满足发送条件的{if((DeskDriver[i].keyScaned==1)&(DeskDriver[i].sendOK==0)&(DeskDriver[i].enable==1)) { DeskLoadBuf(i); //将柜台号转载到发送缓冲区RFSendPacket(SendBuf, PAKT_LEN+1); //无线发射DeskDriver[i].sendCount++;DeskDriver[i].enable=0;return;}}}void DeskLoadBuf(uint8 deskNum) //发送次数加 1 //关闭允许发送{SendBuf[0]=OPPO_ADDR; //对方无线地址SendBuf[1]='a'; //打头关键字SendBuf[2]='b';SendBuf[3]=(char)deskNum; //柜台号码SendBuf[4]=0x0d;SendBuf[5]=0x0a;}//结尾关键字#ifdef WATCHDOGvoid WATCHDOG_Init(void){while(( WDMOD & 0x04 ) == 0x04) {WDMOD = 0x00;} //判断看门狗超时标志/ 软件清零看门狗超时标志位WDTC = 0x5f0000;WDMOD = 0x03;IRQDisable();WDFEED = 0xAA;WDFEED = 0x55;IRQEnable();}//设置看门狗定时器参数//设置看门狗模式:中断且复位//关中断//第一次喂狗启动 WDT//喂狗序列//开中断#endifint8 UART0_Init (uint32 baud, UARTMODE set) {uint32 bak;/* 参数过滤 */if ((baud ==0 ) || (baud > 115200)) return (0);if ((set.datab <5) || (set.datab > 8)) return (0);if ((set.stopb == 0) || (set.sto t r ))(0);if (set.parity >r urn (0);/* 设置串口波特率 */U0LCR = 0x80;bak = (Fpclk >> 4) / baud; (Fpclk/16)/16U0DLM = bak >> 8;bak/256 // DLAB = 1 使能除数所存访问//外设时钟左移四位相当于除以 16 相当于//除数高位取 16 位分频值的高 8 位相当于U0DLL = bak & 0xFF; //除数低位取 16 位分频值的低 8 位相当于bak%256/* 设置串口模式 */bak = set.datab - 5; //设置字长if (set.stopb ==b |= 0x04;//判断是否为 2 位住手位if (set.parity != 0){set.parity = set.parity - 1;bak |= 0x08;}bak |= set.parity << 4; U0LCR =(bak&0x7F); //设置奇偶校验//DLAB 除数访问位置 0 ,用于访问接收发送寄存器U0FCR = 0x01;U0IER = 0x01;return (1);}void __irq IRQ_UART0 (void){if ((U0IIR & 0x0F) == 0x04) {RSMCHR = U0RBR;if(RSSMS_ID==0) judge_RCV();else direct_RCV();}VICVectAddr = 0x00;}void judge_RCV(void){if (HDM1_ID==0) //使能FIFO ,并设置触发点为 8 字节//允许 RBR 中断,即接收中断//通过读取 U0IIR 来清除中断//读取接收的数据//直接保存到接收数组//中断处理结束//第一次判断{if(RSMCHR==cnPUREDA TCHR1){HDM1_ID=1;RcvBuf[0]=RSMCHR;}}else{if(RSMCHR==cnPUREDATCHR2){RcvBuf[1]=RSMCHR;RSSMS_ID=1;RSMLEN=RCV_LEN1;RcvPointer=2;HDM1_ID=0;}else{HDM1_ID=0;}}}void direct_RCV(void){RcvBuf[RcvPointer]=RSMCHR;//判断为点阵数据关键字 1 0xaa //保存关键字 1//第二次判断//判断为点阵数据关键字 2 0x55//保存关键字 1//置直接保存数据标志//置接收数据长度//置接收数据指针为 2//向接收数据缓冲区保存数据RcvPointer++;RSMLEN--;if (RSMLEN==0){RCVCOMP_ID=1;RSSMS_ID=0;RcvPointer=2;}} //接收缓冲区地址加 1//接收长度减 1//当接收长度变为 0 时,置相应标志//置接收完成标志//清除直接接收数据标志//接收数据缓冲区地址归位void {} void {} void {UART0_SendBuf (void)uint8 i;for (i=0; i<(RCV_LEN1+2); i++)U0THR =RcvBuf[i];while ((U0LSR & 0x20) == 0);//等待数据发送完毕UART0_SendBufEx (char * buffer ,uint8 len)uint8 i;for (i=0; i<(len); i++)U0THR =buffer[i];while ((U0LSR & 0x20) == 0);//等待数据发送完毕VIC_Init(void)IRQEnable();VICIntSelect = 0x00000000; VICVectCntl0 = 0x20 | 14; //使能 IRQ 中断//设置所有的通道为 IRQ 中断//分配 EINT0 中断到向量中断 1VICVectAddr0 = (uint32)IRQ_Eint0;//设置中断服务程序地址VICVectCntl2 = 0x20 | 0x06; // UART0 分配到 IRQ slot,0 即最高优先级VICVectAddr2 = (uint32)IRQ_UART0; //设置 UART0 向量地址VICVectCntl1 = 0x20 | 0x04; //设置定时器 0 中断通道分配向量中断 1VICVectAddr1 = (uint32)IRQ_Timer0; /置中断服务程序地址VICIntEnable =(1<<14) | (1 << 0x06) | (1<<0x0使4);能//SPI 中断&UART0 中断和定时器 0 中断}uint8 KeyScan(void){uint8 nRes = 0;IO0CLR = IO0CLR|KEY_R1|KEY_R2|KEY_R3|KEY_R4; //行线输出全部输出高电平delay(5); //读取各个管脚的状态,判断是列线引脚是否有低电平浮现if(((IO0PIN&KEY_C1)==0) | | ((IO0PIN&KEY_C2)==0) | | ((IO0PIN&KEY_C3)==0) | | ((IO0PIN&K EY_C4)==0)){INPUT1++; //每 20ms 扫描一次,浮现低电平的次数计数if (INPUT1>=8) //超过一定次数,说明按键按下已经稳定,读取按键{if (INPUT1_ID==1) //为 0,表示按键按下未放开,当按键向来按下时,只进行一次处理{INPUT1_ID=0;nRes =KeyProcess();return nRes;}}}else{INPUT1=0;INPUT1_ID=1;}return 0;}uint8 KeyProcess(void)//列线无低电平浮现,计数清零//没有输入,为干扰*/{uint8 nResult = 0;//第一行输出低电平IO0CLR = IO0CLR|KEY_R1;IO0SET = IO0SET|KEY_R2|KEY_R3|KEY_R4;delay(2);if((IO0PIN&KEY_C1)==0) nResult = 4;if((IO0PIN&KEY_C2)==0) nResult = 3;if((IO0PIN&KEY_C3)==0) nResult = 2;if((IO0PIN&KEY_C4)==0) nResult = 1;if(nResult !=0 )goto result;//第三行输出低电平IO0CLR = IO0CLR|KEY_R3;IO0SET = IO0SET|KEY_R1|KEY_R2|KEY_R4;delay(2);if((IO0PIN&KEY_C1)==0) nResult = 12;if((IO0PIN&KEY_C2)==0) nResult = 11;if((IO0PIN&KEY_C3)==0) nResult = 10;if((IO0PIN&KEY_C4)==0) nResult = 9;if(nResult !=0 )goto result;//第二行输出低电平IO0CLR = IO0CLR|KEY_R2;IO0SET = IO0SET|KEY_R1|KEY_R3|KEY_R4; delay(2);if((IO0PIN&KEY_C1)==0) nResult = 8;if((IO0PIN&KEY_C2)==0) nResult = 7;if((IO0PIN&KEY_C3)==0) nResult = 6;if((IO0PIN&KEY_C4)==0) nResult = 5;if(nResult !=0 )goto result;//第二行输出低电平IO0CLR = IO0CLR|KEY_R4;IO0SET = IO0SET|KEY_R1|KEY_R2|KEY_R3; delay(2);if((IO0PIN&KEY_C1)==0) nResult = 16;if((IO0PIN&KEY_C2)==0) nResult = 15;if((IO0PIN&KEY_C3)==0) nResult = 14;if((IO0PIN&KEY_C4)==0) nResult = 13;/ 取各个管脚的状态result:Desk_NUM=nResult; SendDesk_ID=1;//保存柜台号//置发送柜台号标志if(DeskDriver[Desk_NUM].allow10s==1) {DeskDriver[Desk_NUM].allow10s=0;DeskDriver[Desk_NUM].keyScaned=1;DeskDriver[Desk_NUM].timeCnt=0;DeskDriver[Desk_NUM].enable=1;DeskDriver[Desk_NUM].sendCount=0; 1DeskDriver[Desk_NUM].sendOK=0;}return nResult;} //开始限定时间,在限定时间内不接受按键//接受按键,并置按下标志//计数归零//开启允许无线发送//初始值 0 表示发送次数为 0,发送一次加//初始值 0 表示没发送成功void SendDesk_Pro(void) {if (Desk_NUM==0x55) return;DeskBuf[0]='a';DeskBuf[1]='b';DeskBuf[2]=Desk_NUM;DeskBuf[3]=0x0d;DeskBuf[4]=0x0a;UART0_SendBufEx(DeskBuf,5);Desk_NUM=0x55;} //无效柜台号,返回//发送完毕,将柜台号置为无效柜台号void TI_CC_SPISetup(void){IO0SET=IO0SET|TI_CC_CSn_PIN ; //设置片选信号无效片选低电平有效PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x55 << 8) ; //设置管脚状态SPCCR = 0x52;SPCR = (0 << 3) |(1 << 4) |(1 << 5) |(0 << 6) |(0 << 7); }//设置 SPI 时钟分频 // CPHA = 0,数据在 SCK 的第一个时钟沿采样// CPOL = 1, SCK为低有效// MSTR = 1, SPI处于主模式 // LSBF = 0, SP数I据传输 MSB ( 位 7)在先// SPIE = 0, S I断被禁止Delay , ((cycles-15) % 6) + 15void TI_CC_Wait(unsigned int cycles0) {uint16 cycles=cycles0*56;while(cycles>15)cycles = cycles - 6;}void TI_CC_PowerupResetCCxxxx(void) {IO0SET=IO0SET|TI_CC_CSn_PIN; TI_CC_Wait(30);IO0CLR=IO0CLR|TI_CC_CSn_PIN; TI_CC_Wait(30);IO0SET=IO0SET|TI_CC_CSn_PIN; TI_CC_Wait(45);IO0CLR=IO0CLR|TI_CC_CSn_PIN; while (IO0PIN&SOMI0);SPDR = TI_CCxxx0_SRES; while( 0 == (SPSR & 0x80)); while (IO0PIN&SOMI0);IO0SET=IO0SET|TI_CC_CSn_PIN; }void writeRFSettings(void)//设置片选信号无效//设置片选信号有效//设置片选信号无效//至少 40us//设置片选信号有效//等待 CCxxxx 准备好//发送命令复位//等待 SPIF 置位,即等待数据发送完毕//等待 CCxxxx 准备好//设置片选信号无效{Write register settingsTI_CC_SPIWriteReg(TI_CCxxx0_IOCFG2, 0x0B); // GDO2输出脚配置(连续时钟) .TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG0, 0x06);//GDO0 输出脚配置(当同步词汇发送/收到时声明,在数据端末尾时反声明) .TI_CC_SPIWriteReg(TI_CCxxx0_SYNC1, 0xD3); //同步词汇高字节.TI_CC_SPIWriteReg(TI_CCxxx0_SYNC0, 0x91); / 步词汇低字节.TI_CC_SPIWriteReg(TI_CCxxx0_PKTLEN, 0x11); /数/据包长度 (17).TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL1, 0x05); //数据包自动控制(开启附加字节;地址检查,无广播) .TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL0, 0x04);//数据包自动控制 (开启 CRC ; 固定长度数据包) .TI_CC_SPIWriteReg(TI_CCxxx0_ADDR,HOME_ADDR); // 设备地址. TI_CC_SPIWriteReg(TI_CCxxx0_CHANNR, 0x10); /信/道数 (16).TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL1, 0x06); /频/率合成器控制(软件给出) . TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL0, 0x00); /频/率合成器控制(软件给出) . TI_CC_SPIWriteReg(TI_CCxxx0_FREQ2, 0x10);//频率控制词汇, 高字节(软件给 .TI_CC_SPIWriteReg(TI_CCxxx0_FREQ1, 0xA7); //频率控制词汇, 中字节(软件给 .TI_CC_SPIWriteReg(TI_CCxxx0_FREQ0, 0x62);//频率控制词汇, 低字节(软件给 .TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4, 0x2a);//调制器配置(信道滤波带宽: 101.56K) .TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG3, 0x83); /调/制器配置(数据率 38.4k) .TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2, 0x11); /调/制器配置( GFSK 格式; 15/16 同步词汇侦测) .TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG1, 0x22); /调/制器配置( FEC ,前导数目) . TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG0, 0xF8); // 调 制 器 配 置 ( 信 道 空 间 199.951172 .TI_CC_SPIWriteReg(TI_CCxxx0_DEVIATN, 0x34); /调/制器背离配置(软件给出 19k) TI_CC_SPIWriteReg(TI_CCxxx0_MCSM1 , 0x3F); / 通信控制状态机配置(完成后 保持在 RX ) .TI_CC_SPIWriteReg(TI_CCxxx0_MCSM0 , 0x18); /主/通信控制状态机配置(软件给 出) (下同) .TI_CC_SPIWriteReg(TI_CCxxx0_FOCCFG, 0x16); /频/率便宜补偿配置. TI_CC_SPIWriteReg(TI_CCxxx0_BSCFG, 0x6C); //位同步配置. TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL2, 0x43); // AGC 控制. TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL1, 0x40); // AGC 控制. TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL0, 0x91); // AGC 控制. TI_CC_SPIWriteReg(TI_CCxxx0_FREND1, 0x56); /前/末端 RX 配置. TI_CC_SPIWriteReg(TI_CCxxx0_FREND0, 0x10); /前/末端 TX 配置. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL3, 0xA9); //频率合成器校准. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL2, 0x2A); //频率合成器校准. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL1, 0x00); /频/率合成器校准. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL0, 0x11); /频/率合成器校准. TI_CC_SPIWriteReg(TI_CCxxx0_FSTEST, 0x59); /产/品测试.TI_CC_SPIWriteReg(TI_CCxxx0_TEST2, 0x81); /不/同的测试设置.TI_CC_SPIWriteReg(TI_CCxxx0_TEST1,TI_CC_SPIWriteReg(TI_CCxxx0_TEST0, } void TI_CC_SPIWriteReg(char addr, char{ IO0CLR=IO0CLR|TI_CC_CSn_PIN;0x35); /不/同的测试设置. 0x0B); //不同的测试设置.value)//设置 片选信号有效出) 出) 出)while (IO0PIN&SOMI0);SPDR = addr;while( 0 == (SPSR & 0x80));SPDR = value;while( 0 == (SPSR & 0x80));IO0SET=IO0SET|TI_CC_CSn_PIN; }//等待 CCxxxx 准备好//等待 SPIF 置位,即等待数据发送完毕//等待 SPIF 置位,即等待数据发送完毕//设置片选信号无效void TI_CC_SPIWriteBurstReg(char addr, char *buffer, char count) {char i;#ifdef WIRLUART#endifIO0CLR=IO0CLR|TI_CC_CSn_PIN;while (IO0PIN&SOMI0);SPDR = addr | TI_CCxxx0_WRITE_BURST; while( 0 == (SPSR & 0x80));for (i = 0; i < count; i++){SPDR = buffer[i];while( 0 == (SPSR & 0x80)); } IO0SET=IO0SET|TI_CC_CSn_PIN;#ifdef WIRLUART//设置片选信号有效//等待 CCxxxx 准备好//发送首地址//等待 SPIF 置位,即等待数据发送完毕//挨次发送数据//等待 SPIF 置位,即等待数据发送完毕//设置片选信号无效#endif}void __irq IRQ_Eint0(void){if(RFReceStadPacket(rcv_buf,PAKT_LEN+1,AddState)/)/接收数据包和附加字节( RSSI,CRC,LQI ){LoadRcvBuf();SendDate(rcv_buf,AddState);if(IO1PIN&LED2)IO1CLR=IO1CLR|LED1;elseIO1SET=IO1SET|LED1;#ifdef WIRLUARTrcv_buf[3]=rcv_buf[3]+0x30;UART0_SendBufEx((char*)(&(rcv_buf[3])),1);#endifTI_CC_SPIStrobe(TI_CCxxx0_SFRX); //冲洗 RX BUFFER}else{TI_CC_SPIStrobe(TI_CCxxx0_SIDLE); //置空暇模式TI_CC_SPIStrobe(TI_CCxxx0_SCAL); //手动校正频率合成器TI_CC_SPIStrobe(TI_CCxxx0_SFRX); //冲洗 RX BUFFERTI_CC_SPIStrobe(TI_CCxxx0_SFTX); //冲洗 RX BUFFERTI_CC_SPIStrobe(TI_CCxxx0_SRX);#ifdef WIRLUART//转为接收模式#endif}#ifdef WIRLUART#endifEXTINT = 0x01;VICVectAddr = 0x00;}//清除 EINT0 中断标志char RFReceStadPacket(char *rxBuffer,char length,char *status){if ((TI_CC_SPIReadStatus(TI_CCxxx0_RXBYTES) & TI_CCxxx0_NUM_RXBYTES)) { #ifdef WIRLUART#endifTI_CC_SPIReadBurstReg(TI_CCxxx0_RXFIFO, rxBuffer, length)弹; /数据TI_CC_SPIReadBurstReg(TI_CCxxx0_RXFIFO, status, 2);/ 附加字节暂未使用return (char)(status[TI_CCxxx0_LQI_RX]&TI_CCxxx0_CRC_OK);}else{return 0; //报错}}char TI_CC_SPIReadStatus(char addr){char x;uint32 i;i=0;IO0CLR=IO0CLR|TI_CC_CSn_PIN; while (IO0PIN&SOMI0){if(i>5000){//设置片选信号有效//等待 CCxxxx 准备好#ifdef WIRLUART#endifreturn 0;}//超时返回i++; }SPDR =(addr | TI_CCxxx0_READ_BURST);// 发送读取数据的地址while( 0 == (SPSR & 0x80)); SPDR = 0;while( 0 == (SPSR & 0x80)); x = SPDR;IO0SET=IO0SET|TI_CC_CSn_PIN; #ifdef WIRLUARTch[0]=x;UART0_SendBufEx(ch,1);#endifreturn x;//等待 SPIF 置位,即等待数据发送完毕//写入哑函数以读取数据//等待 SPIF 置位,即等待数据发送完毕//读出数据//设置片选信号无效//此处不能有串口发送函数,时间会影响//TI_CC_SPIReadBurstReg//返回寄存器的值}void TI_CC_SPIReadBurstReg(char addr, char *buffer, char count) {unsigned int i;IO0CLR=IO0CLR|TI_CC_CSn_PIN;while (IO0PIN&SOMI0);SPDR = (addr | TI_CCxxx0_READ_BURST);//设置片选信号有效//等待 CCxxxx 准备好//发送首地址while( 0 == (SPSR & 0x80));for (i = 0; i < count; i++){//等待 SPIF 置位,即等待数据发送完毕SPDR = 0 ;while (0 ==(SPSR & 0x80));buffer[i] = SPDR;}IO0SET=IO0SET|TI_CC_CSn_PIN; }void TI_CC_SPIStrobe(char strobe) //读出数据//设置片选信号无效{uint32 i;#ifdef WIRLUART #endifIO0CLR=IO0CLR|TI_CC_CSn_PIN; while (IO0PIN&SOMI0){ //设置片选信号有效//等待 CCxxxx 准备好if(i>5000){#ifdef WIRLUART#endifreturn ; //超时返回}i++;}SPDR = strobe;while( 0 == (SPSR & 0x80));IO0SET=IO0SET|TI_CC_CSn_PIN; #ifdef WIRLUART//发送命令滤波//等待 SPIF 置位,即等待数据发送完毕//设置片选信号无效#endif}void RFSendPacket(char *txBuffer, char size){#ifdef WIRLUART#endifTI_CC_SPIWriteBurstReg(TI_CCxxx0_TXFIFO, txBuffer, size)写;入//发送数据TI_CC_SPIStrobe(TI_CCxxx0_STX); //进入发送模式发送数据while ((IO0PIN&TI_CC_GDO0_PIN)==0); //等待 GDO0 变高#ifdef WIRLUART#endifwhile (IO0PIN&TI_CC_GDO0_PIN);#ifdef WIRLUART//等待 GDO0 变低,结束发送#endif}。