51单片机毕业设计题目_51单片机经典项目

51单片机毕业设计题目_51单片机经典项目STC12C5A60S2DS12887单片机毕业设计51单片机项目数码管显示的合成出租车计价器设计Synthetictaximeterdigitaldisplaydesign学生姓名: 学生学号: 10700121专业名称: 电子信息工程指导教师:计算机与信息工程学院2014年6月13日独创性声明本人声明所呈交的毕业设计(论文)是本人在指导教师指导下进行的研究工作和取得的研究成果,除了文中特别加以引用标注之处外,论文中不包含其他人已经发表或撰写过的研究成果,没有伪造数据的

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

STC12C5A60S2

DS12887

单片机毕业设计

51单片机项目

数码管显示的合成出租车计价器设计

Synthetic taxi meter digital display design

学生姓名:
学生学号: 10700121
专业名称: 电子信息工程
指导教师:

计算机与信息工程学院
2014年6月13日

独创性声明

本人声明所呈交的毕业设计(论文)是本人在指导教师指导下进行的研究工作和取得的研究成果,除了文中特别加以引用标注之处外,论文中不包含其他人已经发表或撰写过的研究成果,没有伪造数据的行为。

毕业设计(论文)作者签名: 签字日期:2014年6月13日

毕业设计(论文)版权使用授权书

本毕业设计(论文)作者完全了解学校有关保留、使用论文的规定。同意学校保留并向有关管理部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。本人授权天津城建大学可以将本论文的全部或部分内容编入有关数据进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本论文。
(保密的毕业设计(论文)在解密后适用本授权说明)

毕业设计(论文)作者签名: 指导教师签名:

签字日期:2014年6月13日 签字日期: 2014年6月13日

摘 要
本次设计为的我的毕业设计,我主要为大家介绍一种快速而省钱的乘车方式。在本次设计中,我将会详细的讲解这种介于公交车与现在出租车之间的乘车方式的设计背景、设计思路、实现原理、设计的原理图及其程序的要点部分。本次设计主要以单片机为控制芯,控制四片MAX7219,使32个数码管显示不同的数据来得到自己想要的数据,这就是本次设计的主体思路。
关键词:合乘出租车、单片机、MAX7219、数码管
Abstract
The design is my graduation project,I mainly introduce a fast and economical way to travel.In this design,I will explain this design that between the bus ride and now the taxi way in detail and explain the design background, design ideas, realization of the principle point of the design schematics and procedures. The design of the main control core is SCM, which control four MAX7219, making 32 digital display different data to get the data that we want. This is the main idea of this design .
Keywords: Car、SCM、MAX7219、Digital
目 录
第一章 绪论 1
第二章 方案设计 2
2.1 设计原理 2
2.2 设计实现的功能 2
2.3 方案选择 2
2.3.1 单片机的选择 3
2.3.2 外围电路的方案设计 3
2.4 总设计流程图及其说明 4
2.4.1 总设计流程图 4
2.4.2 总设计流程图分析 5
第三章 硬件电路设计 6
3.1 控制主电路设计 6
3.2 按键扫描电路 7
3.3 时钟电路 7
3.4 数据显示模块 8
3.4.1 电路原理图 8
3.4.2 工作原理 9
3.5 原理图设计软件 9
第四章 程序的编写 10
4.1 编译环境 11
4.2 烧写软件 11
4.3 程序的编写 11
4.3.1 头文件 11
4.3.2 扩展I/O口P4的寄存器设置 12
4.3.3 MAX7219.H文件 12
4.3.4 DS12887.H文件 13
4.4 主程序 16
4.4.1 主程序流程图 16
4.4.2 主程序分析 16
4.4.3 主程序代码分析 17
4.5 程序运行结果 18
第五章 设计实物的测试和调试 18
5.1 测试目的 19
5.2 测试项目 19
5.2.1 功能测试 19
5.2.2 稳定性测试 19
5.3 测试并调试结果 20
5.4 测试与调试后的总结 21
第六章 总 结 22
6.1 设计开发流程总结 23
6.2 自我认识 23
致 谢 24
参考文献 25
附 录 26

第一章 绪论
自2013年北京市出台规定后,同时也兴起了以合乘为运营业务的优秀企业。自2013年北京出台政策后合乘的形式以及种类也是多种多这样,五花八门的拼车工具也是层出不穷,主要是以无锡打的宝科技有限公司为代表的自主合乘微信平台等合乘成功率很高的工具。
随着中国城市化进程的飞速发展以及城市人口的密集增长,在很多大中型城市,尤其是以北京、上海、广州、深圳为代表的城市,打车困难并且在上下班时间交通压力大的问题,2012年3月份,北京出台相关政策,鼓励乘客合乘出租车,并对合乘的分摊费用及发票做出了规定。特别是在早晚高峰时段,合乘者各付共同路段车费的60%,并可打印多份发票
随着人们生活水平质量的提高,人们对交通工具的最求也越来越高。既希望交通工具实惠,又希望交通工具快捷。现在的公交车虽然实惠,但是公交车在很多方面给人们的生活带来不便:人们做公交车时必须到公交站牌区等公交车;坐公交车必须做自己要到的那条路线上经过的公交车,这个原因往往会造成人们等一个小时甚至更长的时间的车;错过了一辆公交车,一般就必须等下一辆相同型号的车。
与公交车相比,出租车有很多优点:任意一辆出租车可以到达任何地方,非常快捷;还可以电话叫出租车,现在甚至还可以通过网络查找距离自己最近的出租车;当你不知道自己的目的地址在什么地方时,坐出租车是一种跟好的选择。这时我们往往不用查找自己的目的地的具体路线,出租车司机比我们更加了解地图,会将我们送到目的地。虽然出租车快捷舒适,但是现在人们大多数还是坐公交车,公交车价格实惠,出租车的乘车费用是公交车的十几倍甚至几十倍。这就是本次设计将要改善人们对出租车看法的地方。
第一章,本次设计将讲解设计的方案,工作原理,要实现的功能。
第二章,这一章详细的讲解设计的电路原理图及其各个部分功能的具体实现的方法。
第三章,这一章是设计实物的具体实现。在这一章,我详细的介绍程序编写的关键点的实现及程序调试的环节等。
最后的几章是对本次设计的参考文献,致谢词等。这是我第一次做这样的比较正式的设计,有不到位的地方,希望各位老师多多包涵。
第二章 方案设计
2.1 设计原理
现在城市的出租车的要求都是单人付费,很少有几个人共同付费或者出租车司机在车上已有乘客时搭载其他的顾客的情况。这些情况导致出租车的个人一次乘车费用比公交车贵上几十倍。
本次设计,即数码管显示的合成出租车计价器可以使个人一次乘车费用降低的同时,增加出租车司机的一次驾车收入。
数码管显示的合成出租车计价器的计费方式与普通的出租车的计费方式不同。在乘车付费人数为一人时,数码管上显示的该顾客需要支付的乘车费,其计费方式与现在乘出租车的是一样的。当乘车付费人数为两人甚至更多时,数码管上将会同时显示不同的乘客需要支付的乘车费。这时出租车的计费方式将会有所变化:首先计价器会自动的降低出租车的起步价,其次所有需要付费的乘客的起步费用加在一起所得到的起步费用比单人付费时的起步价高,甚至是单人付费时的起步价的几倍。这样既减少了个人乘车时的费用,又增加了司机在行驶同样一段路程上的钱数。
2.2 设计实现的功能
数码管显示的合成出租车计价器主要是为了显示不同的顾客同一辆出租车时各自的费用。它的要求有以下几点:
数码管显示的合成出租车计价器最多可以显示四个付费顾客的乘车费用,即出租车上最多可以承载四人。
显示的付费人数是根据实际的将要付费的人数来定的,而不是车上乘客的人数定的。
显示每一位顾客的乘车时间,起步价及单价。
④起步价和单价可以由出租车公司修改(起步价和单价的修改需要密码),以防止出租车乘车标准有所改变时需要从新设计出租车计价器。
2.3 方案选择
数码管显示的合成出租车计价器主要是以单片机为主控芯片,单片机通过控制四个MAX7219将传输数据到三十二个数码管,使这些数码管在不同的情况下显示不同的数据。
2.3.1 单片机的选择
本次设计选择STC12C5A60S2型号的单片机作为控制芯片。其主要有以下几个原因:
本次设计共需要32个引脚(包括电源端和接地端)的控制芯片,单片机当为首选。
去掉电源端和接地端,需要30个引脚来控制外围电路。一般的单片机虽然有四路I/O口共32个引脚,但是本次设计需要五路I/O口,使不同的模块数据通过不同的I/O口输入和输出。不同I/O口间数据的输入和输出影响小,既便于程序的编写,有可以防止电路的不稳定性造成数据的显示出现乱码。STC12C5A60S2型号的单片机其内部有自带的第五路I/O口P4,编写程序的时候只需设置相应的寄存器就可以用相应的第五路I/O口的引脚了。
STC12C5A60S2型号的单片机为增强型的单片机,它的每个时钟就是一个机器周期,运行速度是普通单片机的8到12倍。
④STC12C5A60S2型号的单片机价格实惠,同时其内部还用各种寄存器可以做一些其它的用途,与一般的单片机相比,他的功能非常强大,使人在设计电路的时候可以减少很多外围电路的设置来达到节约PCB板的成本。
⑤我经常使用STC12C5A60S2型号的单片机做课设,对其内部的寄存器的设置非常熟悉。
2.3.2 外围电路的方案设计
本次设计的外围电路主要涉及到数据显示和按键控制。其中数据显示必须用数码管,这是设计任务书中要求的。
数码管显示数据,其中数码管有三十二个。合成出租车最多可以乘载四个顾客,即最多有四个顾客同时付费。需要四个指示付费顾客的数码管及每个顾客需要显示价钱的数码管四个,这样需要二十个可以显示数据的普通数码管。除此以外还需要显示时间和出租车在单人乘车时的起步价及单价:这里我用可以显示时间的数码管三排(每排四个数码管),一排显示时间(小时和分钟),一排显示起步价,最后一排显示单价。
用三排可以显示时间的数码管是在需要显示年月日时分秒的时候直接编写程序就可以了,不必要重新制作PCB。
三十二个数码管,需要32个选择控制引脚,至少8个数据引脚,这样就需要四十个引脚的控制芯片了。为了节省控制芯片的引脚资源,我用四个MAX7219芯片来控制这些数码管。每个MAX7219芯片控制八个数码管数据的显示。一个MAX7219芯片可以由三个单片机引脚控制,四个MAX7219芯片只占用单片机的六个引脚资源。
2.4 总设计流程图及其说明
2.4.1 总设计流程图
下面是本次设计的具体实施步骤,每一步实施完成后才能去完成下一个步骤。有一个步骤没有完成或着出现错误将导致整个流程无法进行下去,甚至会造成设计无法完成。

