武汉科技大学51单片机实现简易计算器.docx

上传人:b****7 文档编号:11246781 上传时间:2023-02-26 格式:DOCX 页数:45 大小:1.50MB
下载 相关 举报
武汉科技大学51单片机实现简易计算器.docx_第1页
第1页 / 共45页
武汉科技大学51单片机实现简易计算器.docx_第2页
第2页 / 共45页
武汉科技大学51单片机实现简易计算器.docx_第3页
第3页 / 共45页
武汉科技大学51单片机实现简易计算器.docx_第4页
第4页 / 共45页
武汉科技大学51单片机实现简易计算器.docx_第5页
第5页 / 共45页
点击查看更多>>
下载资源
资源描述

武汉科技大学51单片机实现简易计算器.docx

《武汉科技大学51单片机实现简易计算器.docx》由会员分享,可在线阅读,更多相关《武汉科技大学51单片机实现简易计算器.docx(45页珍藏版)》请在冰豆网上搜索。

武汉科技大学51单片机实现简易计算器.docx

武汉科技大学51单片机实现简易计算器

二○一六~二○一七学年第一学期

信息科学与工程学院

电子技术综合设计

(二)

课程设计报告

 

班级:

电信1401班

姓名:

程赐项志雄

学号:

************************

******

 

二○一六年十二月一日

 

一、实验要求

利用普中科技HC6800-ESV2.0单片机开发板设计一款带蜂鸣器的电子计算器。

主要使用开发板上的数码管、LED点阵、矩阵键盘、蜂鸣器等模块功能。

开发板配有光盘,里面有各个模块的使用说明和程序范例可供参考。

1)每2位同学分工协作。

2)上电开机或者复位键按下之后,2个4位数码管分别自动显示2个同学学号的后4位。

3)定义矩阵键盘的S1-S9代表数字按键1-9,键盘S10代表数字按键0,键盘S11-S16分别代表按键+、-、×、÷、=、C,其中C按键为计算器清零按键,按下C键计算器开始新的计算。

4)计算器计算过程中,用LED点阵显示+、-、×、÷运算符号,用8位数码管显示键入的数字和运算的结果。

键入时依次显示并自动移位,例如18+9=27,先键入1,显示1,再键入8,1自动左移一位显示18,键入+,LED点阵显示+,键入9,数码管之前显示的18消失并重新显示为9,键入=,数码管显示运算结果27。

5)为这16个矩阵键盘的按键分配不同的蜂鸣器频率,使得按下不同的按键蜂鸣器响声不同,便于识别按键。

6)按键应具有一定的消除抖动功能。

7)所有单片机程序代码都用C语言编写,并烧写到单片机中上电自动运行。

二、设计思想

程序流程图:

三、实验原理

1.单片机概述

当今时代,是一个新技术层出不穷的时代。

在电子领域,尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统正以前所未见的速度被单片机智能控制系统所取代。

单片机具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。

目前,一个学习与应用单片机的高潮正在工厂、学校及企事业单位大规模地兴起。

过去习惯于传统电子领域的工程师、技术员正面临着全新的挑战,如不能在较短时间内学会单片机,势必会被时代所遗弃,只有勇敢地面对现实,挑战自我,加强学习,争取在较短的时间内将单片机技术融会贯通,才能跟上时代的步伐。

它所给人带来的方便也是不可否定的,它在一块芯片内集成了计算机的各种功能部件,构成一种单片式的微型计算机。

20世纪80年代以来,国际上单片机的发展迅速,其产品之多令人目不暇接,单片机应用不断深入,新技术层出不穷。

20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。

所以学好单片机更加有利于我们大学生更好地了解电子控制方面的知识。

2.单片机最小系统

单片机最小系统为什么称之为单片机最小系统呢?

单片机最小系统,也叫做单片机最小应用系统,是指用最少的原件组成单片机可以工作的系统。

单片机最小系统的三要素就是电源、晶振、复位电路。

(1)电源

这个很好理解,电子设备都需要供电,就连我们的家用电器(手电筒^_^)也不例外。

主流单片机的电源现在是5V和3.3V这两个标准,当然现在还有对电压要求更低的单片机系统。

我们所学的STC89C52RC,它需要5V的供电系统,我们的开发板是使用USB口出来的5V直流电压直接供电的。

