四川师范大学成都学院
排队叫号系统设计 —电线路实现训练
学生姓名 学 号 所 在 系 专业名称 班 级 指导教师
李 松 ********** 通信系 通信工程 2009级通信工程1班
刘强、段纯爽
四川师范大学成都学院
二○一一年六月
一、设计任务
排队叫号系统设计 设计内容
主机通过按键完成叫号,数码管显示被叫的号码;蜂鸣器响,提醒顾客接受服
务;
从机通过串行通信方式完成排队取号功能;
从机显示队列中排在其前面的顾客数;
二、方案与论证
1.单片机芯片的选择方案和论证 方案一
采用AT89S51芯片作为硬件核心,内部具有4KB ROM存储空间,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术,所以在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次插拔会对芯片造成一定饿损坏。 方案二
采用STC89C52芯片,STC89C52S是一种低功耗、高性能的8位CMOS微控制器,具有8K的可编程Flash存储器,同样具有AT89S51的功能,且具有在线编程可擦除技术,当对电路进行调试时,由于程序的错误修改或对程序新增功能需要烧入程序时,不需要对芯片多次插拔,所以不会对芯片造成损坏。
综上所述,选择采用STC89C52作为主控制系统核心。 2.显示模块选择方案和论证 方案一
采用LED数码管动态扫描,LED数码管价格适中,对于显示数字合适,采用动态扫描法语单片机连接时,虽然占用的单片机口线少,但连线还需要花费一点时间,所以也不用此种作为显示。 方案二
采用点阵式数码管显示,点阵式数码管时由八行八列的发光二极管组成,对于显示文字比较合适,若采用在显示数字显得太浪费,且价格相对较高,所以在此也不用此种作为显示。 方案三
采用1602液晶显示屏,该显示屏的显示功能强大,内置192种字符,可显示大量的符号、数字、清晰可见,而且功率消耗小寿命长抗干扰能力强。 综上所述,在设计中采用1602液晶显示屏。
三、系统硬件设计
(一)系统总框图
备上电后,显示器屏幕亮,无信息显示。当客户按键后,每按一下,队伍加1,显示器显示客户队伍号;排满20位后,再按取号键,屏幕显示“队伍满”。当客服叫号时,队伍减1,程序进行信息处理,在显示器上显示“几号客户到几号窗口”,同时进行声音提示;当队伍空时,显示“队伍空”,显示器屏幕清空,储存的队伍号码归零处理 (二)原理图设计
主要以AT89C51为控制核心,包括显示电路,音乐提示电路,晶振电路。共四大板块
1602液晶显示 叫号提示音 AT89C51 客户端取号 单片机终端窗口叫号 晶振电路
AT89C51中有一个用于构成内部振荡器的高增益反相放大器,引脚XTAL1和XTAL2分别是该放大器的输入端和输出端。这个放大器与作为回馈组件的片外石英晶体或陶瓷谐振器一起构成自激振荡器。
外接石英晶体(或陶瓷谐振器)及电容C1、C2接在放大器的反馈回路中构成并联振荡电路。对外接电容C1、C2虽然没有十分严格的要求,但是电容容量的大小会轻微影响振荡频率的高低、振荡器工作的稳定性、起振的难易程序及温度稳定性,如果使用石英晶体,我们推荐电容使用30pF±10pF,而如果使用陶瓷谐振器建议选用40pF±10pF。
使用外部振荡器时,外部振荡信号应直接加到XTAL1,而XTAL2悬空。内部方式时,时钟发生器对振荡脉冲二分频,如晶振为12MHz,时钟频率就为6MHz。晶振的频率可以
在1MHz-24MHz内选择。电容取30PF左右。本系统采用内部方式,晶振选用12MHz。
液晶显示电路
图5.2晶体内部方式
如下图5.3,P1口接LCD1602的8个双向数据线接口,P3.4接1602的数据/命令选择端,P3.5接1602的读/写选择端,P3.6接1602的使能信号。BLA、BLK分别是1602的背光源的正负极,VL是1602对比度调整端。本文是通过对RS、RW以及E的高低电平进行写指令和写数据操作来控制1602的显示的。
图5.3液晶显示电路
5.3声音提示电路
使用最简单的蜂鸣器来作为提示音部分,通过改变端口高低电平来进行发声,并对延时进行修改来调试发声频率,从而修改发出的声音的好坏
四、系统软件设计
开始 客户取号 初始化 队伍号码累加 队伍空显示器初始化、清零 窗口消号 队伍号码递减 1602显示信息 信息处理 结束 声音提示
五、总结与展望
此课题对于目前的我们来说难度相对较大,通过查阅相关书籍、网上资料和一些仿真实例,做成了现在的排队叫号系统。此系统采用LCD1602显示,做起来比较简单,只设立了两个处理窗口,虽然很少,不过根据需要可以自行增加,具有较好的扩展功能。设计采用声音提示,由于能力有限,不会编写音乐程序,就用了最简单的蜂鸣器声音,通过改变延时程序,对蜂鸣器的频率来进行调节,最后声音勉强可以。本设计虽不及现今比较成熟的产品,不过对需求不是很高的人还是可以的。从此次设计中,我学到了很多,对没有掌握的知识都有了一定的了解。特别是单片机有了更深的了解,学好单片机,对于我们将来也是大有帮助,可以为我们生活提供更好的便捷,我也会再接再厉学好单片机,运用好单片机,让他更好的为我们服务。
六、参考文献
[1]马骏.车站售票大厅智能排队叫号系统的设计和开发. 科技情报开发与经济. 2010年第20卷第19期
[2] 杨彦、王霖、张凤荔、刘丽萍. 基于RS485 和单片机的排队机控制系统设计. 中文核心期刊《微计算机信息》(测控自动化)2008 年第24 卷第1-1 期
[3] 张忠安 齐俊传. 门诊排队叫号系统设计. 医疗卫生装备·2006年第27卷第10
[4] 欧志旋. 一种基于单片机开发的排队叫号系统设计. 计算机光盘软件与应用2010 年第6 期
[5]唐海波 于宏图 李继平. 单片机在服务叫号管理系统中的应用. 《微型机与应用》2002年第5期
[6] 黄璟. 基于89C51单片机的排队系统主显示屏的设计.科技风2009.19期 [7] 杨连国 史小军 堵国梁 朱为.LED显示屏在医院排队叫号系统中的应用。现代显示2006。6
[8] 张毅刚。MCS-51单片机应用设计。哈尔滨:哈尔滨工业大学出版社
[9] 闫玉德 俞虹。MCS-51单片机原理与应用(C语言版)。机械工业出版社。2003
附录一:系统总电路
附录二:源代码
#include #define uchar unsigned char #define uint unsigned int sbit rs=P2^0; sbit rw=P2^1; sbit e=P2^2; sbit key1=P1^0; sbit key2=P1^1; sbit key3=P1^2; sbit sounder=P3^7; uchar prompt1[]=\"Your No.is 00!\"; uchar prompt2[]=\"No.00 Go To Win.0\"; uchar prompt3[]=\"Queue is full \"; uchar prompt4[]=\"Queue is empty !\"; uint num_count=0; //排队叫的号码 uint rank_number[20]={0}; //排队叫号存储的数组 uint num=0; //窗口消的号码 int RankFlag=0; //叫号的标志 int ClearNumFlag=0; //消号的标志 uint LengthFlag=0; //队列长度 叫一次号时+1,消一次号时-1 /*延时函数*/ void delay(uint n) { while (n--); } /***************************************** LCD1602 *显示屏命令写入函数* *****************************************/ void LCD_write_com(uchar com) { e=0; rs=0; rw=0; P0= com; delay(1000); e=1; delay(1000); e=0; } /***************************************** LCD1602 *显示屏数据写入函数* *****************************************/ void LCD_write_data(uchar dat) { e=0; rs=1; rw=0; P0 = dat; delay(1000); e=1; delay(1000); e=0; } /***************************************** LCD1602 *显示屏清空显示* *****************************************/ void LCD_clear(void) { LCD_write_com(0x01); delay(1000); } /***************************************** LCD1602 显示屏初始化函数 *****************************************/ void LCD_init(void) { LCD_write_com(0x38); /*显示模式设置*/ delay(100); LCD_write_com(0x38); delay(100); LCD_write_com(0x38); delay(100); LCD_write_com(0x38); LCD_write_com(0x08); /*显示关闭*/ LCD_write_com(0x01); /*显示清屏*/ LCD_write_com(0x06); /*显示光标移动设置*/ delay(100); LCD_write_com(0x0C); /*显示开及光标设置*/ } /*简单的蜂鸣器提示音*/ void sound() { uint a; for(a=0;a<500;a++) { sounder=0; delay(61); sounder=1; } } /*获取键值函数*/ uint sweep_key() { uint jianzhi; if(key1==0) { delay(1000); if(key1==0) jianzhi=1; RankFlag=1; } if(key2==0||key3==0) { delay(1000); if(key2==0) jianzhi=2; if(key3==0) jianzhi=3; ClearNumFlag=1; } return (jianzhi); } /***************************************** 叫号机 按一次一号键变量+1,最大为20 *****************************************/ void QueueNumProcess() { if(RankFlag==1) //判断叫号标志是否有效 { if ( LengthFlag<20) { num_count++; rank_number[LengthFlag] = num_count; } LengthFlag++; } } /***************************************** 窗口消号处理函数 *****************************************/ void ClearNumProcess() { uint i; if (ClearNumFlag==1) //判断消号标志是否有效 { num=rank_number[0]; //把消的号赋给全局变量num for(i=0;i<19;i++) //让数组整体左移一个存储单元,即把消得号删除 { rank_number[i]=rank_number[i+1]; } LengthFlag--; } } /***************************************** 检测到按键后,检测函数处理及LCD显示处理 *****************************************/ void CheckButtonProcess(uint m) //m代表检测到的键值 { uint jz,i; jz=m; if((jz==1) && (RankFlag==1)) { // 当队列人数达到20时,提示 // Queue is full if( LengthFlag>=20 ) { LCD_clear(); LCD_write_com(0x80+0x02); delay(100); for(i=0;i<16;i++) { LCD_write_data(prompt3[i]); delay(100); } } else { QueueNumProcess(); prompt1[11]=(num_count)/10+'0'; prompt1[12]=(num_count)%10+'0'; LCD_clear(); LCD_write_com(0x80+02); delay(100); for(i=0;i<15;i++) { LCD_write_data(prompt1[i]); //\"Your No.is 00!\"; delay(100); } RankFlag=0; } } if((jz==2||jz==3) && ClearNumFlag==1) { if(LengthFlag==0) { LCD_clear(); LCD_write_com(0x80+0); delay(1000); for(i=0;i<16;i++) { LCD_write_data(prompt4[i]);//\"Queue is empty \"; delay(100); } delay(65535); //无人排队时屏幕自动清屏,计数归零 LCD_clear(); num_count=0; } else { ClearNumProcess(); //消号处理,营业员操作 sound(); prompt2[3]=num/10+'0'; prompt2[4]=num%10+'0'; prompt2[15]=(jz-1)+'0'; LCD_clear(); LCD_write_com(0x80+0); delay(100); for(i=0;i<16;i++) { LCD_write_data(prompt2[i]); //\"No.00 come to No.0\"; delay(100); } ClearNumFlag=0; } } } /***************************************** main 函数 *****************************************/ void main() { uint Kvalue; LCD_init(); while(1) { Kvalue=sweep_key(); //获取键值 if (RankFlag==1 || ClearNumFlag==1)//判断叫号标志和消号标志是否有效 CheckButtonProcess(Kvalue); delay(200); RankFlag=0; //使叫号标志无效 ClearNumFlag=0; //使消号标志无效 Kvalue=0; //键值清0 } } 因篇幅问题不能全部显示,请点此查看更多更全内容