在这里插入图片描述

图2-1 总设计流程图

2.4.2 总设计流程图分析
根据任务书所要实现的各个功能设计不同的电路模块(画电路原理图)。我焊接了时钟电路模块、按键控制模块和数码管显示模块。在设计这三个模块时,我查找了相关的资料(DS12887的存储地址,MAX7219的寄存器的操作方法等)。检测各个不同的模块,测试这些模块所对应得功能都可以正常实现时,再将各个模块连接到一起检测,看看不同的模块是否能够正常运行。能够正常运行才能说明自己的电路原理图及自己的元器件选择没有问题,才能够根据这个设计原理图来做PCB板。
关于画电路原理图,这一点我没有在总设计流程图中特意的显示出来。但是从上面的分析中可以看出来,我将各个模块连接在一起运行成功时,电路原理图就自己出来了。
焊接电路板是做好设计的第一个关键点,其次才是程序的编写及运行。PCB上元器件焊接完成后,根据上面各个模块原理图合成的总原理图来检查焊接元器件是否正确,同时检查电路板个元器件之间的连线是否和自己的原理图上的一样。假如元器件焊接不正确,将焊接错误的元器件去掉,重新焊接正确的元器件;若是电路板连线错误就要重新制作电路板。
④电路板焊接正确后就可以开始编写程序了。程序的编写是本次设计中最不浪费资源的部分。电器元件焊接错误,电路板制作错误等都会造成资金的浪费,而程序的编写失误则不会。程序编写错误只会导致程序运行的结果不是自己希望的得到的最终结果。但是编写正确的程序并且使程序实现自己所需要的功能不仅需要很长时间,还需要在编写前仔细的思考程序编写的流程图。关于程序的流程图及程序的关键点我将后在后面做详细介绍。
第三章 硬件电路设计
3.1 控制主电路设计

控制主电路采用STC12C5A60S2型号的单片机作为主控制芯片。它的主体原理图如下所示:
在这里插入图片描述

图3-1 主控芯片

本次课程设计需要用到主控芯片五路I/O口,从上图中可以看出,我用到STC12C5A60S2型号的单片机第五路I/O口的第六引脚(P4.5)。这个引脚的应用只需设置寄存器P4SW就可以了。
其次,本次设计我没有用到单片机的复位功能。当单片机本的复位引脚的电平变化有持续两个时钟周期的高电平时,单片机复位。由于本次设计是个小型设计,不涉及到单片机中的看门狗等涉及到复位的程序编写,更不存在死机等问题。所以没有设置复位按键,直接将复位引脚接地使其永不复位。这样做节省了资源。
单片机的P1口的前六个引脚接按键设置,P0口各个引脚和DS12887的八个数据引脚一一对应。P2口的前四个引脚分别连接四路MAX7219的片选信号角,当该引脚输入低电平时,选中该MAX7219芯片;P2口的第五脚同时连接四路MAX7219的数据输入脚,第六脚同时连接四路MAX7219的时钟输入脚。关于寄存器的设置我将在程序的编写部分做详细的介绍。
3.2 按键扫描电路
按键扫描电路用I/O口P1的前六个引脚控制按键的扫描。这种扫描设计用较少的引脚资源,扫描较多的按键。按键扫描电路只需扫描九个按键就可以了,六个引脚刚好可以设置六个按键的扫描。由于扫描按键的时候,I/O口P1的前六个引脚数值在不断地变化,所以在不影响其它显示数据的时候,按键扫描电路所对应的引脚最好设置为单独的I/O口。这样做为自己程序的编写带来方便。下图是按键扫描电路:

在这里插入图片描述

图3-2 按键扫描

从上图可以看出,控制I/O口P1的输出,使P1的输出脚的数值为十六进制数0xfe,即P1的第一脚输出低电平,其它七个引脚输出高电平。当按下按键S0时,P13被拉为低电平,使相应的I/O口引脚被拉低。当在程序中检测到P1^3的数值为0时,就可以判定按下的时按键S0。同样的道理判断其它八个按键。这就是按键扫描的原理。
最后,在每个引脚接一个10K欧姆的电阻并连接到电源端是为了初始化这些引脚的初始状态,防止这些引脚的状态任意选择,导致电路的不稳定和程序结果运行的不稳定。
3.3 时钟电路
在时候模块,我用DS12887来设置并接受时间信号。DS12887与主控芯片的连接图与下图所示:

在这里插入图片描述

图3-3 时钟电路

在上图中,DS12887的数据输入输出引脚与单片机的P0口连接。引脚P27与DS12887的片选信号脚连接,通过控制引脚P27来控制DS12887的开通。在合成出租车计价器的最终结果,时间是一直在显示的,所以引脚P2^7输出低电平,使DS12887一直处于工作状态。
在这里需要注意的是DS12887的AS数据读写控制信号脚与单片机的ALE脚相连接。这个脚是扩展I/O口P4的第六个引脚,在电路上用到该引脚时,需要在编写程序时设置相应的寄存器。关于寄存器的设置我将在程序的编写部分做详细的介绍。
3.4 数据显示模块
数据显示部分是本次设计中的关键部分,在这里我会详细的介绍。
3.4.1 电路原理图
数据显示模块一共用到32个数码管来显示时间、乘客需要支付的乘车费,起步价和单价。为了节省引脚资源,用四个MAX7219来控制这些数码管。每个MAX7219芯片控制八个数码管。四个MAX7219的工作原理是一样的,所以在这里我只介绍一个MAX7219芯片控制八个数码管。其原理图与下图所示:

在这里插入图片描述

图3-4 数据显示

3.4.2 工作原理
由图2-4可以看出MAX7219的DIG所对应的八个引脚分别对应八个数码管的共阴极。控制这八个引脚的电平的变化可以控制八个数码管的开和关(DIG某一脚输出低电平时,相应的数码管亮;输出高电平时,相应的数码管灭)。
数码管的的数据端与MAX7219的数据端分别对应连接,SEG A到SEG G用来控制数码管上显示不同的数,SEG DP控制数码管上的小数点。每个数码管在MAX7219中有相应的数据地址,将要在数码管中显示的数据写在这些地址里。通过单片机打开相应的MAX7219芯片,向MAX7219芯片的数据地址写相应的数据,MAX7219芯片就会控制不同的数码管显示不同的数据。
用同一个数据单口在不同的数码管上显示不同的数据是动态扫描的结果。数据输出端口在一个时间点只能输出一个数据并将这个数据送到相应的数码管上显示。每个数码管从控制芯片中得到数据到显示数据所用的时间非常短,八个数码管显示不同的数据所用的总时间也非常短。这就在我们的视觉上造成一个误差。
在第一个数码管显示数据后,我们将数据输入到第二个数码管时,第一个数码管已经关了。后面的数据的显示也是这样的。这样一来我们看到的理论情况应该是这样的:八个数码管不同时显示数据,最多只有一个数码管显示数据。事实上,八个数码管确实是理论上这样显示数据的,但是在第一个数码管关掉到第二个数码管实现数据的时间间隔非常短,小于千分之一秒,人眼不能分辨。正是这个原因,我们才可以看到32个数码管显示不同的数据。
对于MAX7219的寄存器的设置我将在程序的编写部分做详细的介绍。
3.5 原理图设计软件
在画电路原理图的时候,我用的是Cadence软件,而不是DXP软件。和DXP软件相比,Cadence软件具有以下几点优势;
(1)Cadence软件中的工具比DXP软件中的多。Cadence软件是现在军工业做PCB设计时用的主流软件,它可以设置各种设计师能够想到的问题。
(2)在Cadence软件中建立库文件的时候,可以在一个库中同时建立几个元器件而不需要将设计的元器件保存后再设计其它的元器件。
(3)在Cadence软件中画元器件的封装的时候,我们可以根据元器件的文档资料来设置电子元器件的各个信息,可以使元器件的各个引脚的信息明确。在DXP软件中,只有元器件的引脚类型只有几种选择。
(4)当一个电路原理图非常大而不能在一个界面将原理图画完时,DXP软件需要画一个总原理图框架;而Cadence软件只需建立一个原理图工程,然后在各个页面画不同部分的原理图即可。就这点而言,Cadence软件更加实用,更加方便。
(5)在DXP软件中画完电路原理图后,需要操作若干步骤后才能够让软件检查自己的电路图是否有出错的地方;而Cadence软件只需在一个界面选择自己将要检查的项目,Cadence软件就会在自己出错的地方用亮色显示,甚至会检查出原理图中不正确的连线。
(6)在Cadence软件中,我们可以通过将电子元器件的各个属性填写在表格中来画引脚较多的芯片。
(7)Cadence软件中表示电子元器件的封装信息,我们通过这些信息生成该电路原理图的网表。这个网表将会在画PCB板时自动的选择电子元件并且自动的布线,我们所要做的就是将这些电子元件排版就可以了。

