基于eda的数字钟程序设计【实用文档】doc_第1页
基于eda的数字钟程序设计【实用文档】doc_第2页
基于eda的数字钟程序设计【实用文档】doc_第3页
基于eda的数字钟程序设计【实用文档】doc_第4页
基于eda的数字钟程序设计【实用文档】doc_第5页
已阅读5页,还剩88页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于eda的数字钟程序设计【实用文档】doc文档可直接使用可编辑,欢迎下载

基于eda的数字钟程序设计【实用文档】doc文档可直接使用可编辑,欢迎下载一、课题要求:(1)技术要求:1、掌握多功能数字钟的工作原理.2、应用EDA技术,VHDL语言编写程序。3、层次化设计,设计原理框图.4,、硬件设计及排版。(2)功能要求:1、基本功能:能进行正常的时、分、秒计时功能,分别由6个数码管显示24小时、60分钟、60秒的计数器显示。2、扩展功能:(1)能够利用按键实现“校时”“校分"“清零”功能。(2)能利用扬声器做整点报时,整点前五秒短声,整点长声.(3)本人工作:负责软件部分,,编写各部分模块的VHDL程序,并且锁定引脚,将程序下载到芯片中。二、设计方案:原理框图:数字钟原理框图一共有11个小模块:分频,片选,按键,小时,分,秒,显示模块,七段显示译码器,报时,扬声,36译码器。左边第一个是时钟信号输入端,50Mhz到分频模块。第二个为清零按键,第三个为校分按键,第四个为校时按键。右边第一个为七段显示译码器输出端,第二个为扬声器输出端,第三个为6个数码管输出端。中间模块为数字钟的核心,有计时,报时,校时功能。三、单元模块设计1、分频模块该模块是将时钟脉冲50Mhz分频到1000、500和1,分别给报时模块和及时模块。2、秒模块仿真图该模块为60进制计数器,有分频模块得到的1hz进行计时,计时输出为秒的数值,在计时到59时进位1到co端。当按下s3时,秒清零。3。、分模块仿真图该模块也为60进制计数器,计时输出为分的数值.在EN信号有效且时钟来时,计数器加1、在s2按下时,EN使能端有效,实现校分功能。4、时模块仿真图该模块为24进制计数器,计时输出为小时的数值,在EN信号到来时,计数器加1,在S1按下时,EN信号有效,实现校时功能。5、片选模块仿真图该模块提供数码管片选信号。6、按键模块仿真图该模块是有几个门电路组成,把它编写成一个模块,到时写程序方便。该模块连接几个按键,由按键控制。7、报时模块仿真图该模块为整点报时提供控制信号,当59分时,秒为50,52,54,56,58时,Q500输出“1”;秒为00时,Q1000输出“1”。这两个信号经过逻辑门实现报时功能。8、BBB模块仿真图该模块对应不同的片选信号送出不同的要显示的数据.9、36译码器模块仿真图该模块为36译码器,为输出到数码管对应功能.10、七段译码器模块仿真图该模块为七段译码器,输出到数码管的每一个引脚,可以正确的点亮每一个数码管。11、扬声模块仿真图该模块也为几个门电路组合,控制着对扬声器的输入,当时间到达某一点时,输出不同的脉冲信号到扬声器,给予扬声器信号.四、顶层模块设计程序图:总体框图顶层文件将上面11个小模块集合到一起构成了总的程序,最终也是将这个顶层文件写到FPGA芯片中.五、硬件电路设计由另一位同学负责,收集好器件,将器件排版在电路板上,并将其焊接成成品。六、硬件电路安装及调试在EDA中,将顶层文件各个输入与输出端口锁定引脚。锁定好引脚后将整个顶层文件下载到FPGA芯片中。注:在下载时,要注意先安装USB程序,再设置IDE环境设置,然后再programmer中选择自己要的文件,下载时必须先安装好芯片再接电源,下载成功后,先拔电源,再拔下USB。下载好以后,用杜邦线将硬件和芯片的引脚连接好,检查无误后进行测试。七、调试结果为了每个模块的正确性,将一一对每个模块进行测试.将芯片与硬件连接好,检查无误后,打开电源,此时硬件上的数码管开始计时,等到秒为59时,下一秒,分为1,秒为00。然后用校时功能按键将分校分到59分,此时当秒为50时,扬声器开始响,并且到整点时,扬声器持续响一段时间。按下S3,秒清零。调试结束,基本功能能够计时,并且进位到分和时,扩展功能,按下S2和S3后能够进行分和时的校时,并且到整点时开始报时。八、设计中遇到的问题及解决方案我负责软件部分,开始在编写程序时根本无从下手,再找了一些资料后终于对数字钟有些了解。用EDA设计每一个模块,都需要一个一个的去仿真,看程序对不对,经常在一些小程序上出现问题。本来有好多门电路,发现放在顶层文件中比较麻烦,所以将这些门电路组成两个模块,按键模块和扬声模块,这样方便顶层文件的编写。分频模块,由于要将50MHz的脉冲分到1000Hz,500Hz,和1Hz,分频量比较大,不能仿真,只能先改小一下数据,验证程序是否正确.36译码器部分,本来使用的是38译码器,发现多了2个输入,有6个数码管,但是38译码器并不影响输出.在下载过程,锁定引脚,发现芯片上的引脚与硬件上的引脚是反的,数码管显示的是乱码.当数字钟的时分秒顺序错了以后,不需要重新锁定引脚,只要将对应的杜邦线对调一下就行了。我们校时用的按键是自锁开关,其实只要改成下拉电阻就可以了。九、收获与体会经过两个星期的数电课程设计,收获很大,让我们自己设计了数电模型,从软件和硬件上学到了很多知识.两个同学一个设计软件,一个设计硬件,不仅提高了学习能力,还培养了团队合作能力.我负责的是软件部分,这学期正好学习了EDA技术,把它应用到了软件的程序编写中来。我们设计的是数字钟,虽然数字钟看起来很简单,但是要把每个模块全部搞在一起还是有点难度的。开始经过上网及图书馆借书来了解数字钟的结构与工作原理,把它每一部分的模块摸透清楚后,在开始编程,写入芯片.同时还要把软件与硬件结合起来,在各自做各自的工作时还要紧密结合自己组员的工作,只有两个人的东西做完后,组合起来才算真正的完成。首先明确好数字钟的功能,基本功能:能进行正常的时、分、秒计时功能,分别由6个数码管显示24小时、60分钟、60秒的计数器显示.扩展功能:(1)能够利用按键实现“校时”“校分”“清零"功能。(2)能利用扬声器做整点报时,整点前五秒短声,整点长声。然后设计好总的原理图,将功能全部覆盖进去,设计每个模块,用EDA中的VHDL编写程序,然后再仿真,根据仿真图检测自己的程序是否正确。当每个模块在电脑中仿真无误时,编写顶层文件,把各个小模块连接到一起,然后将整个程序画出原理框图,与自己预测的相比较。当软件做好后,用下载线将自己写的程序写进芯片中,不过此时要注意先连接好线才能开电源,当下载后,要先关电源,再拔USB接口。下载后与同组同学用杜邦线连接开始测试,第一次先将整个程序写入,发现没有正确显示,然后一个一个模块检测后,发现了问题,终于数字钟做好了,基本功能与扩展功能都出来了。这次课程设计后,软件方面有着明显的提高,而且合作啊能力也提高了,作品完成的还是很好的.首先要感谢老师的细心教导,让我学习到了好多知识,从硬件到软件,不仅仅是知识上,还有能力上,还要感谢同组同学,没有他的硬件,这次数字钟也完不成。这次收获还是很大的,自己的努力与汗水终于没有出,总结这次课程设计的经验,在以后的课程设计中能够更好的发挥!十、参考文献:1、《EDA技术与VHDL》清华大学出版社2、《数字系统设计与VerilogHDL(第三版)》王金明编著3、《EDA技术与应用(第2版)》江国强编著4、《EDA技术实用教程》科学出版社 开放性实验报告题目:基于ARM的多线程应用程序设计院系名称:电气工程学院专业班级:自动1302学生姓名:张鹏涛学号:201323020219指导教师:张晓东成绩:成绩:指导老师签名:目录TOC\o"1-3”\h\uHYPERLINK\l_Toc233581系统概述与设计要求PAGEREF_Toc233581HYPERLINK\l_Toc46671.1系统概述PAGEREF_Toc46671HYPERLINK\l_Toc121361.2设计要求PAGEREF_Toc121362286422方案论证PAGEREF_Toc2864222。1实现方法PAGEREF_Toc284922.2线程优势PAGEREF_Toc300312HYPERLINK\l_Toc197593硬件设计PAGEREF_Toc197593HYPERLINK\l_Toc255393.1树莓派接口驱动LED电路设计934软件设计PAGEREF_Toc248624HYPERLINK\l_Toc47954。1驱动三色LED灯PAGEREF_Toc47954HYPERLINK\l_Toc312464.1.1驱动实现方法PAGEREF_Toc3124644。1.2wiringPi库安装和软件编程PAGEREF_Toc922044.2服务器和客户端PAGEREF_Toc1868754.2。1服务器设计方法PAGEREF_Toc269845HYPERLINK\l_Toc128844.2.2客户端设计方法PAGEREF_Toc128845HYPERLINK\l_Toc42335系统调试PAGEREF_Toc42336HYPERLINK\l_Toc25772设计心得PAGEREF_Toc257726HYPERLINK\l_Toc3827参考文献PAGEREF_Toc38277HYPERLINK\l_Toc829附录1(LED驱动程序)8298HYPERLINK\l_Toc22383附录2(服务器程序)PAGEREF_Toc2238310附录3(客户端程序代码)PAGEREF_Toc26713161系统概述与设计要求1.1系统概述本系统设计是基于树莓派开发板上实现的,树莓派由注册于英国的慈善组织“RaspberryPi基金会"开发,Eben·Upton/埃·厄普顿为项目带头人。2012年3月,英国剑桥大学埃本·阿普顿(EbenEpton)正式发售世界上最小的台式机,又称卡片式电脑,外形只有信用卡大小,却具有电脑的所有基本功能,这就是RaspberryPi电脑板,中文译名"树莓派".它是一款基于ARM的微型电脑主板,以SD/MicroSD卡为内存硬盘,卡片主板周围有1/2/4个USB接口和一个10/100以太网接口(A型没有网口),可连接键盘、鼠标和网线,同时拥有视频模拟信号的电视输出接口和HDMI高清视频输出接口,以上部件全部整合在一张仅比信用卡稍大的主板上,具备所有PC的基本功能。而树莓派2具有900MHz内核频率,4核ARMCortex—A7,1GB内存,带MicroSD卡插槽(支持通过它启动Linux操作系统,如Fedora),40PIN接口(可以增加驱动外设)。本系统设计正式在树莓派2环境下开发实现多线程设计,设计的主要功能就是两个客户端通过服务器互相收发信息。1.2设计要求要求多个客户端能够同时连接服务器,而服务器需要创建线程来管理这多个客户端,并且能够把一个客户端发来的数据进行解析,发给另一个客户端,实现两个甚至多个客户端互相收发信息。能够通过驱动三色灯来发现系统运行的状态,红色说明有错误发生,绿色说明正在正常运行,蓝色说明有用户连接,绿色说明有客户端互相收发信息。2方案论证2.1实现方法要实现服务器同时管理两个甚至多个客户端,就必须引入进程或线程。2.2线程优势一是和进程相比,它是一种非常”节俭"的多任务操作方式。进程是系统中程序执行和资源分配的基本单位。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这就导致了进程在进行切换等操作起到了现场保护作用,这是一种"昂贵"的多任务工作方式。但是为了进一步减少处理机的空转时间支持多处理器和减少上下文切换开销,进程演化中出现了另外一个概念,这就是线程,也被人称为轻量级的进程。它是一个进程内的基本调度单位。线程是在共享的内存空间中并发的多道执行路径,它们共享一个进程的资源,比如文件描述符和信号处理等。因此,大大减少了上下文切换的开销。二是线程间方便的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方.3硬件设计3.1树莓派接口驱动LED电路设计图3.1从图3.1可以知道,要想让三色灯的红色亮起来,首先控制树莓派GPIO.27引脚输出低电平,同理可以控制GPIO.28、GPIO29引脚电瓶来控制绿、蓝LED的启动和关闭。树莓派开发板上的相关引脚如图3.2。图3.24软件设计4.1驱动三色LED灯4.1.1驱动实现方法控制引脚电瓶的高低就能实现控制LED灯的变化,实际上三色LED可以显示无数种颜色,要想超过三种颜色的显示实现,就必须引入PWM.PWM是模拟脉宽调制来控制输出引脚的实际输出电瓶大小,此系统可以控制引脚从0~3.3V变化来显示不同的颜色.wiringPi适合那些具有C语言基础,在接触树莓派之前已经接触过单片机或者嵌入式开发的人群。wiringPi的API函数和arduino非常相似,这也使得它广受欢迎。作者给出了大量的说明和示例代码,这些示例代码也包括UART设备,I2C设备和SPI设备等。4.1。2wiringPi库安装和软件编程首先需要在树莓派上安装wiringPi库,我们选择直接在网上下载安装源码,输入命令:cd~进入根目录下,输入命令:gitclonegit://git.drog/wiringPi从网上下载源码包,输入命令cdwiringPi进入安装包目录下,依次输入命令:configuremakemakeinstall来配置、编译和安装,最后输入命令sudo./build来执行编译之后生成的可执行文件,完成安装。最后输入命令:gpioreadall会出来引脚图来确定已经安装成功。接下来就需要运用库的软件编程来驱动led灯啦,在写C文件时首先要加入库的头文件:#include<wiringPi。h>和C语言必要的头文件:#include〈stdio.h>,然后还需要加入实现软件PWM的头文件:#include<softPwm。h〉。接下来我们就需要运用库的API函数wiringPiSetup()初始化wiringPi,若初始化失败会返回—1;然后运用库的API函数softPwmCreate()创建软件PWM,此函数有3个输入参数,分别是控制引脚号,PWM最小值,PWM最大值;运用库的API函数softPwmWrite()写PWM的值,此函数有2个输入参数,分别是控制那个引脚号,写入的PWM的值,此值需要在最小最大值之间。完整代码如附录1。4.2服务器和客户端4.2.1服务器设计方法为了方便起见,我们把服务器和客户端都定义在本地IP上进行测试,服务器端的话,首先我们需要把主函数传入的端口号记录下来,并且利用C语言标准函数atoi转换成整型值.接着我们定义两个整型数组来存放两个客户端的套接字,然后我们根据端口去创建服务器,创建服务器需要几个函数来实现,第一个就是socket()函数来创建一个服务器的套接字,此函数有3个输入参数,我们选择ipv4协议族,流式Socket,TCP协议类型。然后根据端口号和本地IP配置服务器,之后就是调用绑定bind(),监听listen()函数来完成服务器的创建.之后就是根据创建的套接字来进行循环,如果有客户端连接,就保存客户端套接字创建一个线程去处理,此处我们以两个客户端为例来进行操作。若是套接字编号0发来消息,我们就转发给套接字编号1,若是超过2个的客户端连接进来我们直接关闭创建的线程就行,之后要是有客户端掉线,就把线程和客户端一块销毁。具体代码实现见附录24。2。2客户端设计方法首先我们封装三个函数,分别是连接、读数据、写数据,开始就调用连接函数,在连接函数里我们创建客户端并通过输入的服务器ip和端口去连接服务器,然后我们创建两个线程分别是读和写,在读函数里我们不间断读键盘数据并发送给服务器,在写函数里不间断的读服务器发来的数据并显示在屏幕上.具体代码实现见附录3。5系统调试此系统的调试,我们选择Linux虚拟机模拟调试,首先运行服务器和两个客户端,然后客户端连接服务器,之后两个客户端互相收发数据.为了方便起见,我在PC机上运行和仿真,首先安装虚拟机VMware8。0,然后安装VMwareTools,虚拟机的工具是为了共享电脑上的文件,这样可以在电脑上编写代码,在虚拟机上编译运行。编译服务器的代码,输入命令gccserver.c—oserver.exe-lpthread,回车之后会生成server.exe可执行文件,之后我们运行服务器,输入命令./server.exe6789,运行服务器,其中6789为输入的端口号。之后编译客户端代码,输入命令gccclient。c-oclient。exe—lpthread,回车之后会生成client.exe可执行文件,我们事先查看虚拟机ip,输入命令ifconfig回车就能看到虚拟机本机ip,为我们客户端连接服务器所用。之后我们运行客户端一,输入命令。/client.exe192.168。20。1096789,回车,然后用同样的命令运行客户端二,之后我们在一个客户端输入信息回车,在另一个客户端就能接收到,具体运行结果如图5.1,5。2,5.3。图5。1图5.2图5.3设计心得此次开发性试验设计让我收获甚多.一是要有一个积极的心态,独立解决问题的意识,培养扎实基础的认识。不要什么东西都感觉跟简单(很多东西可能是看似简单)就不去做了或者不屑一做,以至于性网上搜搜就可以了,这样很不好。有自己的东西有自己的付出才会有程序运行成功时的喜悦和小自豪,这样也有助于培养自己的兴趣.要时刻牢记态度决定一切。其次是兴趣,感觉学习工作中兴趣很关键,只是一个引发人积极性的问题,有了兴趣就自觉了,效率自然就高了。再次要敢于尝试和挑战。不要安于现成的程序,而且不要害怕失败,在程序调试的过程中这点尤为重要,“发现出问题然后解决问题”是一个积累经验的过程,而且很高效。最后要不懈追求。对于源代码进行不断的完善,要尽可能的实现课题所要求的功能.对于初学者或者开发较少的人来说,大量大写程序还是有必要的,但同时要注意思考,理解其实现的内在意义。还可以自己添加一些有意义的功能来实现。当看到自己编写的程序正常运行时,兴趣也会随之而来,乐此不疲,形成一个良性循环.

