工业控制 | 能源技术 | 汽车电子 | 通信网络 | 安防监控 | 智能电网 | 移动手持 | 无线技术 | 家用电器 | 数字广播 | 消费电子 | 应用软件 | 其他方案

2位LED显示单片机计算器

作者:dolphin时间:2011-04-21浏览次数:5855

一、设计要求

1.设计4*4的键盘,其中10个数字键0~9,其余6个为“+” “-” “*”“/” “=”和“C”

2.设计2位LED接口电路

3.实现1位数的简单运算

二、硬件系统设计

1、LED接口电路

简易计算器需要2位8段码LED显示电路。用8031单片机经8255A扩展2位8段码LED显示器,用8255A的A口作为段码(字形代码)数据口,PB0和PB1作为位控制端口。在位控制口加集电极开路的反相高压驱动器74LS06以提供驱动LED显示器所需的足够大的电流,然后接至各数码显示器的共阴极端。同理,在段码数据口集电极开路的正相高压驱动器74LS07提供足够大的电流,然后接到数码显示器的各段。逻辑电路结构如下:

2、键盘接口电路

简易计算器需要4*4的行列式键盘。用8031单片机经8255A扩展4*4行列式键盘,8255A的B口和C口用于扩展键盘接口,B口高4位作为输出口,C口低4位作为输入口。逻辑电路结构如下:


3、计算器逻辑电路图

将LED接口电路和键盘接口电路结合到一起就是简易计算器的逻辑电路图,如下:


三、软件设计

1、LED显示程序设计

LED显示器由七段发光二极管组成,排列成8字形状,因此也成为七段LED显示器,器排列形状如下图所示:

为了显示数字或符号,要为LED显示器提供代码,即字形代码。七段发光二极管,再加上一个小数点位,共计8段,因此提供的字形代码的长度正好是一个字节。简易计算器用到的数字0~9的共阴极字形代码如下表:

0~9七段数码管共阴级字形代码

2位LED显示的程序框图如下:


2、读键输入程序设计

为了实现键盘的数据输入功能和命令处理功能,每个键都有其处理子程序,为此每个键都对应一个码――键码。为了得到被按键的键码,现使用行扫描法识别按键。其程序框图如下:


3、主程序设计

(1)数值送显示缓冲程序设计

简易计算器所显示的数值最大位两位。要显示数值,先判断数值正负,如果是负值,则符号位显示“-”,然后将数值除以10,余数送显最最低位,判断商是否为0,若为0则返回,若不为0,则将商除以10,将余数送显高位。程序框图如下:


(2)运算主程序设计

首先初始化参数,送LED低位显示“0”,高位不显示。然后扫描键盘看是否有键输入,若有,读取键码。判断键码是数字键、清零键还是功能键(“+”“-”“*”“/”“=” ),是数值键则送LED显示并保存数值,是清零键则做清零处理,是功能键则又判断是“=”还是运算键,若是“=”则计算最后结果并送LED显示,若是运算键则保存相对运算程序的首地址。运算主程序框图如下所示:


4、简易计算器源程序

OUTBIT equ 07FFDh ; 位控制口

OUTSEG equ 07FFCh ; 段控制口

IN equ 07FFEh ; 键盘读入口

data1 equ 70h

data2 equ 71h

dizhi1 equ 72h

dizhi2 equ 73h

LEDBuf equ 60h ; 显示缓冲

ljmp Start

LEDMAP: ; 八段管显示码

db 3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h

db 7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71h

Delay: ; 延时子程序

mov r7, #0

DelayLoop:

djnz r7, DelayLoop

djnz r6, DelayLoop

ret

DisplayLED:

mov r0, #LEDBuf

mov r1, #2 ; 共2个八段管

mov r2, #00000010b ; 从左边开始显示

Loop:

mov dptr, #OUTBIT

mov a, #0

movx @dptr, a ; 关所有八段管

mov a, @r0

mov dptr, #OUTSEG

movx @dptr, a

mov dptr, #OUTBIT

mov a, r2

movx @dptr, a ; 显示一位八段管

mov r6, #1

call Delay

mov a, r2 ; 显示下一位

rr a

mov r2, a

inc r0

djnz r1, Loop

ret

TestKey:

mov dptr, #OUTBIT

mov a, #0

movx @dptr, a ; 输出线置为0

mov dptr, #IN

movx a, @dptr ; 读入键状态

cpl a

anl a, #0fh ; 高四位不用

ret

KeyTable: ; 键码定义

db 0dh, 0ch, 0bh, 0ah

db 0eh, 03h, 06h, 09h

db 0fh, 02h, 05h, 08h

db 00h, 01h, 04h, 07h

GetKey:

mov dptr, #OUTBIT

mov P2, dph

mov r0, #Low(IN)

mov r1, #00100000b

mov r2, #4

KLoop:

mov a, r1 ; 找出键所在列

cpl a

movx @dptr, a

cpl a

rr a

mov r1, a ; 下一列

movx a, @r0

cpl a

anl a, #0fh

jnz Goon1 ; 该列有键入

djnz r2, KLoop

mov r2, #0ffh ; 没有键按下, 返回 0ffh

sjmp Exit

Goon1:

mov r1, a ; 键值 = 列 X 4 + 行

mov a, r2

dec a

rl a

rl a

mov r2, a ; r2 = (r2-1)*4

mov a, r1 ; r1中为读入的行值

mov r1, #4

LoopC:

rrc a ; 移位找出所在行

jc Exit

inc r2 ; r2 = r2+ 行值

djnz r1, LoopC

Exit:

mov a, r2 ; 取出键码

mov dptr, #KeyTable