第四章 程序的编写
4.1 编译环境
本次设计的程序编写是在KEIL中进行的。单片机版的KEIL软件自带了多种单片机的头文件,在这些头文件中定义了单片机的各个寄存器。这些寄存器包括单片机的I/O 口的地址指示;特殊寄存器的地址指示,中断寄存器的地址指示,中断优先级的设置等。
KEIL软件中有连接路径设置,可以将程序的头文件和各个子文件与程序的主文件相连接,使主文件能够调用这些文件中的函数及变量。KEIL软件的编写语言为C语言和汇编语言。
用C语言或者汇编语言写完一个程序后,只需点击检测按钮KEIL软件就会检测出程序中除逻辑外的错误,并指出出错的地方所在的位置。同时KEIL软件还会将程序中检测到的没有用到的变量和函数设置为警告,这些没有用到的变量和函数会占用程序的空间资源,将这些没有用到的变量和函数去掉后,会提高最终生成的文件的运行速度和程序的稳定性。
KEIL软件的连接器件所组成的按钮将程序的所有文件连接在一起生成可以烧入单片机的HEX文件。
除此之外,KEIL软件还有仿真功能。在仿真功能中,我们可以设置单片机的晶振频率。通过单片机的晶振频率,我们可以比较精确的设置程序的每一个步骤执行时所用的时间。仿真功能中还可以显示单片机各个I/O口引脚在不同时刻电平的高低情况。通过这些I/O口引脚电平的变化情况,我们既可以在将程序烧入单片机中之前,检测程序的结果,又能够在自己分析不出自己的错误原因时,快速的找到自己逻辑错误点。最重要的一点,我们可以利用这个功能在硬件电路没有完成前开始编写程序。
4.2 烧写软件
STC_ISP_V480是我这次设计所用到的烧写软件。这款软件提供了将HEX文件烧入STC系列的单片机中的时所需要的STC芯片类型。
4.3 程序的编写
4.3.1 头文件
一般用KEIL软件编写程序时,选择的都是ATMEL公司的51系列的单片机芯片。51系列的单片机的结构大体上都是一样的,所以它的头文件的设置的主体都是一样的,即使有不一样的地方,只需再重新在主文件中加载设置就可以了。
但是本次设计所用到的单片机型号是STC12C5A60S2,这个单片机不仅包含了AT89S51头文件中的一些设置,同时它自己还有很多寄存器设置。所以本次程序编写的头文件为STC12C5A60S2.H。
4.3.2 扩展I/O口P4的寄存器设置
访问STC12C5A60S2单片机的P4口,需要一些特殊的设置。这种型号的单片机的P4口的位地址为0XC0H,在STC12C5A60S2单片机的头文件中的定义为P4为0xC0。定义了P4口的位地址后还需要设置P4SW寄存器才能够同使用一般I/0的方法那样使用P4口。P4SW的寄存器的位地址为0XBBH。关于这两个寄存器我们所用到的只有P4口的第六位P4.5及P4SW寄存器的第六位ALE_P4.5,其设置于下所述:
ALE_P4.5的值为0时,ALE_P4.5的作用和一般的单片机是一样的,为ALE信号脚,只有访问片外扩展器件时,ALE信号脚才会出现高低电平的变化。
ALE_P4.5的值为1时,ALE信号脚被设置成单片机扩展I/O口P4的P4.5。在原理图中P4.5用来控制DS12887的AS信号脚。
4.3.3 MAX7219.H文件
在 MAX7219文件中,我定义了六个引脚,两个函数。六个引脚用来控制MAX7219芯片的选择和数据的传输。前四个引脚为MAX7219芯片的片选信号,定义为:ml1为P20;ml2为P21;ml3为P22;ml4为P23;这四个引脚定义是用来选择MAX7219芯片的,当选择一个MAX7219芯片时,这个MAX7219芯片对应的片选信号引脚值为0。同时这四个芯片的片选信号引脚值在一个时间点最多一个为0。例如单片机选中第一个MAX7219芯片时, ml1值为0,ml2为1,ml3为1,ml4为1。最后两个引脚定义为 dinP24;clk为P25。din是四个MAX7219芯片共同的串行数据输入输出端。clk为时钟频率输入端,输入的频率为单片机的主频率。
两个函数的定义分别为: void write_address(unsigned char address,unsigned char data1,unsigned char number); void init_max7219();
这两个函数都是无返回值的函数。第一个函数用三个功能:(1)选择MAX7219芯片,这是由该函数中的参数number来实现的。number的值只有四个:1,2,3,4。number的值为1时,在第一个函数中就会选中第一个MAX7219芯片,其在函数中的实现为 ml1为0,ml2为1,ml3为1,ml4为1。当number为其它值时,会选择相应的MAX7219芯片。除此以外,第二个函数的第一个参数为寄存器的地址,第二个参数为第一个参数地址寄存器的输入的数据。
第二个函数用来初始化MAX7219芯片。MAX7219芯片内部有很多寄存器,只有了解这些寄存器的作用及其设置,才能够正确无误的使用MAX7219芯片。
MAX7219芯片的寄存器及其设置:
(1)掉电模式下的寄存器的地址为0XOCH,其输入数据有两个,0X01H和0X00H。当输入数据位0X00H时,MAX7219芯片会将数码管全部关闭;当输入数据0X01H时,MAX7219芯片将扫描限制控制寄存器所选择的数码管打开。
(2)译码模式寄存器的地址为0X09。译码模式寄存器用来设置数据的现实方式。当输入数据为0X01H时,译码器对数据寄存器的低四位进行译码(BCD码),此时数据寄存器的最高位为小数点位。当输入的数据为0X00H时,译码模式寄存器选择不译码,此时MAX7219芯片控制数码管的方式与单片机直接控制数码管的方式相同。
(3)亮度控制寄存器的地址为0X0AH。数码管的亮度是通过电流脉冲的宽度来调节的,亮度控制寄存器将数码管的亮度由强到弱分为十六个等级,输入的数据从0X0FH到0X00H。输入的数据越大,数码管的亮度越强。
(4)扫描控制寄存器的地址为0X0BH。扫描控制寄存器用来控制数码管显示的个数,若八个数码管同时显示,扫描控制寄存器将以800HZ频率对这八个数码管进行数据扫描。在本次设计中需要八个数码管同时显示,所以这里就在扫描控制寄存器中输入数据0X07H。
(5)显示检测寄存器的地址为0X0FH。其输入数据有两种,对应着两种状态。 输入数据0X00H,显示检测寄存器的工作状态为正常,此时可以开始向数码管中写数据了。 输入数据0X01H,显示检测寄存器的工作状态为检测,只点亮数码管而不能向MAX7219芯片的其它寄存器中输入数据。
(6)0X01H到0X08H所在的数据寄存器分别对应着八个数码管。在这些数据寄存器中输入OXOOH到0X09H,其相应的数码管中将显示数据0到9;在这些数据寄存器中输入0XFFH,将会关闭相应的数码管。
(7)MAX7219芯片的初始化: 打开掉电模式寄存器,设置其工作状态为正常模式,即在掉电模式寄存器中输入数据0X01H; 设置显示检测寄存器的工作模式为显示模式,即在显示检测寄存器中输入数据0X00H; 设置译码模式寄存器的状态为译码模式,即在译码模式寄存器中输入数据0XFFH;④ 设置亮度控制寄存器,设置数码管的亮度;⑤ 设置扫描控制寄存器,使寄存器能够同时扫描八个数码管。
4.3.4 DS12887.H文件
DS12887为时钟显示芯片。DS12887自带晶振和电池,可以在掉电的时候自动的运行10年,还可以将时间信号保存到其内部的存储器中。DS12887显示时间的模式有很多种。例如,其显示小时的模式可以为12小时制的也可以是24小时制的,当小时的计算模式为12小时制的时候,有AM和PM提示。
DS12887芯片内部有多个寄存器用来存储或设置DS12887芯片的现实模式,下面来介绍各个寄存器的地址及该寄存器存储的数据范围:
(1)秒寄存器地址为0X00H,这个寄存器中存储的是当前的时间秒,数据模式为BCD模式和二进制模式。
(2)秒闹钟寄存器地址为0X01H。这个寄存器中设置的是闹钟的秒。这个寄存器的数据模式和秒寄存器的一样。
(3)分钟寄存器的地址为0X02H。这个寄存器中存储的是分钟的信息,当秒寄存器的数据从0X3BH或者二进制数111011变为0X00H或者0时,分钟寄存器中的数据自动加一。
(4)分钟闹钟寄存器的地址为0X03H。这个寄存器中存储的时闹钟的分钟信息,其用法和秒闹钟寄存器的用法是一样的。
(5)小时寄存器的地址为0X04H。在这个存储小时信息的寄存器中,数据的存储模式有两种: 12小时模式; 24小时模式。当寄存器B的第二为的值为1时,小时寄存器存储模式为24时制;当寄存器B的第二为的值为0时,小时寄存器存储模式为12时制。
(6)小时闹钟寄存器的地址为0X06H。该寄存器存储的是闹钟的小时信息,小时的设置模式与小时寄存器的一样。
(7)星期寄存器的地址为0X07H。该寄存器中存储的是星期信息,当寄存器中的数据值为0时,表示今天是星期天;数值为2表示今天是星期一,其它几天的显示以此类推。
(8)日期寄存器的地址为0X07H。日期寄存器中存储的是日期信息。它的取值范围受月份寄存器和年份寄存器共同的的影响。例如,月份寄存器中的数值为0X01H时,该寄存器的数值最大为0X1F;年寄存器存储的数值为0X00H,月份寄存器中的数值为0X02H时,该寄存器数值最大为0X1CH。
(9)月份寄存器的地址为0X08H。寄存器中存储的为月份信息,取值范围为0X01H到0X0BH。
(10)年份寄存器的地址为0X09H。寄存器中存储的为年份信息,取值范围为0X00H到0X63H。在显示器上显示年份的时候,我们会自己将本世纪的数加到年份数的前面。
(11)寄存器A的地址为0X0AH。 其最高位为UIP,更新标志位。当寄存器A的最高位的值为1时,表示DS12887芯片即将进行更新。当期数值为0时,表示至少244微秒内芯片不会更新。当芯片不更新时,我们可以读各个寄存器中的数据,也可以将数据写入各个寄存器汇中进行设置。 寄存器A的第五、六、七位时用来启动和关闭晶体振荡器和复位分频器的。当寄存器A的第五、六、七位的值分别为0,1,0时,晶体振荡器打开,同时保持时钟运行;当寄存器A的第五、六、七位的值分别为1,1,X(X值可以是0,也可以是1)时,晶体振荡器打开,复位分频器保持复位状态。 寄存器A的低四位是用来设置其它寄存器的。
(12)寄存器B的地址为0X0BH。对于程序的编写,熟练掌握寄存器B用法,将会为调试工作带来很多便利。 寄存器B的最高位SET用来设置DS12887芯片是否更新,当该位的值为0时,DS12887芯片可以更新;当该位的值为1时,禁止DS12887芯片更新。在写程序的时候一般设置该位的值为0; 寄存器B的第七位PIE为周期中断输出控制,当该位的值为0时,周期中断将不会输出;当该位的值为1时,周期中断可以输出到IRQ。 寄存器B的第六位控制闹钟中断,当该位的值为0时,闹钟中断将不会输出;当该位的值为1时,闹钟中断可以输出到IRQ。④ 寄存器B的第五位控制更新结束中断,当该位的值为0时,更新结束中断将不会输出;当该位的值为1时,更新结束中断可以输出到IRQ。⑤ 寄存器B的第四位SQWE值为0时,SQW脚输出低,当该位值为1时,SQW脚输出设定频率的方波。⑥ 寄存器B的第三位DM位的值为0时,时、分、秒、年、月、日等寄存器中的数据格式为二进制;DM值为1时,这些寄存器中的数据格式为BCD码。⑦ 寄存器B的第二位24/12,当寄存器B的第二位值为1时,小时寄存器和小时闹钟寄存器的小时模式为24时制;当该位值为0时,小时寄存器和小时闹钟寄存器的小时模式为12时制。 ⑧ 其余的几个寄存器主要是用来控制一些中断的,在本次设计中没用到,在这里就不做介绍了。
(13)DS12887芯片内部有两段RAM可以用来存储数据。这两段RAM地址范围为0X0EH到0X30H和0X33H0X7EH。可以将掉电情况下需要保存的数据存储到这两段地址中。
在DS12887.H文件中,我一共定义了四个引脚,四个函数。它们分别为: 引脚定义,dds为P37;drw为P36;dcs为P27;das为P45; 函数定义,第一个函数,void write_ds12887(unsigned char add,unsigned char date);第二个函数,unsigned char read_ds12887(unsigned char add);第三个函数,void init_ds12887();第四个函数,void set_time()。
dcs为片选信号脚,该脚的电平为低时,选中DS12887芯片。dds为总线数据输入输出控制角,当dds的值为1时,表示DS12887芯片正在输出数据,即单片机从DS12887芯片中读出数据。das为地址锁存引脚。drw为读写控制引脚,drw值为1时,从DS12887芯片中读出数据;drw的值为0时,将数据写入DS12887芯片中。
void write_ds12887(unsigned char add,unsigned char date)作用是向相应的寄存器或者地址写数据:函数的第一个参数为将要写入数据的地址,第二个参数为将要写入的数据。该函数无返回值
unsigned char read_ds12887(unsigned char add)的作用是从一个地址中读取数据,该函数的参数为将要读取数据的地址。该函数的返回值为参数地址所保存的数据。
void init_ds12887()为DS12887芯片的初始化函数,无返回值。在该函数中先设置寄存器A的值为0X20H,此时开启了晶体振荡器,保持时钟芯片的运行。然后设置寄存器B的值为0X26H,使DS12887芯片正常更新运行的同时禁止DS12887芯片的各个中断的输出,最重要的是设置小时的模式为24时制,各个寄存器数据输出模式为BCD码。
第一次使用一个DS12887芯片时,不仅要初始化DS12887芯片,还要将DS12887芯片中的时、分、秒、年、月、日等信息设置为现在时刻的数据。void set_time()为无返回值函数,没有输入参数。这是我在时钟模块中留下的一个扩展模块,防止以后需要修改时间用。我以前编写过DS12887芯片的时间设置程序,我用这个程序来设置本次设计中DS12887芯片的第一次时间显示。
4.4 主程序
按键控制模块的工作原理我在前面已经详细的介绍了,在这里就不做介绍了。由于主程序不仅涉及函数和引脚的定义,还涉及到程序的流程及各个功能的实现,所以我将主程序部分独立的作为一节。
4.4.1 主程序流程图
在这里插入图片描述