从图中可以看到,供电电路在40脚和20脚的位置上,40脚接的是VCC,代表的是电源正极,20脚接的是GND,代表的是电源的负极。

这个地方我们还要普及一个看原理图的知识。

电路原理图是为了表达这个电路的工作原理而存在的,很多器件在绘制的时候更多考虑是方便分析原理,不是表达各个器件实际位置的。

比如上边的单片机引脚图,引脚的位置我们是可以随意放的,但是每个引脚上有一个引脚标号(在表示芯片的方框的内部),这个引脚标号代表的才是单片机真正的引脚位置,如上图,一般情况下,这种双列直插的封装的芯片,左上角是1脚,逆时针旋转引脚号依次增加,一直到右上角是最大脚位,咱们现在选用的单片机一共40个引脚,因此右上角就是40。

(2)晶振

晶振,又叫晶体振荡器,从这个名字我们就可以看出来,它注定一生都要不停振动的。

他起到的作用是为单片机系统提供基准时钟信号,类似于我们部队训练时喊口令的人,单片机内部所有的工作都是以这个时钟信号为步调基准来进行工作的。

STC89C52RC单片机的18脚和19脚是晶振的引脚,我们接了一个11.0592M的晶振(它每秒钟震荡11,059,200次),外加两个20pF的电容,电容的作用是帮助晶振起振,并维持震荡信号的稳定。

(3)复位电路

如图是一个复位电路,接到了单片机的9脚RST(Reset)复位引脚上,这个复位电路如何起到的作用我们后边再讲,现在着重讲一下复位对单片机的作用。

单片机复位一般是3种情况,上电复位、手动复位、程序自动复位。

我们假如我们的单片机程序有100行,当某一次运行到第50行的时候,突然停电了,这个时候单片机内部有的区域数据会丢失掉,有的区域数据没丢失,那么下次打开设备的时候,我们希望单片机能正常运行。

所以上电后,单片机要进行一个内部的初始化过程,这个过程就可以理解为上电复位,上电复位保证单片机每次都从一个固定的相同的状态开始工作。

这个过程跟我们打开电脑电源开电脑的过程是一致的。

当我们的程序运行,遭受到意外干扰而导致程序死机,或者程序跑飞的时候,我们就可

以按下一个复位按键,让程序重新初始化重新运行,这个过程就叫做手动复位,最典型的就是我们电脑的重启按钮。

当我们的程序死机或者跑飞的时候,我们的单片机往往有一套自动复位机制,比如看门狗,具体应用以后再了解。

在这种情况下,如果程序长时间失去响应,单片机看门狗模块会自动复位重启单片机。

还有一些情况是我们程序故意重启复位单片机。

电源、晶振、复位构成了单片机最小系统的三要素,也就是说,一个单片机具备了这三个条件,就可以运行我们下载的程序了,其他的比如LED小灯、数码管、液晶等设备都是属于单片机的外设,我们最终完成我们想要的功能就是通过对单片机编程来控制这些外设实现的。

3.矩阵键盘

(1)机械按键的特点

绝大多数情况下,我们按按键是不能一直按住的,所以我们通常是判断按键从按下到弹起两种状态发生变化了,就认为是有按键按下。

程序上,我们可以把每次按键状态都存储起来,当下一次按键状态读进来的时候,与当前按键状态做比较,如果发现这两次按键状态不一致,就说明按键发生动作了,当上一次的状态是未按下、现在是按下,此时的按键动作就是“按下”;当上一次的状态是按下、现在是未按下,此时的按键动作就是“弹起”。

显然,每次按键动作都会包含一次“按下”动作和一次“弹起”动作,我们可以任选一个动作来执行程序,或者两个都用以执行不同的程序

也是可以的。

(2)矩阵键盘

由给的开发板的电路图来看,矩阵键盘是由P1口来控制的,每一位控制一行或者一列。

行线P10~P13为输出线,列线P14~P17为输入线。

一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。

延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下。

最后一步确定键值。

现在我们以第二行的S5键为例,若按下S5后我们应该怎么得到这个键值呢?

当判断确实有键按下之后,行线轮流输出低电平,根据读入列线的数据可以确定键值。