短短一周的开放性ARM多线程设计很快结束了,我发现我对嵌入式这个方向、对嵌入式技术、对Linux都有了新的认识。通过这次的编程,我了解到,要真真正正的掌握计算机程序还不是一件简单容易的事儿,但真正掌握后,它带给我们的将是无穷的便捷与科技,我喜欢高端便捷的生活。我希望我能做计算机这个万能机器人的主人而不是奴隶,我会努力加油的!参考文献[1]徐千洋.Linux

C函数库参考手册.[M]中国青年出版社.2002

[2]马忠梅,马广云,徐英慧,田译.ARM嵌入式处理结构与应用基础[M].北京航空航天大学出版社。2002

[3]邹思铁。嵌入式Linux设计与应用[M].北京清华大学出版社。2002

[4]杜春雷。ARM体系结构与编程[M].清华大学出版社。2003

[5]田泽。嵌入式系统开发与应用[M]。北京航空航天大学出版社。2005

[11]陈鑫。嵌入式软件技术的现状与发展动向[M].软件世界。2001

[6]田泽。嵌入式系统开发与应用实验教程[M].北京航空航天大学出版社.2004

[7]Alessandro

Rubini,Jonathan

Corbet.Linux设备驱动程序[M].中国电力出版社.2002附录1(LED驱动程序)#include<wiringPi.h>#include〈softPwm.h>#include〈stdio.h>#defineucharunsignedchar#defineLedPinRed27#defineLedPinGreen28#defineLedPinBlue29voidledInit(void){softPwmCreate(LedPinRed,0,100);softPwmCreate(LedPinGreen,0,100);softPwmCreate(LedPinBlue,0,100);}voidledColorSet(ucharr_val,ucharg_val,ucharb_val){softPwmWrite(LedPinRed,r_val);softPwmWrite(LedPinGreen,g_val);softPwmWrite(LedPinBlue,b_val);}intmain(void){inti;if(wiringPiSetup()==—1){printf("setupwiringPifailed!");return1;}ledInit();while(1){ledColorSet(0xff,0x00,0x00);//reddelay(500);ledColorSet(0x00,0xff,0x00);//greendelay(500);ledColorSet(0x00,0x00,0xff);//bluedelay(500);}return0;}附录2(服务器程序)#include<stdio.h>#include<stdlib.h〉#include<string.h>#include<signal.h>#include〈unistd.h>#include<error。h>#include<errno。h>#include〈fcntl.h〉#include<sys/types。h>#include<sys/socket。h>#include<sys/epoll.h>#include<netinet/in.h〉#include〈arpa/inet。h>#include<pthread。h>#defineBUFSIZE1024intsocket_client[2];intsocket_create(intport){intst=socket(AF_INET,SOCK_STREAM,0);inton=1;if(setsockopt(st,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))==—1){printf("setsockoptisfailed%s\n",strerror(errno));return0;}structsockaddr_inaddr;memset(&addr,0,sizeof(addr));addr.sin_family=AF_INET;addr。sin_port=htons(port);addr。sin_addr。s_addr=htonl(INADDR_ANY);if(bind(st,(structsockaddr*)&addr,sizeof(addr))==-1){printf("zhang.pt:bindisfailed%s\n",strerror(errno));return0;}if(listen(st,300)==-1){printf(”zhang。pt:listenisfailed%s\n",strerror(errno));return0;}returnst;}voiddeliver(intindex,constchar*buf,ssize_tlen){ssize_trc=0;if(index==0){if(socket_client[1]==0){printf("%d:usernotonline\n",index);}else{rc=send(socket_client[1],buf,len,0);printf(”send:%s,send:%ubytes\n",buf,rc);if(rc<=0){if(rc==0)printf("zhang.pt:sendfailed,disconnection,\n");elseprintf("zhang.pt:sendfailed,%s\n",strerror(errno));}}}if(index==1){if(socket_client[0]==0){printf("%d:usernotonline\n”,index);}else{rc=send(socket_client[0],buf,len,0);printf("send:%s,send:%ubytes\n",buf,rc);if(rc〈=0){if(rc==0)printf("zhang.pt:sendfailed,disconnection,\n”);elseprintf(”zhang.pt:sendfailed,%s\n",strerror(errno));}}}}voidsocket_work(intindex){charbuf[BUFSIZE];ssize_trc=0;while(1){memset(buf,0,sizeof(buf));rc=recv(socket_client[index],buf,sizeof(buf),0);if(rc<=0){if(rc==0)printf(”%d:recvdisconnection\n",index);elseprintf(”%d:recvfailed,%s\n”,index,strerror(errno));close(socket_client[index]);socket_client[index]=0;break;}else{printf(”%d:recv:%s,recv:%ubytes\n",index,buf,rc);deliver(index,buf,rc);}}}void*socket_handle(void*arg){intclient_st=*(int*)arg;free((int*)arg);printf("zhang.pt:handle_threadisbegin\n");intindex=0;if(socket_client[0]==0){socket_client[0]=client_st;}else{if(socket_client[1]==0){socket_client[1]=client_st;index=1;}else{close(client_st);returnNULL;}}socket_work(index);printf("zhang。pt:handle_threadisend\n");returnNULL;}voidsockaddr_toa(conststructsockaddr_in*addr,char*IPAddr){unsignedchar*p=(unsignedchar*)&(addr—>sin_addr.s_addr);sprintf(IPAddr,"%u。%u。%u.%u",p[0],p[1],p[2],p[3]);}voidsocket_accept(intst){pthread_tthr_d;pthread_attr_tattr;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);structsockaddr_inclient_addr;socklen_tlen=sizeof(client_addr);while(1){memset(&client_addr,0,sizeof(client_addr));intclient_st=accept(st,(void*)&client_addr,&len);if(client_st==-1){printf("zhang.pt:acceptfailed%s\n",strerror(errno));break;}else{charsIP[32];memset(sIP,0,sizeof(sIP));sockaddr_toa(&client_addr,sIP);printf(”zhang.pt:acceptby%s\n",sIP);int*tmp=malloc(sizeof(int));*tmp=client_st;pthread_create(&thr_d,&attr,socket_handle,tmp);}}pthread_attr_destroy(&attr);}intmain(intarg,char*args[]){if(arg〈2){printf("zhang.pt:serverporterror!\n”);return0;}intiport=atoi(args[1]);if(iport==0){printf(”zhang。pt:port%disinvalid!\n”,iport);return0;}printf("zhang。pt:serverisbegin*v*!\n");memset(socket_client,0,sizeof(socket_client));intst=socket_create(iport);if(st==0)return0;socket_accept(st);close(st);printf("zhang.pt:serverisend\n");return0;}附录3(客户端程序代码)#include<stdio。h>#include<stdlib。h〉#include〈string。h〉#include<errno.h>#include〈unistd。h〉#include〈arpa/inet.h〉#include<sys/types.h>#include〈sys/socket.h>#include〈pthread.h>#defineBUFSIZE1024void*socket_read(void*arg){intst=*(int*)arg;charbuf[BUFSIZE];while(1){memset(buf,0,sizeof(buf));ssize_trc=recv(st,buf,sizeof(buf),0);if(rc〈=0){printf("zhang。pt:recvfailed,%s\n”,strerror(errno));break;}else{printf(”zhang.pt:recv:%s,recv:%ubyte\n”,buf,rc);}}returnNULL;}void*socket_write(void*arg){intst=*(int*)arg;charbuf[BUFSIZE];while(1){memset(buf,0,sizeof(buf));read(STDIN_FILENO,buf,sizeof(buf));intilen=strlen(buf);if(buf[ilen-1]=='\n'){buf[ilen-1]=0;}ssize_trc=send(st,buf,sizeof(buf),0);printf(”zhang.pt:send:%s,send:%ubyte\n”,buf,rc);if(rc〈=0){printf("zhang.pt:sendfailed,%s\n",strerror(errno));}}returnNULL;}intsocket_connect(constchar*hostname,intiport){intst=socket(AF_INET,SOCK_STREAM,0);structsockaddr_inaddr;memset(&addr,0,sizeof(addr));addr.sin_family=AF_INET;addr。sin_port=htons(iport);addr。sin_addr.s_addr=inet_addr(hostname);if(connect(st,(structsockaddr*)&addr,sizeof(addr))==-1){printf(”zhang。pt:connectfailed%s\n",strerror(errno));}else{printf("zhang。pt:connectsuccess\n”);}returnst;}intmain(intarg,char*args[]){if(arg〈3){printf("zhang.pt:serverip&porterror!\n”);return0;}intiport=atoi(args[2]);if(iport==0){printf("zhang。pt:port%disinvalid\n”,iport);return0;}printf("zhang。pt:clientisbegin\n");intst=socket_connect(args[1],iport);if(st==0)return0;pthread_tthr_read,thr_write;pthread_create(&thr_read,NULL,socket_read,&st);pthread_create(&thr_write,NULL,socket_write,&st);pthread_join(thr_read,NULL);close(st);printf(”zhang.pt:clientisend\n");return0;}基于AT89s52的多功能数字钟引言单片机(Single—ChipMicrocomputer),是集CPU,RAM,ROM,定时,计数和多种接口于一体的微控制器。它体积小,成本低,功能强,广泛应用于工业自动化上和智能产品。时钟,自从它被发明的那天起,就成为了人类的好朋友,但随着时间的推移,科学技术的不断发展,时钟的应用越来越广范,人们对时间计量的精度要求也越来越高。怎样让时钟更好的为人民服务,怎样让我们的老朋友再次焕发青春呢?这就要求我们不断设计出新型的时钟,来不断满足人们的日常生活需要。然而市场上的时钟便宜的比较笨重,简单实用的又比较昂贵。那么,有没有一款既简单实用价格又便宜的时钟呢?我们设计小组设想:可不可以利用单片机功能集成化高,价格又便宜的特点设计一款结构既简单,价格又便宜,功能又强大的单片机电子时钟呢?基于这种情况,我们课程设计小组成员多方查阅资料,反复论证设计出了这款集时钟显示、闹铃提醒和秒表功能于一体的单片机数字时钟。【摘要】本设计由数码管显示模块、单片机处理模块、闹铃提醒模块、按键控制模块和电源模块等组成。通过单片机软件运算方式进行时钟计时,外部获得的按键信息进行模式切换和控制,输出到信号数码管显示模块,从而控制数码管显示内容,实现时钟显示、闹铃提醒和秒表等功能。【关键词】数字钟;AT89s52;PNP9012;数码管【Abstract】Thedesignconsistsofthedigitaldisplaymodule,MCUprocessingmodule,alarmremindingmodule,keycontrolmoduleandpowermoduleandothercomponents.ThroughthewayMCU’ssoftwareoperationtotime,externalinformationonaccesstokeydataprocessingtomodechangingandcontrol,outputsignaltodigitaldisplaymoduletocontrolthedigitaldisplaycontent,andthen,realizingtheclockdisplayandalarmremindingandstopwatch,andotherfunctions.【Keywords】Dgitalclock;AT89s52;PNP9012;nixietube目录TOC\o”1—3”\h\z\uHYPERLINK\l_Toc30296目录PAGEREF_Toc302963一、课程选题及设计目的PAGEREF_Toc1706341。1课程选题及相关设计要求PAGEREF_Toc102804HYPERLINK\l_Toc312461.1.1课程题目PAGEREF_Toc312464HYPERLINK\l_Toc61571.1.2设计要求PAGEREF_Toc61574HYPERLINK\l_Toc292261.1.3本设计功能完成情况PAGEREF_Toc2922641.2课程设计目的PAGEREF_Toc148395HYPERLINK\l_Toc186481。3课程设计所用软件PAGEREF_Toc186485HYPERLINK\l_Toc28490二、硬件设计与实现PAGEREF_Toc2849062.1课题分析PAGEREF_Toc125156HYPERLINK\l_Toc7002.1.1元件选择PAGEREF_Toc7006HYPERLINK\l_Toc268692.1。2工作原理PAGEREF_Toc268697HYPERLINK\l_Toc10072。1.3系统的硬件构成及功能PAGEREF_Toc100782.2由原理设计实际电路PAGEREF_Toc2643210HYPERLINK\l_Toc23022.2.1抢答器实际电路图PAGEREF_Toc230210HYPERLINK\l_Toc182722.2。2PCB图设计PAGEREF_Toc1827211HYPERLINK\l_Toc198023。1软件功能需求PAGEREF_Toc1980212HYPERLINK\l_Toc133683.2系统主程序设计PAGEREF_Toc13368124.1仿真电路设计PAGEREF_Toc836319HYPERLINK\l_Toc55994。2功能仿真结果PAGEREF_Toc559919HYPERLINK\l_Toc280434.2.1时间显示PAGEREF_Toc2804319HYPERLINK\l_Toc194204.2。2闹铃设定PAGEREF_Toc19420204。2。3时间设定PAGEREF_Toc802820HYPERLINK\l_Toc159264.2.4秒表使用PAGEREF_Toc1592620附录课程选题及设计目的1课程选题及相关设计要求1。1.1课程题目基于AT89s52的多功能数字钟1.1.2设计要求1.显示时间:用数码管显示时:分,时间可用硬件调整。2.定时功能,可硬件调整(时分)定时,定时到驱动蜂鸣器(或LED)提示.3。计时功能:精确到0.1秒,结果在数码管显示.4。设计出相应电路并用protel出图。5.给出完整的汇编语言(或C语言)源程序。1.1。3本设计功能完成情况1.显示时间:完整实现并自由发挥。用数码管显示,按照时—分-秒的格式显示,时间可用硬件调整,比照设计要求增加了秒显示功能。2。定时功能,完整实现。可硬件调整(时分)定时,定时到驱动蜂鸣器(或LED)提示,本设计采用了LED提示(亮1min)。3.计时功能:完整实现并自由发挥。精确到0.01秒,结果在数码管显示,比照设计要求秒表精度提高了10倍。4。设计出相应电路并用protel出图,完整实现.。5.给出完整的汇编语言(或C语言)源程序,完整实现。6.仿真,此步骤为自行添加,用于验证了设计的可行性。1。2课程设计目的(1)学习使用protel设计电子线路原理图和PCB图的方法。(2)学习使用protues仿真并调试电路及程序的方法。(3)学习使用以AT89s52为核心设计外围电路及实现预期功能的思想和方法.(4)学习查找电路所用元件封装方式的查找和自行制作的方法.(5)学习使用KeilC设计相应程序实现硬件控制和功能的方法。1.3课程设计所用软件软件工具:AltiumDesignerSummer09、Protel99用于设计电路原理图和PCB图。KeiluVision4用于软件的编写、编译以及hex文件的生成.Protues7。5用于软件的仿真。硬件设计与实现2。1课题分析2.1。1元件选择本设计使用到的元器件包括:AT89s52芯片、数码管、PNP9012、电容、电阻、晶振、按键开关、。AT89s52芯片是系统的核心,它主要负责控制各个部分的协调工作。选择该芯片的原因主要有以下几点:(1)该芯片在以前的电子设计中使用过一次,手头恰好有,便于节省课程设计资金。(2)内部资源丰富,功能强大,片上Flash允许程序存储器在系统可编程,亦适于常规编程器.(3)能工作在3.5~5。5V,其工作电压范围宽泛,便于使用.在AT89s52芯片外围接上复位电路,外部时序电路、上拉电阻,数码管,按钮等外部设备,通过数码管、PNP9012搭配实现功能的显示。P3。3为蜂鸣器(用LED代替)输出口,P0为数码管段选显示输出,P2为数码管位选显示输出,P3.0—P3。2为按键控制接口.原件列表:AT89s521片四位共阳极数码管2片PNP9012三极管8个22μF电容1个30pF电容2个1KΏ电阻12个4.7KΏ电阻8个12M晶振1个导线、焊锡若干2.1。2工作原理基于上述设计要求,根据功能要求,设计中除了必要的单片机复位和时序电路外,还需要有闹铃提醒电路、显示电路、按键控制电路等部分。各个电路都有其自己的功能。电路进入就绪状态后,开始计时.然后由按键控制进行模式切换和控制状态。在电路中P3。0-P3。2为按键控制部分的3个按键,P3.0对应模式切换功能,P3。1在时钟显示和闹铃模式下起到加1功能,P3。2在时钟显示和闹铃模式下起到减1功能,在秒表模式下起到控制秒表开始和暂停的功能。P3.3为闹铃输出口,闹铃时间到,则该输出口置高,保持1min,使LED保持高亮达到闹铃提醒功能。P0为数码管段选显示输出,同个8个口电平高低不同,控制单个数码管的显示,;P2为数码管位选显示输出,通过8个口的输出电平高低不同,控制相连的PNP9012的导通状态,从而控制共阳数码管的显示.AT89s52的针脚定义如下:2.1.3系统的硬件构成及功能(1)抢答器的电路框图P3.0-3.2P0口P3.0-3.2P0口单片机P2口数码管显示模块外围驱动电路电源模块按键控制模块闹铃提醒模块复位电路及时序电路抢答器电路功能框图2.2由原理设计实际电路2.2。1抢答器实际电路图抢答器工作电路原理图2.2.2PCB图设计(注明:因为沟通的原因,实际作出的PCB图未按照此图制作,而是制作了第一版设计的一个PCB,其中有错误,故在实际应用时,自行焊接了设计电路.)三、电子线路软件设计与实现3.1软件功能需求为了能够计时准确,显示无闪烁,按键响应及时无抖动等功能需求,根据设计要求,可以得出相应的软件功能可分为以下部分:(1)初始化部分(2)显示部分(3)键盘扫描判断部分(4)数码管驱动部分(5)主程序(6)定时器计时设计3.2系统主程序设计基于以上软件需求,以及ATMega16L指令集特点,编写了如附录程序来实现逾期功能。初始化部分.#include<reg52。h>sbitKEY1=P3^0;sbitKEY2=P3^1;sbitKEY3=P3^2;sbitled=P3^3;codeunsignedchartab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阴数码管0-9unsignedcharStrTab[8];//定义缓冲区Unsignedcharminute=30,hour=12,second,msecond,miao,key1flag=0,key2flag=0;//定义并且初始化值12:30:00unsignedcharkeytemp1=0,keytemp2=0,clockhor=0,clockmin=0,clocksec=0,clockflag,keycount,keyflag1,t;显示部分。voidDisplaypro(void){StrTab[0]=tab[hour/10];//显示正常时间StrTab[1]=tab[hour%10];StrTab[2]=0xbf;StrTab[3]=tab[minute/10];StrTab[4]=tab[minute%10];StrTab[5]=0xbf;StrTab[6]=tab[second/10];StrTab[7]=tab[second%10];}voiddisplaymiao(){StrTab[6]=tab[msecond/10];//显示秒表时间StrTab[7]=tab[msecond%10];StrTab[2]=0xbf;StrTab[3]=tab[miao/10];StrTab[4]=tab[miao%10];StrTab[5]=0xbf;StrTab[0]=tab[0];StrTab[1]=tab[0];}voidtiming(void){StrTab[0]=tab[hour/10];//显示正常时间StrTab[1]=tab[hour%10];StrTab[2]=0xff;StrTab[3]=tab[minute/10];StrTab[4]=tab[minute%10];StrTab[5]=0xff;StrTab[6]=tab[second/10];StrTab[7]=tab[second%10];}voidclock(void){StrTab[0]=tab[clockhor/10];//显示闹铃时间StrTab[1]=tab[clockhor%10];StrTab[2]=0x7f;StrTab[3]=tab[clockmin/10];StrTab[4]=tab[clockmin%10];StrTab[5]=0x7f;StrTab[6]=tab[clocksec/10];StrTab[7]=tab[clocksec%10];}voidzero(void){StrTab[0]=tab[0];//显示零时间StrTab[1]=tab[0];StrTab[2]=0xbf;StrTab[3]=tab[0];StrTab[4]=tab[0];StrTab[5]=0xbf;StrTab[6]=tab[0];StrTab[7]=tab[0];}键盘扫描判断部分.voidkeyjudge()//模式切换键扫描{keyflag1=0;delay(1000);if(keyflag1=1){if(key1flag〈=4){key1flag++;}if(key1flag>=4){key1flag=0;}}keyflag1=0;}数码管驱动部分。voidtime1_isr(void)interrupt3using0//定时器1用来动态扫描{staticunsignedcharnum;TH1=0xf8;//重入初值TL1=0xf0;switch(num){case0:P2=0xfe;P0=StrTab[num];break;//分别调用缓冲区的值进行扫描case1:P2=0xfd;P0=StrTab[num];break;case2:P2=0xfb;P0=StrTab[num];break;case3:P2=0xf7;P0=StrTab[num];break;case4:P2=0xef;P0=StrTab[num];break;case5:P2=0xdf;P0=StrTab[num];break;case6:P2=0xbf;P0=StrTab[num];break;case7:P2=0x7f;P0=StrTab[num];break;default:break;}num++;//扫描8次,使用8个数码管if(num==8)num=0;}延时程序。voiddelay(unsignedintcnt)//延时函数{while(--cnt);}主程序。main()//主函数{TMOD|=0x01;//定时器0用于计时TH0=0xd8;TL0=0xf0;ET0=1;TR0=1;TMOD|=0x10;//定时器1用于动态扫描TH1=0xF8;TL1=0xf0;ET1=1;TR1=1;EA=1;EX0=1;IT0=1;t=0;Displaypro();while(1)//主循环{while((key1flag==0)){Displaypro();}while((key1flag==1)){zero();if(!KEY3)//按键去抖以及动作{delay(10000);if(!KEY3){msecond=0;miao=0;}while((key1flag==1)){displaymiao();}}}while((key1flag==2)){timing();if(key2flag==0){if(!KEY3)//按键去抖以及动作{delay(10000);if(!KEY3){minute++;if(minute==59)minute=0;//分加1timing();}}}if(key2flag==1){if(!KEY3)//按键去抖以及动作{delay(10000);if(!KEY3){hour++;if(hour==24)hour=0;//分减1timing();}}}timing();}while((key1flag==3)){clock();if(key2flag==0){if(!KEY3)//按键去抖以及动作{delay(10000);if(!KEY3){clockmin++;if(clockmin==59)clockmin=0;//分加1clock();}}}if(key2flag==1){if(!KEY3)//按键去抖以及动作{delay(10000);if(!KEY3){clockhor++;if(clockhor==24)clockhor=0;//分减1clock();}}}clock();}}}////////////////////////////////////////////////////////////////voidinter()interrupt0{if(key1flag==1){if(t==0){t=1;}elset=0;}}闹铃响应设计if((hour==clockhor)&&(minute==clockmin)){clockflag=1;}else{clockflag=0;}if(clockflag==1){led=1;}else{led=0;}秒表设计voidtim(void)interrupt1using1{staticunsignedintcount;//定义内部静态变量TH0=0xf8;//重新赋值TL0=0x30;count++;keycount++;if(!KEY1){keyflag1=1;keyjudge();}if(!KEY2){if(key2flag〈=2){key2flag++;}if(key2flag>=2){key2flag=0;}}if((count%5)==0){if(t==1)msecond++;if(msecond==100){msecond=0;miao++;//秒加1if(miao==100)miao=0;}}(9)走时设计if(count==500){count=0;second++;//秒加1if(second==60){second=0;minute++;//分加1if(minute==60){minute=0;hour++;//时加1if(hour==24)hour=0;}}}}四、系统功能仿真4.1仿真电路设计因为使用Protues7.5进行电路仿真时,默认单片机正常工作同时电路驱动能力无限大,因此可以省略掉复位和时序电路以及三极管驱动部分,仿真电路图设计如下:4。2功能仿真结果4。2.1时间显示4。2.2闹铃设定4。2.3时间设定4。2.4秒表使用附录:完整程序设计#include〈reg52.h〉sbitKEY1=P3^0;sbitKEY2=P3^1;sbitKEY3=P3^2;sbitled=P3^3;codeunsignedchartab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阴数码管0-9unsignedcharStrTab[8];//定义缓冲区unsignedcharminute=30,hour=12,second,msecond,miao,key1flag=0,key2flag=0;//定义并且初始化值12:30:00unsignedcharkeytemp1=0,keytemp2=0,clockhor=0,clockmin=0,clocksec=0,clockflag,keycount,keyflag1,t;voiddelay(unsignedintcnt)//延时函数{while(-—cnt);}voidDisplaypro(void){StrTab[0]=tab[hour/10];//显示正常时间StrTab[1]=tab[hour%10];StrTab[2]=0xbf;StrTab[3]=tab[minute/10];StrTab[4]=tab[minute%10];StrTab[5]=0xbf;StrTab[6]=tab[second/10];StrTab[7]=tab[second%10];}voiddisplaymiao(){StrTab[6]=tab[msecond/10];//显示秒表时间StrTab[7]=tab[msecond%10];StrTab[2]=0xbf;StrTab[3]=tab[miao/10];StrTab[4]=tab[miao%10];StrTab[5]=0xbf;StrTab[0]=tab[0];StrTab[1]=tab[0];}voidtiming(void){StrTab[0]=tab[hour/10];//显示正常时间StrTab[1]=tab[hour%10];StrTab[2]=0xff;StrTab[3]=tab[minute/10];StrTab[4]=tab[minute%10];StrTab[5]=0xff;StrTab[6]=tab[second/10];StrTab[7]=tab[second%10];}voidclock(void){StrTab[0]=tab[clockhor/10];//显示闹铃时间StrTab[1]=tab[clockhor%10];StrTab[2]=0x7f;StrTab[3]=tab[clockmin/10];StrTab[4]=tab[clockmin%10];StrTab[5]=0x7f;StrTab[6]=tab[clocksec/10];StrTab[7]=tab[clocksec%10];}voidzero(void){StrTab[0]=tab[0];//显示零时间StrTab[1]=tab[0];StrTab[2]=0xbf;StrTab[3]=tab[0];StrTab[4]=tab[0];StrTab[5]=0xbf;StrTab[6]=tab[0];StrTab[7]=tab[0];}voidkeyjudge(){keyflag1=0;delay(1000);if(keyflag1=1){if(key1flag<=4){key1flag++;}if(key1flag〉=4){key1flag=0;}}keyflag1=0;}main()//主函数{TMOD|=0x01;//定时器0用于计时TH0=0xd8;TL0=0xf0;ET0=1;TR0=1;TMOD|=0x10;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论