图4-1 程序流程图
4.4.2 主程序分析
上面的流程图是我设计将我的第一个流程图修改多次并验证得到的。我将这个流程图写成具体的程序,程序运行的结果为自己想要的结果的。下面将来分析流程图的功能实现。
(1)合成出租车的起步价、单价和时间的修改。合成出租车的初始化信息一般由出租车公司统一管理,所以在数码管显示的合乘出租车计价器中设置了密码权限,同时这个密码只有出租车公司自己知道。 当出租车的起步价、单价有变化时,出租车公司只需输入密码修改起步价和单价和不需要从烧写程序到单片机中,也不需要将计价器从车上卸下来,更不需要重新修改计价器的PCB板。 不同地方的出租车的显示时间也不相同,当出租车公司需要修改出租车的时间时,其修改方式和修改出租车的起步价和单价的方式一样。 由程序流程图可以看出,当出租车公司修改这些信息时,出租车上没有乘客,数码管不显示,程序可以自动的得到这些信息而进入信息修改部分。
(2)乘客的费用显示和计算。当有乘客上车时,出租车司机按下计费开始按键,表示上来了一个乘客,开始计费。在显示该乘客费用的数码管部分显示起步价,之后每过五分钟,乘客的数码管的费用会自动加上单价。
(3)出租车上乘客人数的判断。出租车上最多可以承载四个人,当车上的人数不到四人时,有人上车,上车的人的计费方式与(2)中的计费方式类似;当车上的人数超过四人时,出租车将不在搭载新的乘客。
(4)当有乘客下车时,出租车司机按下该乘客所对应的计费结束键,使该乘客所对应的显示费用的数码管停止计费。同时,关闭该乘客的所对应的数码管。
(5)出租车上的乘车人数与出租车的付费人数有时是不一致的。出租车上的付费人数有二极管指定,二极管的亮起的个数为需要付费乘客的人数。
(6)当出租车上没有乘客时,从流程图上可以看出,程序将判断是否修改起步价、单价等信息,若不修改这些信息,出租车上的数码管只显示时间。
4.4.3 主程序代码分析
主程序中连接了其它程序块外,还定义了一些函数和变量。下面我将详细的介绍这些函数和变量的作用。
(1)我在主程序中定义了很多变量。 字符型的数组有mima[4],shuzu[4]:mima[4]用来设定原始密码,shuzu[4]用来存储修改起步价、单价等信息时输入的密码。在主程序中将这两个密码相比较,若两个数组对应的数据相等,则可以修改起步价、单价等信息,否则不可以。字符型的变量有miao0,miao1,fen0,fen1,d1,change,
qibujia,danjia。miao0和miao1用来判断时间是否过了一秒,时间显示数码管上的小数点闪烁的时间间隔为一秒。fen0和fen1用来判断时间是否过了五分钟。若过了五分钟,每位乘客需要需支付的乘客费自动加上出租车单价,相应的数码管也会显示现在的乘车费;否则数码管上显示的需要支付的费用不变。change用来标识是否需要修改起步价、单价等信息。change的数值为1时,修改信息,为0时,不修改信息。
(2)主程序中定义的函数有:第一个函数为void close_deng(),这个函数是用来关闭指示付费乘客的二极管。第二个函数为void display_time(unsigned char number),这个函数用来显示时间。第三个函数void display_guke(unsigned int a[]),这个无返回值函数用来点亮指示付费乘客的二极管。第四个函数为void
display_danjia(unsigned char danjia,unsigned char address,unsigned char number),这个函数用来显示各个需付费乘客需要支付的费用。
(3)根据上面几个函数和变量的介绍,再加上前面几个模块函数及其各引脚的定义,主程序就很容易理解了。这里就不做深入的介绍了。
4.5 程序运行结果
经过我多次的修改修改程序,程序的运行结果不经可以实现任务书中的基本功能,还为本次的设计在未来的使用中留下来很多可以扩展的部分。这样做的目的是,当合成出租车的起步价、单价等信息出现变动时,我既不需要编写程序,也不需要修改电路板,可以节省很多的成本。
至此,本次设计已完成了一大半,接下来要测试数码管显示的合乘出租车计价器的整体稳定性。