首先,单片机将P10输出为低电平,其它P11~P13输出高电平,此时读取列线的数据全为高电平,说明没有在第一行有键按下;其次,单片机将P11输出低电平,其它P10、P12、P13仍为高电平,此时再来读取列线数据,发现列线读到的数据有低电平,数值为1011(0x0B),如果我们的键盘布局已经确定,那么0x0B就代表S5的值了。

转到S5键功能处理子程序就可以达到目的。

综上所述,可以写出这部分的代码:

(定义P1口为GPIO_KEY)

/*....................读取按键的位置....................*/

voidKeyDown(void)

{

charw=0;

GPIO_KEY=0x0f;

if(GPIO_KEY!

=0x0f)//读取按键是否按下

{

Delay10ms

(1);//延时10ms进行消抖

if(GPIO_KEY!

=0x0f)//再次检测键盘是否按下

{

//测试行

GPIO_KEY=0XF0;

switch(GPIO_KEY)

{

case(0X70):

KeyValue=0;break;

case(0Xb0):

KeyValue=4;break;

case(0Xd0):

KeyValue=8;break;

case(0Xe0):

KeyValue=12;break;

}

//测试列

GPIO_KEY=0X0F;

switch(GPIO_KEY)

{

case(0X07):

KeyValue=KeyValue+1;break;

case(0X0b):

{

KeyValue=KeyValue+2;

if(KeyValue==10)

{

KeyValue=0;

}

}break;

case(0X0d):

KeyValue=KeyValue+3;break;

case(0X0e):

KeyValue=KeyValue+4;break;

}

while((w<20)&&(GPIO_KEY!

=0xf0))//检测按键松手检测

{

Delay10ms

(1);

w++;

}

}

}

}

4.数码管

(1)数码管的基本介绍

先将一张原理图看一下,如下图所示

这是比较常见的数码管的原理图,我们板子上一共有8只数码管。

从图5-2能看出来,数码管共有a,b,c,d,e,f,g,dp这8个段,而实际上,这8个段每一段都是一个LED小灯,所以数码管就是由8个LED小灯所组成的。

我们看一下数码管内部结构图5-3。

数码管分为共阳数码管和共阴数码管,所谓的共阴数码管就是8只LED小灯的阴极是接在一起的,也就是阴极是公共端,由阳极来控制小灯是否亮灭。

同理,共阳数码管就是阳极是接到一起的,我们可以仔细研究下图5-3。

我们会发现,数码管上边有2个com,实际上就是我们数码管的公共端。

为什么有2个,我个人认为,一方面有2个可以起到对称的效果,刚好是10个引脚,另外一个方面,公共端通过的电流较大,我们初中就学过并联电路电流之和等于总电流,用2个com可以把公共电流平均到2个引脚上去,降低线路承受的电流。

根据以上知识,我们可以写出数码管亮的数字的断码(数码管的真值表),我们用一个数组表示:

#defineGPIO_DIGP0

unsignedcharcodeDIG_CODE[17]={

0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x3f,0x7c,0x39,0x5e,0x79,0x71};

//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码

(2)数码管的控制

由上图可以看出P0控制数码管的段选,LED1到LED8控制数码管的位选端。

我们在电路图中找到相应的部分。

138译码器在数电学过,这里不做过多介绍。

可以看出是由P2.2,P2.3,P2.4这三个端口控制的,为此我们只要相应的赋值就能指定某一位数码管的亮灭。

(3)数码管的动态显示

a.动态显示的基本原理

我们在上面学习数码管静态显示的时候说到,74HC138只能在同一时刻导通一个三极管,而我们的数码管是靠了8个端口来控制,那我们如何来让数码管同时显示呢?

这就用到动态显示。

多个数码管显示数字的时候,我们实际上是轮流点亮数码管(一个时刻内只有一个数码管是亮的),利用人眼的视觉暂留现象(也叫余辉效应),就可以做到看起来是所有数码管都同时亮了,这就是动态扫描显示的含义。

例如:

我们有2个数码管,我们要显示“12”这个数字,让高位的位选端导通,然后给它赋值“1”,延时一定时间后让低位的位选三极管导通,然后给它赋值“2”。

把这个流程以一定的速度循环运行就可以让数码管显示出“12”,由于交替速度非常快,人肉眼识别到的就是“12”这个数字。

那么一个数码管需要点亮多长时间呢?