movc a, @a+dptr

mov r2, a

WaitRelease:

mov dptr, #OUTBIT ; 等键释放

clr a

movx @dptr, a

mov r6, #10

call Delay

call TestKey

jnz WaitRelease

mov a, r2

ret

Start:

mov sp, #40h

mov LEDBuf+0, #0

mov LEDBuf+1, #03fh

mov dptr, #7FFFh

mov a, #89h

movx @dptr, a

MLoop:

call DisplayLED ; 显示

call TestKey ; 有键入?

jz MLoop ; 无键入, 继续显示

call GetKey ; 读入键码

Jisuan:

mov r3, a

cjne r3, #0fh, Qita ;判断是否为清零键?

mov r3, #00h ;清零

mov r4, #00h

mov r5, #00h

mov data1, #00h

mov data2, #00h

mov dizhi1, #00h

mov dizhi2, #00h

mov LEDBuf+0, #0

mov LEDBuf+1, #03fh

ljmp MLoop

Qita: clr c

cjne r3, #0ah ,follow ;判断是数字键还是功能键?

follow:

jc Shuzi

ljmp Gn

Shuzi: mov a, r4 ;判断是否已有运算符输入,没有就将数值存在

jnz Shuzi2 data1,有就将数值存在data2

mov a, r3

mov data1, a

ljmp Xs ;显示第一次输入的数值

Shuzi2:

mov a, r3

mov data2, a

ljmp Xs ;显示第二次输入的数值

Gn: mov r4, #01h ;将01h给r4,说明已有运算符输入

cjne r3, #0eh, Ja ;判断键值是否为“=”?

mov r4, #00h ;将r4清零

mov a, dizhi1 ;执行“=”

mov dph, a

mov a, dizhi2

mov dpl, a

mov a, #00h

jmp @a+dptr ;转到本次输入的算法程序

Ja: cjne r3, #0ah, Jn ;若键值为“+”则将“+”的程序首地址存在

mov dptr, #Jia dizhi1和dizhi2中

mov a, dph

mov dizhi1, a

mov a, dpl

mov dizhi2, a

ljmp MLoop

Jn: cjne r3, #0bh, Ce ;若键值为“-”则将“-”的程序首地址存

mov dptr, #Jian dizhi1和dizhi2中

mov a, dph

mov dizhi1, a

mov a, dpl

mov dizhi2, a

ljmp MLoop

Ce: cjne r3, #0ch, Cu ;若键值为“*”则将“*”的程序首地址存在

mov dptr, #Cheng dizhi1和dizhi2中

mov a, dph

mov dizhi1, a

mov a, dpl

mov dizhi2, a

ljmp MLoop

Cu: cjne r3, #0dh, Zhuan ;若键值为“/”则将“/”的程序首地址存在

mov dptr, #chu dizhi1和dizhi2中

mov a, dph

mov dizhi1, a

mov a, dpl

mov dizhi2, a

Zhuan: ljmp MLoop

Jia: mov a, data1 ;加法程序

add a, data2

ljmp Xs

Jian: mov a, data1 ;减法程序

subb a, data2

ljmp Xs

Cheng: mov a, data1 ;乘法程序

mov b, data2

mul ab

ljmp Xs

Chu: mov a, data1 ;除法程序

mov b, data2

div ab

Xs: mov b, #10 ;显示个位数字

div ab

mov r5, a

mov a, b

mov dptr,#LEDMap

movc a, @a+dptr

mov LEDBuf+1,a

mov a, r5

First:

cjne a,#0,Next

ljmp MLoop ;运算完后继续扫描键盘

Next:

mov b,#10 ;显示十位数字

div ab

mov r5, a

mov a, b

mov dptr, #LEDMap

movc a, @a+dptr

mov LEDBuf+0, a

mov a, r5

ljmp First

end

四、系统调试与存在的问题

1.在打开一个程序要进行编译运行时,要在项目中打开它,而不是单单以一个文件的形式打开。

2.打开WAVE6000后,需要对仿真器进行设置,然后才能用其对所编程序进行编译并执行。

3.试验箱上提供的6位的LED显示器和4*6的键盘,而简易计算器只用两位LED显示器和4*4键盘,所以必须用软件方法把前4位LED和键盘后2列屏蔽掉。

4. 十位上的LED显示管有数字时才显示,没有数字时不显示,而不是显示“0”,做清零操作后LED显示器个位显示“0”,而全部关闭不显示。

五、心得体会

课程设计是培养学生综合运用所学知识,发现、提出、分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程。随着科学技术发展的日新日异,单片机已经成为当今计算机应用中空前活跃的领域,在生活中可以说得是无处不在。因此作为电子信息工程专业的学生来说掌握单片机的开发技术是十分重要的。
我的题目是简易计算器,对于我们这些实践中的新手来说,这是一次考验。怎么才能找到课堂所学与实际应用的最佳结合点?怎样让自己的业余更接近专业?怎样让自己的计划更具有序性,而不会忙无一用?这都是我们所要考虑和努力的。这次课程设计我学到很多很多的东西,学会了怎么样去制定计划,怎么样去实现这个计划,并掌握了在执行过程中怎么样去克服心理上的不良情绪。不仅巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识,掌握了一种系统的研究方法,可以进行一些简单的编程。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,对单片机汇编语言掌握得不够好。

这次课程设计通过我们小组的努力终于顺利完成了,在设计中遇到了很多编程问题,最后在老师的辛勤指导下,终于迎刃而解,在此我表示感谢!同时,对给过我帮助的所有同学和各位指导老师再次表示忠心的感谢!


关键词: 显示 单片机 计算器

解决方案


评论

技术专区