第五章 设计实物的测试和调试
5.1 测试目的
从一个用产品的角度看,我认为一个好的设计,它最重要的地方不是它能够实现设计的基本要求,也不是它的成本比一同类设计低很多甚至低很多倍,更不是它的创意的目光独特,而是这个设计的质量。检测设计的质量就是测试最重要的测试项目。
5.2 测试项目
5.2.1 功能测试
不同的人完成同一个设计,其结果是不同的。所以在测量设计的功能时,不仅要测量设计任务书上的基本要求的功能,还要测量扩展的功能。在这里,任务书上的基本功能要着重测量。
5.2.2 稳定性测试
今年我在一家电脑设计及生产公司实习了三个月,第一个月我主要是测试、维修电脑主板等电子产品。我所实习的单位的产品都是工业级别,产品的要求非常严格。参照其要求,我对自己的设计也做了的相关的要求。
本次设计是我第一次设计的产品,我非常希望有一天它可以用到人们的日常生活中。所以我希望我的设计实物有非常强的稳定性。
对于本次设计的稳定性,我有以下几点要求:在突然断电后再上电时,产品显示正常;设计说明书上的每一个操作,我的设计都能够准确无误的实现;我的设计在运行的过程中不会出现错误。
对于设计的第一点,我将会不停地断电和上电,每一次上电时我将会记录显示的数据,看起是否显示正常。若有一次显示不正常,我将会检查修改电路和程序,直到数码管显示的合乘出租车计价器每一次的显示的数据都准确无误。
测试项目的第一点通过之后才可以检测测试项目的第二项。在这一项,我做的有两点。第一点,按照设计说明书上的步骤,先自己检测操作十遍。显示的结果准确无误后,找十个不同的人操作一遍,若显示的结果正确,进行下一项;否则,需要重新修改自己的程序。第二点,按照设计说明书上的操作步骤,在不同的操作步骤中执行错误的操作。若无论执行任何错误操作,数码管都只显示时间,说明设计无问题,否则需要重新修改设计程序。
最后一项关系到人们生活的利益。从出租车司机的角度和乘客的角度看,没有人会希望自己某一次乘车时,数码管显示错误的数据。当数码管显示出现错误时,将会造成一系列不良的后果。首先,司机和乘客之间不能够正确的收取或支付乘车费;其次,司机和乘客不知道在路上行驶的时间。测试最后一项:我将按照工业的标准,是我的数码管显示的合乘出租车计价器在所有的数码管显示的情况下运行48小时,若运行的过程中数码管显示正常,则表示数码管运行正常。否则需要修改电路板。
每一次测试结果出现错误数据显示时,都需要确定出现错误的原因,确定不是程序和电路板出现问题时需要重新测试该项。否则修改程序或者电路板。
5.3 测试并调试结果
完成一个设计的程序和电路板使人的自信心得到增强,但是当检测到这个设计出现问题时,作为设计本人,我将感觉到设计就像一只刺猬,无处下手。
在测试的过程中,我发想了一些电路板和程序上的问题。根据这些问题,我做了一些相关的修改。由于这是我第一次做设计,所以在测试的时候发现了很多问题。在这里,我会详细的介绍几个给我留下深刻印象的问题。
(1)我没有拿到我的电路板时,我根据设计原理图将主程序写完了。但是当我将这个程序生成HEX文件烧进电路板时,数码管不显示时间,也没有显示小数点。当时,我做的第一件是接了一个万用表。我先按照电路原理图将电路板的各个元器件测量一遍,发现元器件焊接无问题;之后,我测量这些元器件各个引脚的与那些现在同一条线上,发现也没有问题。
发现电路板无问题后,我开始检查我写的程序。最后我发现我在芯片MAX7219的初始化中少加了一行代码。这段代码的作用是用来打开MAX7219芯片的。
(2)打开芯片MAX7219后,数码管开始显示数据。但是时间不能够正确的显示。我查了以下DS12887芯片在电路图上的连接线,发现DS12887的地址锁存引脚连接与单片机的扩展I/O口P4的地第六脚相连接。我做相关的设置后,时间可以正常显示。
截止到目前,各个基本功能调试成功,接下来将会正式的开始测试。
(3)在不断地开关电路板的电源时,我发现电路板的时间显示极不稳定,经常在上电时显示时间的部分数码管出现乱码,有时其实现实时间,数字也会闪烁。但是当我将合乘出租车计价器固定时,这些情况也都消失了。本次设计的实物时两块电路板连接起来的,在电路板的连接部分,电路板有时会接触不良。只要在上电前检查两块电路板是否连接牢固就可以了。
(4)调试上面一项的出现的问题的过程中,我有一次将DS12887芯片从电路板上取下来。然后我重新插上DS12887芯片时,数码管不显示时间了,也不现实乱码。只显示我初始化的时间。我摸了一下芯片DS12887,发现该芯片发热,我意识到时芯片插错了。
(5)在执行我自己写的操作说明书上的步骤的过程中,我发现了很多问题。根据这些问题,我对程序做了相关的改动:
我第一次按下乘客的开始计费按键时,相应的数码管开始计费;但是该乘客对应的指示二极管亮。在本次设计中,指示二极管代替数码管中不需要用到数码管的小数点,所以这些小数点由芯片MAX7219控制。我检查程序时发现自己在上次调试时间的时候将指示功能关掉了。
数码管显示的合成出租车计价器的计费方式与一般的出租车不同。合乘出租车的起步价将随着出租车上的付费人数变化而变化。同一时间,出租车上的付费人数越多,起步价越低。
在出租车上有乘客的情况下,每上一个付费乘客,出租车上付费乘客将要支付的费用作出相应的变化,但是这个变化是有个底线的。正是没有设置这个底线,我的出租车的起步价有出现负数的情况。
数码管现实的合乘出租车计价器可以同时显示四个乘客乘车费用,有四个按钮来停止计费。表示这些乘客下车了。操作的过程中,我发现但我按下停止计费按钮时,对应的数码管不停止计费,而另一组数码管停止计费关掉了。这是程序逻辑问题,我已修改过来。
④关于本次设计,我所做的扩展部分:出租车公司可以输入密码来修改出驻车的起步价、单价等操作,没有发现问题。至此,程序的操作完成了,即完成了测试项目的前两项。
⑤在程序的运行48并显示检测其运行结果的测试项目中,我没有运行连续运行48小时。我连续运行了6小时,并且连续运行了一个星期。第一天的我发现数码管只显示起步价,是程序出错。修改了程序后,连续运行一个星期,每次数码管的显示结果都是126.4(按出租车的平均行驶速度为每小时12千米),其中起步价为4元,路程费为122.4元。至此,完成数码管显示的合乘出租车计价器的调试和测试项目,即完成数码管显示的合乘出租车计价器的实物。
5.4 测试与调试后的总结
测试出设计的错误地方,然后修改程序,调试结果显示。测试和调试是密不可分的。上面我介绍的我在测试问题后的修改程序或者检查电路等其实就是在做调试。所以我就不在独立的介绍调试部分了。
从电路图的设计到实物的合格,发费时间最多的部分就是设计实物的测试和调试。这一部分我一共发了三周的时间。若我现在重新设计一个类似的项目,我将能够大大的缩短自己测试和调试部分的时间。下面是缩短这部分时间的一些总结:
每一次将程序生成的HEX文件烧入到单片机中,都要查看自己烧入的HEX文件是否为自己刚刚编译生成的文件。
当确认程序出现问题时,做的第一件事应该是看看自己是否正确的烧入HEX文件。若正确烧入HEX文件,就没有必要反复地编译未修改的程序代码,更没有必要反复的重新生成HEX文件。只需编译一次,重新生成一个HEX文件就可以了。
重新烧入编译生成的HEX文件后,若程序运行的结果不变,则说明需要修改程序。
当发现一个不知道为什么出错的问题时,做的第一件事就是再次检查自己的电路板,看其是否出错。若不出错,用其它的开发板检查自己的程序。
④不同模块实现的功能是不同的函数隔离开。同时,不同的函数之间不存在数据相互影响的问题,以防止出现乱码。
第六章 总 结
通过制作数码管显示的合乘出租车计价器,我不仅了解了类似的电子产品的设计开发过程,还认识到自己的一些不足之处。
6.1 设计开发流程总结
(1)我们拿到一个类似于数码管显示的合乘出租车计价器的设计时,我们所要做的第一件事不是去买材料。我很多同学拿到设计后就去买材料去了,结果浪费了一天时间还不知道没什么电子元器件。电子元器件和设计要实现的功能是联系在一起的,不同的功能需要不同的元器件。只有确定了电子元器件后,我们才能够确定需要买什么元器件。
(2)在买电子元器件时,还需要注意几点问题:首先确定控制芯片,查看工作频率,工作电压等是否是自己需要的;选择元器件的时候,要查看改元器件是否能够工作在自己所选择控制芯片的工作频率下工作;若要买电路模块,一定要有电路模块的详细资料。这样不仅为程序的编写带来便利,还能够避免因为连接错误而导致电路模块烧坏或者损坏电路主板。
(3)选择完电子元器件后,就是设计电路原理图了。画电路原理图的时候,先将各个模块的原理图分别画出并焊接到不同的动动板上,主控制芯片模块也单独焊接在一块动动板上。分别将各个功能模块与主程序模块相连接,并烧入测试程序,检查该功能是否正常。无论模块的检测结果是否正常,都将检测下一个模块。
所有的模块检查完后,分析检查结果。若所有的功能模块的检测结果都不正常,则说明主控制模块很可能出现问题。否则就是检测不正常的功能模块有问题。维修检测不正常的模块,直到所有模块的功能都正常为止。
当所有的模块功能都检测正常后,将所有的功能模块都连接到主控制模块上。分别在主控制模块上烧写各模块的测试程序。若有不能够正常运行程序的模块,修改该模块与主模块之间的连接。当所有的模块都能够使主控制模块正常的运行其相对应的程序时,就可以按照模块间的连接将电路图画出来。
(4)画好电路图后,就可以根据电路图画PCB板了。画PCB板的时候一定需注意电子元器件的实际封装。
(5)只有了解了一个电子元器件,才能够知道怎么通过程序来控制这个芯片。
(6)关于调试和测试部分,我在上一章已经具体的介绍了。
6.2 自我认识
通过设计数码管显示的合乘出租车计价器,我更加深刻的认识到自己的一些不足:
(1)在编写MAX7219芯片模块的程序的时候,我将MAX7219芯片仔细认真的看了三遍,编写的程序不能够使MAX7219芯片控制数码管。当我看我同学的MAX7219芯片的程序后,我发现自己少设置了一个寄存器。这个问题让我对自己的自信心产生了怀疑。但是当我用两个小时帮助一个画完一个同学的设计仿真图和写完相应的程序时,我发现自己可以完成别人一个星期也可能完成不了的问题。当别人对自己或者自己对自己的能力产生怀疑时,我们要做的就是积极的锻炼提高自己的能力。
(2)除此之外,我发现自己有时不能够彻底的解决一件事。
在写本本次设计的程序的时候,我用到了我大三的时候编写的程序子文件DS12887.H和SKY.H。但是我发现这两个子文件中的一些函数不具备移植性。
我以前也遇到过这样的问题,但是我自己觉得调用子文件中的函数时,只需稍微修改一下,不会浪费很多时间的。这个问题不仅使我编写的程序出现问题,还浪费时间。
(3)在编写数码管显示的合乘出租车计价器的程序的时候,我做过几次大的改动。每一次大的改动都是我在讲自己设计的结果演示我的指导老师查看后,指导老师要求下我才我修改。
每一次我的指导老师指出的问题,我提前已经注意到了,但是我不想修改。最开始的时候,我觉得自己已经实现了任务书中的功能,没有必要再做修改,或者我觉得自己所发现的问题不影响设计的结果。直到我将程序大改动两次后,我觉得自己与其浪费时间去修改发现的问题或者需要加上功能,还不与将数码管显示的合乘出租车计价器按照其实际的作用完美的设计出来。
致 谢
数码管的合乘出租车计价器虽然是我自己的毕业设计,但是没有刘老师的指导和帮助,我将无法完成我的毕业设计。我改写过很多次程序,也改动过程序的流程图设计。我的每一次改动都是在刘老师的指导下完成的。
刘老师先从设计的基本功能来检验我的设计,然后检查我的程序的基本操作是否出现乱码的情况,接着从操作简便的角度来指导我该向那些方面修改我的设计实物,最后刘老师从实物运行功率的角度考虑我的设计。经过上面的一些指导,我的毕业设计完美完成!
再次感谢刘老师,您辛苦了!
参考文献
[1]刘和平.单片机C语言编译及其应用.2006.
[2]马忠梅.单片机的C语言应用程序设计.2006.
[3]曹国华,单片机原理及接口技术. 西安:西安电子科技大学出版社.2000.
[4]周向红,范伟. DS12887实时时钟芯片及应用研究.2006.
[5]陈洪财.基于单片机的模块化教学研究.电气电子教学学报.2010.
[6]谭浩强,C程序设计.北京:清华大学出版社.2003.
[7]谭博学.集成电路原理与应用.北京:电子工业出版社.2003.
[8]范立南,李雪飞,尹授远.单片微型计算机控制系统设计.北京:人民邮电出版社.2004.
[9]郝文化.电路原理图与PCB设计.机械工业出版社.2004.
[10] 李伯成.基于MCS-51单片机的嵌入式系统设计.电子工业出版社.2004.7.
[11]谢斌.Proteus与Keil在单片机开放性实验中的应用.电子测量技术.2008.
[12] 沈红卫.单片机应用系统设计实例与分析.北京航空航天大学出版社.2003.
[13] 张毅刚.单片机原理及应用.北京:高等教育出版社.2003.
[14]郭天祥.51单片机C语言教程.北京:电力工业出版社.2010.
[15]MAX7219显示驱动芯片中文资料.电子发烧友.
[15]MAX7219显示驱动芯片外文资料.元器件交易网.

附 录
1 电路原理图
在这里插入图片描述
在这里插入图片描述

附录 整体设计电路图

2 程序
2.1 主程序文件
#include “STC12C5A60S2.H”
#include “sky_hechengche.h”
#include “max7219.h”
#include “ds12887.h”