也就是说要多长时间完成一次全部数码管的扫描呢(很明显:

整体扫描时间=单个数码管点亮时间*数码管个数)?

答案是:

10ms以内。

当电视机和显示器还处在CRT(电子显像管)时代时,有一句很流行的广告语——“100Hz无闪烁”,没错,只要刷新率大于100Hz,即刷新时间小于10ms,就可以做到无闪烁,这也就是我们的动态扫描的硬性指标。

那么你也许会问,有最小值的限制吗?

理论上没有,但实际上做到更快的刷新却没有任何进步的意义了,因为已经无闪烁了,再快也还是无闪烁,只是徒然增加CPU的负荷而已(因为1秒内要执行更多次的扫描程序)。

所以,通常我们设计程序的时候,都是取一个接近10ms,又比较规整的值就行了。

b.数码管的消影问题

在实验的过程中会发现,我们的两次数码管动态刷新显示的时候似乎并不是那么完美,第一个小问题,发现数码管的不应该显示的段,似乎有微微的发亮,这种现象叫做“鬼影”,这个“鬼影”严重影响了我们的视觉效果,我们该如何解决呢?

“鬼影”的出现,主要是因为我们数码管位选和段选产生的瞬态所造成的。

举个简单例子,我们在数码管动态刷新的那部分程序中,实际上每一个数码管点亮的持续时间是1ms的时间,1ms后进行下个数码管的切换。

在进行数码管切换的时候,我们的P0还没有正式赋值,而P0此刻却保持了前一次的值,所以会产生鬼影。

弄懂原理之后就很好解决了。

我们只要避开这个瞬态就可以了。

产生瞬态的方法是,我们在进行刷新的赋值语句期间,避免一切数码管的赋值即可。

方法有两个,一个方法是刷新之前关闭所有的段,改变好了位选后,再打开段即可;第二个方法是关闭数码管的位,赋值过程都做好后,再重新打开即可。

这里我们选择第一个方法,因为138译码器的输出一定会有一个结果,无法选择第二个方法。

关闭段:

在选择数码管的位选端之前,加一句P0=0;这样就把数码管所有的段都关闭了,程序写好后,再给P0赋对应的值即可。

这里我写了两个数码管显示的程序,一个是动态实时显示按键按下的值,另一个是显示结果和学号这种知道结果的数字,相关程序如下:

/*....................数码管显示键值....................*/

voidDis_play(intn,unsignedcharnum)

{

P2=n<<2;

P0=DIG_CODE[num];

}

/*....................显示动态数码管....................*/

voiddisplay(intu,longintvalue)//u表示数字位数,value表示值

{

inti,v,h;

inta[8];//用于存放每位的的数字

v=value;

for(i=1;i

a[i]=v%10;

v=v/10;

}

for(i=1;i

{

GPIO_DIG=DIG_CODE[a[i]];

P2=P2table[i-1];

h=500;

while(h--);//延时

P0=0;//消影

}

}

5.LED点阵

电路部分找到如下:

可以看到这个8*8的点阵是由P0接口和D0-D7口控制的,我们找到相应的接口:

(1)74HC595

通过搜寻74HC595的技术手册,可以找到如下资料:

74HC595的引脚功能:

74595的数据端:

Q0--Q7:

八位并行输出端,可以直接控制数码管的8个段。

Q7':

 级联输出端。

将它接下一个595的DS端。

DS:

 串行数据输入端,级联的话接上一级的Q7'。

74595的控制端说明:

/MR(10脚):

低电平时将移位寄存器的数据清零。

通常我将它接Vcc。

SH_CP(11脚):

上升沿时数据寄存器的数据移位。

Q0->Q1->Q2-->Q3-->...-->Q7;下降沿移位寄存器数据不变。

(脉冲宽度:

5V时,大于几十纳秒就行了。

我通常都选微秒级)

ST_CP(12脚):

上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。

通常我将ST_CP置为低电平,当移位结束后,在ST_CP端产生一个正脉冲(5V时,大于几十纳秒就行了。

我通常都选微秒级),更新显示数据。

/OE(13脚):

高电平时禁止输出(高阻态)。

如果单片机的引脚不紧张,用一个引脚控制它,可以方便地产生闪烁和熄灭效果。

比通过数据端移位控制要省时省力。

74HC595的内部结构:

第一层为移位D触发器;

第二层为锁存D触发器;

第三层为输出3态门;

74HC595的时序图:

1)74164和74595功能相仿,都是8位串行输入转并行输出移位寄存器。