void close_deng();
void display_time(unsigned char number);
void display_guke(unsigned int a[]);
void display_danjia(unsigned char danjia,unsigned char address,unsigned char number);
void main()
{

unsigned char mima[4]={2,0,1,4},shuru[4];
unsigned char miao0,miao1,fen0,fen1,d1=0;
unsigned char change=0,danjia=17,qibujia=80;
unsigned int sky,a[4]={0,0,0,0},b[4]={0,0,0,0},i=0,j=0;

P4SW|=0x20;
init_ds12887();
init_max7219();

fen0=read_ds12887(0x02);
miao0=read_ds12887(0x00);
danjia=read_ds12887(0x30);
qibujia=read_ds12887(0x0e);
display_danjia(danjia,0,2);
display_danjia(qibujia,4,2);
close_deng();
while(1)
{

display_danjia(danjia,0,2);
display_danjia(qibujia,4,2);
fen1=read_ds12887(0x02);
//display_time(d1);
if(fen1==(fen0+5))
{

fen0=fen1;
for(i=0;i<4;i++)
{

if(a[i]1)
{

b[i]+=danjia;
}
else
{

b[i]=0;
}
}
}
//display_time(d1);
miao1=read_ds12887(0x00);
sky=sky_he();
if(sky
0)
{

change=1;
for(i=0;i<4;i++)
{

change=sky_he();
write_address(i+1,0×80,1);
while(change==224)
{

change=sky_he();
shuru[i]=change;
}
write_address(i+1,shuru[i],1);
if(shuru[i]!=mima[i])
{

change=0;
close_deng();
return;

			}
		}
		close_deng();
	}
	for(i=0;i<4;i++)
	{
		if(sky==(i+1))
		{
			a[i]=1;
			if(sky==1)
		       {
			   	 qibujia=80;
				 b[0]=qibujia;
			   }
		    if(sky==2)
			    {
			   	 qibujia=60;
				 b[1]=qibujia;
				 b[0]=b[0]-20;
			   }
			if(sky==3)
				{
			   	 qibujia=50;
				 b[2]=qibujia;
				 b[1]=b[1]-10;
				 b[0]=b[0]-10;
			   }
			if(sky==4)
				{
			   	 qibujia=40;
				 b[3]=qibujia;
				 b[2]=b[2]-10;
				 b[1]=b[1]-10;
				 b[0]=b[0]-10;
			   }
		}
		
	}
	for(i=0;i<4;i++)
	{
		if(sky==(i+5))
		{
			a[i]=0;
			b[i]=0;
		}
	}
	
	while(change)
	{
		 sky=sky_he();
		 if(sky==8)
		 {
		 	change=0;
		 }
		 else if(sky==1)
		 {
		 	fen0=read_ds12887(0x02);
			fen0++;
			if(fen0==60)
				fen0=0;
			write_ds12887(0x02,fen0);
			display_time(1);
		 }
		 else if(sky==5)
		 {
		 	fen0=read_ds12887(0x04);
			fen0++;
			if(fen0>=24)
				fen0=0;
			write_ds12887(0x04,fen0);
			display_time(1);
		 }
		 else if(sky==2)
		 {
		 	danjia++;
			write_ds12887(0x30,danjia);
			display_danjia(danjia,0,2);
		 }
		 else if(sky==6)
		 {
		 	if(danjia==0)
				danjia=0;
			else
			    danjia--;
			write_ds12887(0x30,danjia);	
			display_danjia(danjia,0,2);
		 }
		 else if(sky==3)
		 {
		 	qibujia++;
			write_ds12887(0x0e,qibujia);
			display_danjia(qibujia,4,2);
		 }
		 else if(sky==7)
		 {
		 	if(qibujia==0)
				qibujia=0;
			else
			    qibujia--;
			write_ds12887(0x0e,qibujia);	
			display_danjia(qibujia,4,2);
		 }

	}
	if(miao0!=miao1)
	{
		miao0=miao1;
		if(d1==0)
			d1=1;
		else
			d1=0;	
	}
	display_time(d1);
	display_guke(b);	

}

}
void display_time(unsigned char number)
{

unsigned int time,i;
time=read_ds12887(0x04);
i=time%10;
if(number==1)
{

i=0x80+i;
}
write_address(7,i,1);
i=time/10;
write_address(8,i,1);
time=read_ds12887(0x02);
i=time%10;
write_address(5,i,1);
i=time/10;
write_address(6,i,1);
}
void display_danjia(unsigned char danjia,unsigned char address,unsigned char number)
{

unsigned char i,j;
i=danjia;
j=i%10;
//j=j+0x80;
write_address(address+1,j,number);
j=i/10;
j=j%10;
j=j+0x80;
write_address(address+2,j,number);
j=i/100;
j=j%10;
write_address(address+3,j,number);
j=i/1000;
j=j%10;
write_address(address+4,j,number);
}
void close_deng()
{

write_address(1,0×00,1);
write_address(2,0×00,1);
write_address(3,0×00,1);
write_address(4,0×00,1);
}
void display_guke(unsigned int a[])
{

unsigned int sum=0;
if(a[0]!=0)
{

write_address(4,0×81,1);
display_danjia(a[0],4,3);
}
else
{

write_address(4,0,1);
display_danjia(a[0],4,3);
}
if(a[1]!=0)
{

write_address(3,0×82,1);
display_danjia(a[1],4,4);
}
else
{

write_address(3,0,1);
display_danjia(a[1],4,4);
}
if(a[2]!=0)
{

write_address(2,0×83,1);
display_danjia(a[2],0,3);
}
else
{

write_address(2,0,1);
display_danjia(a[2],0,3);
}
if(a[3]!=0)
{

write_address(1,0×84,1);
display_danjia(a[3],0,4);
}
else
{

write_address(1,0,1);
display_danjia(a[3],0,4);
}
}
2.2 按键扫描文件
#ifndef SKYHECHENGCHE
#define SKYHECHENGCHE
//按键初始化

sbit d0=P1^0;
sbit d1=P1^1;
sbit d2=P1^2;
sbit d3=P1^3;
sbit d4=P1^4;
sbit d5=P1^5;
void delaySky(unsigned int k)
{

unsigned int i,j;
for(i=0;i<k;i++)
for(j=0;j<110;j++);
}
unsigned int sky_he()
{

unsigned int returnData=224;
P1|=0x3f;
delaySky(2);
d3=0;
if(d00)
{

delaySky(2);
returnData=0;
while(!d0);
}
if(d1
0)
{

delaySky(2);
returnData=1;
while(!d1);
}
if(d2==0)
{

delaySky(2);
returnData=2;
while(!d2);
}

P1|=0x3f;
delaySky(2);
d4=0;
if(d0==0)
{
	delaySky(2);
	returnData=3;
	while(!d0);	
}
if(d1==0)
{
	delaySky(2);
	returnData=4;
	while(!d1);	
}
if(d2==0)
{
	delaySky(2);
	returnData=5;
	while(!d2);	
}
P1|=0x3f;
delaySky(2);
d5=0;
if(d0==0)
{
	delaySky(2);
	returnData=6;
	while(!d0);	
}
if(d1==0)
{
	delaySky(2);
	returnData=7;
	while(!d1);	
}
if(d2==0)
{
	delaySky(2);
	returnData=8;
	while(!d2);	
}
P1|=0x3f;
return returnData;

}
#endif
2.3 时钟芯片文件
#ifndef ds12887
#define ds12887

sbit dds=P3^7;
sbit drw=P3^6;
sbit dcs=P2^7;
sbit das=P4^5;
//sbit p45=P4SW^5;

void write_ds12887(unsigned char add,unsigned char date)
{

dcs=0;
das=1;
dds=1;
drw=1;
P0=add;
das=0;
drw=0;
P0=date;
das=1;
drw=1;
dcs=1;

}
unsigned char read_ds12887(unsigned char add)
{

unsigned char aa;
dcs=0;
das=1;
drw=1;
dds=1;
P0=add;
das=0;
dds=0;
P0=0xff;
aa=P0;
dcs=1;
das=1;
dds=1;
return aa;
}
void init_ds12887()
{

write_ds12887(0x0a,0x20);
write_ds12887(0x0b,0x26);
}
void set_time()
{

unsigned char i;
for(i=0;i<10;i++)
write_ds12887(i,0);
}
#endif
2.4 MAX7219芯片文件
#ifndef MAX7219
#define MAX7219

//引脚定义
sbit ml1=P2^0;
sbit ml2=P2^1;
sbit ml3=P2^2;
sbit ml4=P2^3;
sbit din=P2^4;
sbit clk=P2^5;
void write_address(unsigned char address,unsigned char data1,unsigned char number)
{

unsigned char i,address1;
address1=address;
if(number1)
{

ml1=0;
ml2=1;
ml3=1;
ml4=1;
}
else if(number
2)
{

ml1=1;
ml2=0;
ml3=1;
ml4=1;
}
else if(number3)
{

ml1=1;
ml2=1;
ml3=0;
ml4=1;
}
else if(number
4)
{

ml1=1;
ml2=1;
ml3=1;
ml4=0;
}
for(i=0;i<8;i++)
{

	clk=0;
	din=(bit)(address1&0x80);
	clk=1;
	address1=address1<<1;
}
address1=data1;
for(i=0;i<8;i++)
{
	clk=0;
	din=(bit)(address1&0x80);
	clk=1;
	address1=address1<<1;
}
if(number==1)
	ml1=1;
else if(number==2)
	ml2=1;
else if(number==3)
	ml3=1;
else if(number==4)
	ml4=1;

}
void init_max7219()
{

unsigned char i;
for(i=1;i<5;i++)
{

write_address(0x0c,0x01,i);
write_address(0x0f,0x00,i);
write_address(0x09,0xff,i);
write_address(0x0b,0x07,i);
write_address(0x0a,0x05,i);
}
}
#endif

DS12887