74164的驱动电流(25mA)比74595(35mA)的要小,14脚封装,体积也小一些。

2)74595的主要优点是具有数据存储寄存器,在移位的过程中,输出端的数据可以保持不变。

这在串行速度慢的场合很有用处,数码管没有闪烁感。

3)595是串入并出带有锁存功能移位寄存器,它的使用方法很简单,如下面的真值表,在正常使用时ST_CP为低电平,/OE为低电平。

从DS每输入一位数据,串行输入时钟SH_CP上升沿有效一次,直到八位数据输入完毕,输出时钟ST_CP上升沿有效一次,此时,输入的数据就被送到了输出端。

595具体使用的步骤:

第一步:

目的:

将要准备输入的位数据移入74HC595数据输入端上。

方法:

送位数据到_595。

第二步:

目的:

将位数据逐位移入74HC595,即数据串入

方法:

SH_CP产生一上升沿,将DS上的数据移入74HC595移位寄存器中,先送高位,后送低位。

第三步:

目的:

并行输出数据。

即数据并出。

方法:

ST_CP产生一上升沿,将由DS上已移入数据寄存器中的数据送入到输出锁存器。

相关程序如下:

/*....................向74HC595发送8位串行数据....................*/

voidHC595SendData(ucharBT)

{

uchari;

//--发送一个字节--//

for(i=0;i<8;i++)

{

MOSIO=BT>>7;//从高位到低位

BT<<=1;

S_CLK=0;

S_CLK=1;

}

//--输出--//

R_CLK=0;//setdatalinelow

R_CLK=1;//片选

R_CLK=0;//setdatalinelow

}

(2)点阵

点阵LED内部原理图如图7-2所示,从7-2图上可以看出来,其实点阵LED点亮原理还是很简单的。

在我们图上蓝色方框外侧的就是点阵LED的引脚号,左侧的8个引脚是接的内部LED的阳极,上侧的8个引脚接的是内部LED的阴极。

那从图上可以看出来,我们的9脚如果是高电平,13脚是低电平的话,最左上角的那个LED小灯就会亮,因此我们可以控制任意一个点的亮灭。

为此我们应该先将我们要亮的符号提前定义好等待发送:

//=号

unsignedcharcodetab5[]={36,36,36,36,36,36,36,36};

//+号

unsignedcharcodetab1[]={8,8,8,255,8,8,8,8};

unsignedcharcodetab[]={127,191,223,239,247,251,253,254};//P0口控制一列

//-号

unsignedcharcodetab2[]={8,8,8,8,8,8,8,8};

//除号

unsignedcharcodetab4[]={8,8,8,42,8,8,8,8};

//×号

unsignedcharcodetab3[]={129,66,36,24,24,36,66,129};

显示点阵的程序:

*....................显示点阵....................*/

voiddisplayd(inta)

{

switch(a)

{

case

(1):

{intk;

for(k=0;k<8;k++)

{

P0=0xff;

HC595SendData(tab1[k]);

P0=tab[k];

}

}break;

case

(2):

{intk;

for(k=0;k<8;k++)

{

P0=0xff;

HC595SendData(tab2[k]);

P0=tab[k];

}

}break;

case(3):

{intk;

for(k=0;k<8;k++)

{

P0=0xff;

HC595SendData(tab3[k]);

P0=tab[k];

}

}break;

case(4):

{intk;

for(k=0;k<8;k++)

{

P0=0xff;

HC595SendData(tab4[k]);

P0=tab[k];

}

}break;

case(5):

{intk;

for(k=0;k<8;k++)

{

P0=0xff;

HC595SendData(tab5[k]);

P0=tab[k];

}

}break;

}

}

6.蜂鸣器

找到BZ对应的端口:

发现BZ是由P1.5口控制的。

蜂鸣器分为无源蜂鸣器和有源蜂鸣器。

无源内部不带震荡源,所以如果用直流信号无法令其鸣叫,必须用2K-5K的方波去驱动它,这里我们用的是无源蜂鸣器。

相关程序:

voidBeep(int

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 环境科学食品科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1