AD0–AD7 (Multiplexed Bidirectional Address/Data Bus)
Multiplexed buses save pins because address information and data information time-share the same signal paths. The addresses are present during the first portion of the bus cycle and the same pins and signal paths are used for data in the second portion of the cycle. Address/data multiplexing does not slow the access time of the DS12887 since the bus change from address to data occurs during the internal RAM access time. Addresses must be valid prior to the falling edge of AS/ ALE, at which time the DS12887 latches the address from AD0 to AD6. Valid write data must be present and held stable during the latter portion of the DS or WR pulses. In a read cycle the DS12887 outputs 8 bits of data during the latter portion of the DS or RD pulses. The read cycle is terminated and the bus returns to a high impedance state as DS transitions low in the case of Motorola timing or as RD transitions high in the case of Intel timing.
AS (Address Strobe Input)
A positive-going address strobe pulse serves to demultiplex the bus. The falling edge of AS/ALE causes the address to be latched within the DS12887. The next rising edge that occurs on the AS bus will clear the address regardless of whether CS is asserted. Access commands should be sent in pairs.
DS (Data Strobe or Read Input)
The DS/RD pin has two modes of operation depending on the level of the MOT pin. When the MOT pin is connected to VCC, Motorola bus timing is selected. In this mode DS is a positive pulse during the latter portion of the bus cycle and is called Data Strobe. During read cycles, DS signifies the time that the DS12887 is to drive the bidirectional bus. In write cycles the trailing edge of DS causes the DS12887 to latch the written data. When the MOT pin is connected to GND, Intel bus timing is selected. In this mode the DS pin is called Read (RD ).RD identifies the time period when the DS12887 drives the bus with read data. The RD signal is the same definition as the Output Enable (OE ) signal on a typical memory.
R/W (Read/Write Input)
The R/ W pin also has two modes of operation. When the MOT pin isconnected to VCC for Motorola timing, R/ W is at a level which indicates whether the current cycle is aread or write. A read cycle is indicated with a high level on R/ W while DS is high. A write cycle isindicated when R/ W is low during DS.When the MOT pin is connected to GND for Intel timing, the R/ W signal is an active low signal calledWR. In this mode the R/W pin has the same meaning as the Write Enable signal ( WE ) on generic RAMs.
CS (Chip Select Input)
The Chip Select signal must be asserted low for a bus cycle in the DS12887 to be accessed. CS must be kept in the active state during DS and AS for Motorola timing and during RD and WR for Intel timing. Bus cycles which take place without asserting CS will latch addresses but no access will occur. When VCC is below 4.25 volts, the DS12887 internally inhibits access cycles by internally disabling the CS input. This action protects both the real time clock data and RAM data during power outages.
IRQ (Interrupt Request Output)
The IRQ pin is an active low output of the DS12887 that can beused as an interrupt input to a processor. The IRQ output remains low as long as the status bit causing theinterrupt is present and the corresponding interrupt–enable bit is set. To clear the IRQ pin the processorprogram normally reads the C register. The RESET pin also clears pending interrupts.When no interrupt conditions are present, the IRQ level is in the high impedance state. Multipleinterrupting devices can be connected to an IRQ bus. The IRQ bus is an open drain output and requires anexternal pullup resistor.
REGISTER A
UIP
The Update In Progress (UIP) bit is a status flag that can be monitored. When the UIP bit is a 1, the update transfer will soon occur. When UIP is a 0, the update transfer will not occur for at least 244 ms. The time, calendar, and alarm information in RAM is fully available for access when the UIP bit is 0. The UIP bit is read only and is not affected by RESET . Writing the SET bit in Register B to a 1 inhibits any update transfer and clears the UIP status bit.
DV0, DV1, DV2
These 3 bits are used to turn the oscillator on or off and to reset the countdown chain. A pattern of 010 is the only combination of bits that will turn the oscillator on and allow the RTC to keep time. A pattern of 11X will enable the oscillator but holds the countdown chain in reset. The next update will occur at 500 ms after a pattern of 010 is written to DV0, DV1, and DV2.
RS3, RS2, RS1, RS0
These four rate–selection bits select one of the 13 taps on the 15–stage divider or disable the divider output. The tap selected can be used to generate an output square wave (SQW pin) and/or a periodic interrupt. The user can do one of the following:

  1. Enable the interrupt with the PIE bit;
  2. Enable the SQW output pin with the SQWE bit;
  3. Enable both at the same time and the same rate; or
  4. Enable neither.
    REGISTER B
    SET
    When the SET bit is a 0, the update transfer functions normally by advancing the counts once per second. When the SET bit is written to a 1, any update transfer is inhibited and the program can initialize the time and calendar bytes without an update occurring in the midst of initializing. Read cycles can be executed in a similar manner. SET is a read/write bit that is not modified by RESET or internal functions of the DS12887.
    PIE
    The periodic interrupt enable PIE bit is a read/write bit which allows the Periodic Interrupt Flag (PF) bit in Register C to drive the IRQ pin low. When the PIE bit is set to 1, periodic interrupts are generated by driving the IRQ pin low at a rate specified by the RS3–RS0 bits of Register A. A 0 in the PIE bit blocks the IRQ output from being driven by a periodic interrupt, but the Periodic Flag (PF) bit is still set at the periodic rate. PIE is not modified by any internal DS12887 functions, but is cleared to 0 on RESET .
    AIE
    The Alarm Interrupt Enable (AIE) bit is a read/write bit which, when set to a 1, permits the Alarm Flag (AF) bit in Register C to assert IRQ . An alarm interrupt occurs for each second that the three time bytes equal the three alarm bytes including a “don’t care” alarm code of binary 11XXXXXX. When the AIE bit is set to 0, the AF bit does not initiate the IRQ signal. The RESET pin clears AIE to 0. The internal functions of the DS12887 do not affect the AIE bit.
    UIE
    The Update Ended Interrupt Enable (UIE) bit is a read/ write that enables the Update End Flag (UF) bit in Register C to assert IRQ . The RESET pin going low or the SET bit going high clears to UIE bit.
    SQWE
    When the Square Wave Enable (SQWE) bit is set to a 1, a square wave signal at the frequency set by the rate–selection bits RS3 through RS0 is driven out on a SQW pin. When the SQWE bit is set to z0, the SQW pin is held low; the state of SQWE is cleared by the RESET pin. SQWE is a read/write bit.
    DM
    The Data Mode (DM) bit indicates whether time and calendar information is in binary or BCD format.
    The DM bit is set by the program to the appropriate format and can be read as required. This bit is not modified by internal functions or RESET . A 1 in DM signifies binary data while a 0 in DM specifies Binary Coded Decimal (BCD) data.
    24/12
    The 24/12 control bit establishes the format of the hours byte. A 1 indicates the 24–hour mode and a 0 indicates the 12–hour mode. This bit is read/write and is not affected by internal functions of RESET .
    DSE
    The Daylight Savings Enable (DSE) bit is a read/write bit which enables two special updates when DSE is set to 1. On the first Sunday in April the time increments from 1:59:59 AM to 3:00:00 AM. On the last
    Sunday in October when the time first reaches 1:59:59 AM it changes to 1:00:00 AM. These special updates do not occur when the DSE bit is a 0. This bit is not affected by internal functions or RESET .
    TIME, CALENDAR AND ALARM LOCATIONS
    The time and calendar information is obtained by reading the appropriate memory bytes. The time,calendar, and alarm are set or initialized by writing the appropriate RAM bytes. The contents of the 10 time, calendar, and alarm bytes can be either Binary or Binary–Coded Decimal (BCD) format. Before writing the internal time, calendar, and alarm registers, the SET bit in Register B should be written to a logic 1 to prevent updates from occurring while access is being attempted. In addition to writing the 10 time, calendar, and alarm registers in a selected format (binary or BCD), the data mode bit (DM) of Register B must be set to the appropriate logic level. All 10 time, calendar, and alarm bytes must use the same data mode. The set bit in Register B should be cleared after the data mode bit has been written to allow the real time clock to update the time and calendar bytes. Once initialized, the real time clock makes all updates in the selected mode. The data mode cannot be changed without reinitializing the 10 data bytes. Table 2 shows the binary and BCD formats of the 10 time, calendar, and alarm locations. The 24–12 bit cannot be changed without reinitializing the hour locations. When the 12–hour format is selected, the high order bit of the hours byte represents PM when it is a logic 1. The time, calendar, and alarm bytes are always accessible because they are double buffered. Once per second the 10 bytes are advanced by 1 second and checked for an alarm condition. If a read of the time and calendar data occurs during an update, a problem exists where seconds, minutes, hours, etc. may not correlate. The probability of reading incorrect time and calendar data is low. Several methods of avoiding any possible incorrect time and calendar reads are covered later in this text.
    The three alarm bytes can be used in two ways. First, when the alarm time is written in the appropriate hours, minutes, and seconds alarm locations, the alarm interrupt is initiated at the specified time each day if the alarm enable bit is high. The second use condition is to insert a “don’t care” state in one or more of the three alarm bytes. The “don’t care” code is any hexadecimal value from C0 to FF. The two most significant bits of each byte set the “don’t care” condition when at logic 1. An alarm will be generated each hour when the “don’t care” bits are set in the hours byte. Similarly, an alarm is generated every minute with “don’t care” codes in the hours and minute alarm bytes. The “don’t care” codes in all three alarm bytes create an interrupt every second.
    NONVOLATILE RAM
    The 114 general purpose nonvolatile RAM bytes are not dedicated to any special function within the DS12887. They can be used by the processor program as nonvolatile memory and are fully available during the update cycle.

From:Translated text as part of the DS12887 data I find in the original manufacturer’s official website DS12887.

DS12887
AD0〜AD7(双向复用地址/数据总线)。复用总线节约引脚,因为 地址信息和数据信息的时间共享相同的信号路径。地址存在 总线周期和相同的引脚和信号路径的第一部分期间在第二用于数据 循环的一部分。地址/数据复用不慢,因为访问的DS12887的时间 在内部RAM的访问时间从地址总线改变数据时。地址必须是有效的 之前,AS / ALE,而在此时,DS12887锁存从AD0的地址AD6的下降沿。 有效的写数据必须存在,并且在DS或WR脉冲后部分保持稳定。在 读周期的DS12887在DS或RD脉冲后部分输出8位数据。读 周期终止,总线返回到高阻抗状态,DS变低的情况下 摩托罗拉的时间或RD变高在英特尔的时间的情况下。
AS(地址选通输入) – 一个正向地址选通脉冲旨在解复用总线。该 AS / ALE的下降沿导致地址被该DS12887内部锁存。发生在AS总线上的下一个上升沿将清除地址不论CS是否有效。访问命令被发送。
DS(数据选通或读输入)- 在DS/ RD引脚有两种操作取决于水平模式 的MOT引脚。当MOT引脚连接到VCC,摩托罗拉总线时机选择。在此模式下 DS是在总线周期的后面部分提供一个正脉冲,称为数据选通。在读 周期,DS表示该DS12887是推动双向总线的时间。在写周期的结尾 DS的上升沿使DS12887锁存写入的数据。当MOT引脚连接到GND,英特尔 总线时机选择。在这种模式下,DS端子被称为读(RD)。道标识的时间段时 该DS12887驱动总线读取数据。在一个典型的存储器,RD信号有相同的定义,即输出使能(OE)信号。
R / W(读/写输入) – R / W引脚也有两种操作模式。当MOT引脚 连接到VCC为摩托罗拉时机,R / W是在一定的水平,指示当前周期是 读或写。一个读周期是表示有高度上的读/写,而DS高。写周期是 当R/ W为低的DS时表示。 当MOT引脚连接到GND为英特尔时机,R / W信号为低电平信号,称为 WR。在这种模式下,R / W引脚具有相同的含义写使能信号(WE)在通用的RAM。
CS(片选输入) – 片选信号必须置低一个总线周期的DS12887到 被访问。 CS必须保持在激活状态时的DS和AS摩托罗拉时机和RD时 和WR为英特尔的时机。总线周期而发生不主张CS将锁存地址,但没有 会发生访问。当VCC低于4.25伏,DS12887内部由抑制存取周期 在内部禁用CS输入。在这个动作保护实时时钟和数据RAM中的数据既停电。
IRQ(中断请求输出)- 该IRQ引脚是DS12887,可以是一个低电平有效输出 用作中断输入到处理器。该IRQ输出仍然很低,只要状态位造成的 中断是当前和相应的中断使能位被置位。要清除IRQ引脚的处理器 程序正常读取C寄存器。 RESET引脚也清除挂起中断。 当没有中断条件都存在,IRQ水平处于高阻抗状态。多种 中断设备可以连接到一个IRQ总线。该IRQ总线是一个开漏输出,需要一个 外部上拉电阻。
寄存器B
UIP
更新进行中(UIP)位是可以监控的状态标志。当UIP位是1,则很快就会出现更新传输。当UIP是0,更新转移不会发生,至少244毫秒。时间,日历和RAM中的报警信息是完全可​​供访问时UIP位为0的UIP位是只读的,并且不受复位的影响。写在寄存器B的SET位到1抑制任何更新转移和清除UIP状态位。
DV0,DV1,DV2
这些3位被用来打开振荡器或关闭和重置倒计时链。 010模式是位,将打开振荡器,并允许RTC保持时间的唯一组合。的模式11X将使振荡器,但拥有倒计时链在复位状态。将发生在500的下一个更新010模式ms后写入DV0,DV1,DV2和。
RS3,RS2,RS1,RS0
这些四个速率选择位用于选择13水龙头上的15级分频器的一个或禁用分频器输出。所选择的抽头可以被用来产生输出方波(SQW引脚)和/或周期性的中断。用户可以执行下列操作之一:
1,启用与PIE的位中断;
2,启用SQW输出引脚SQWE位;
3,在相同的时间和相同的速度同时启用;或
4,启用两者都不是。
寄存器B
SET
当SET位是0,则更新传递函数通常以每秒行进的计数一次。当SET位被写入1,任何更新转移抑制和程序可以初始化时间和日历字节没有在初始化之中发生的更新。读周期可以被执行以类似的方式。 SET是不是由复位或内部功能修改的读/写位DS12887。
PIE
周期性的中断使能PIE位是读/写位,它允许周期中断标志(PF)位在寄存器C驱动IRQ引脚为低电平。当PIE位被设置为1,是将产生的周期性的中断驱动IRQ引脚为低电平时由寄存器A A 0的RS3-RS0位在PIE位块中指定的速度从推动着一个周期性的中断输出的IRQ,但定期标志(PF)位仍设置在定期利率。 PIE不受任何内部DS12887的功能修改,但被清零复位。
AIE
报警中断允许(AIE)位是读/写位,当设置为1,允许报警标志在寄存器C(AF)位断言IRQ。报警中断发生的每一秒,这三个时间字节等于三个报警字节,包括一个“不关心”报警二进制11XXXXXX的代码。当AIE位被设置为0时,AF位不启动IRQ信号。 RESET引脚清除AIE到0。内部该DS12887的功能不影响AIE位。
UIE
结束中断使能(UIE)位的更新是一个读/写,使在更新结束标志(UF)位寄存器C断言IRQ。 RESET引脚变低或设置位要高,以清零UIE位。
SQWE
当方波使能(SQWE)位被设置为1,一个方波信号的频率由设速率选择位通过RS3 RS0被赶出在SQW引脚。当SQWE位被设置为Z0,则SQW引脚保持低电平; SQWE的状态是由RESET引脚清零。 SQWE是一个读/写位。
DM
数据模式(DM)的位表示时间和日历信息是二进制或BCD格式。的DM位由程序设置为适当的格式,可以根据需要进行阅读。此位不通过内部函数或复位修改。在DM A 1表示二进制数据,而一个0在DM指定二进制编码的十进制(BCD)的数据。
24/12
在24/12控制位确定了时间字节的格式。值为1表示24小时模式和0表示12小时模式。该位是读/写,并不受复位的内部功能。
DSE
夏令启用(DSE)位是读/写位使两个特殊的更新时DSE设置为1,在第一星期天到4月从上午1时59分59秒至上午03时00分00秒的时间增量。在最后星期天在10月份的时候1:59:59 AM跳回它的变化1:00:00 PM。当DSE位是0,该位不会受到内部功能或复位的更新不会发生。
时间,日历和报警地址
通过读取相应的内存字节获得的时间和日历信息。时间,日历和闹钟设置或初始化,通过写相应的内存字节。在10中的内容时间,日历和闹钟字节可以是二进制或二进制编码的十进制(BCD)格式。前写内部时间,日历和报警寄存器,寄存器B的SET位应写入逻辑1,以防止访问时正在尝试发生更新。除了撰写了10时间,日历,并在选定的格式(二进制或BCD)的数据模式位(DM)的,报警寄存器寄存器B必须被设置到适当的逻辑电平。所有10时间,日历和闹钟字节必须使用相同的数据模式。后的数据模式位已写入的寄存器B组位应清零允许实时时钟来更新时间和日历字节。初始化后,实时时钟使得在所选择的模式的所有更新。数据模式不能没有重新初始化10变字节的数据。表2示出的10个时间,日历和报警位置的二进制和BCD格式。该24-12位不能没有重新初始化小时的位置改变。当12小时格式选中,小时字节的高位表示PM当它是一个逻辑1,时间,日历和报警字节总是可用,因为它们是双缓冲。每秒一次的10个字节是前进1秒,并检查报警条件。如果发生的时间和日历数据的读取在更新过程中,存在问题的地方秒,分钟,小时等可能不相关。概率
读数不正确的时间和日历数据低。避免任何可能的不正确的几种方法时间和日历读取该文本后面都包括在内。
这三个报警字节可以通过两种方式使用。首先,当报警时间写入相应 小时,分钟和秒报警位置,报警中断的每一天开始在指定的时间 如果报警使能位为高。第二使用条件,是在一个或多个插入一个“不关心”状态 这三个报警字节。 “不关心”的代码是任何十六进制值从C0到FF。两个最 每个字节的显著位设置了“不关心”状态时为逻辑1。报警将产生 当“不关心”位在小时字节设置每个小时。同样,一个报警产生的每 分钟与“不关心”代码小时和分钟报警字节。在所有这三个“不关心”代码 报警字节创建一个中断每一秒。
非易失性RAM
114通用非易失性RAM字节不是专用于DS12887内的任何特殊功能 。它们可用于由处理器程序作为非易失性存储器并且是完全可用在更新周期。

From:翻译原文为我在DS12887生产商官网查找的DS12887资料原文的一部分。
天津城建大学
毕 业 设 计 任 务 书

计 算 机 与 信 息 工 程 学 院 电 子 信 息 工 程 专 业 1 班
姓 名 杨 亮 学 号 10700121

设计题目: 数码管显示的合乘出租车计价器设计
完成期限:自 2014 年 2 月 24 日至 2014 年 6 月 13 日止

指 导 教 师: 刘 毅
教研室/系主任:
院 长: 学 生 签 字 :
批 准 日 期: 2013.12.20 接受任务日期: 2013.12.27
一、设计原始依据(资料):
[1].STC12C5A60S2系列单片机器件手册,http://www.stcmcu.com/index.htm.
[2].张毅刚.单片机原理及应用,高等教育出版社,2006.
[3].李华,MCS-51系列单片机实用接口技术,北京航空航天大学出版社,1993.
[4].何立民,单片机应用系统设计,北京航空航天大学出版社,1990.
[5].高鹏、安涛等,电路设计与制版Protel99入门与提高,人民邮电出版社,2000.
[6].陈勇,DS12887实时时钟芯片及其应用,电子世界,1998, 2: 39-40.
[7].MAX7219显示驱动芯片资料.
[8].计价器相关资料.

二、设计内容和要求:(说明书、专题、绘图、试验结果等)

设计内容:
设计一种用于合乘计费的出租车计价器。能够独立实现每位乘客的行驶里程计算、低速计时时间累计、乘客付费金额计算。
设计要求单片机作为控制核心,外部扩展数码管显示单元、按键处理单元、方波检测处理单元、历史数据记录等电路。在所设计的软件程序下,能够实现计费、显示、查询等功能。

设计要求:

  1. 阅读课题相关中外文资料、论文不少于十篇(外文至少一篇)。
  2. 不少于20000英文字符(3000汉字)外文资料翻译一篇。
  3. 完成2万字以上设计说明书文档一份。论文中包括,任务书、开题报告、摘要、绪论方案设计及工作原理、芯片选择和应用、硬件设计说明、软件编程及调试说明、运行结果与分析、参考文献、致谢等内容(详细参见毕业论文格式)。要求论文结构合理、叙述清晰、语句通顺、图纸图表规范,符合毕业设计论文格式要求。
  4. 完整电路设计原理图(附录中)。
  5. 完成基本程序设计,在实验板上进行程序的运行试验(程序附在附录中)。
  6. 以上内容电子文档备份一套。

设计(研究)进度计划表
序号 起止日期 计划完成内容 实际完成情况 检查人签名检查日期
1
3月24日至4月6日 确定并熟悉自己毕业设计的题目及其要求。
2
4月7日至4月13日 分析本次设计的主要目的并将其分为由不同的功能共同实现,最后选择实现各个功能的芯片。
3
4月14日至4月20日 根据本次设计要实现的功能设计其硬件原理图。

4
4月21日至5月18日 拿到自己的硬件电路,开始编写程序并调试来实现本次设计的功能。

5

5月19日至5月25日 完善自己的设计,最后确定自己的硬件电路及程序编写无误,使本次设计成品的运行结果达到本次设计的要求甚至完美。
6

5月26日至6月1日 根据自己的设计内容及设计要求开始写毕业论文。

7

6月2日至6月8日 最后一次确认自己的设计成品和报告已经完成,不需要改动。

8
指导教师批准,并签名: 年 月 日

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/186212.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号