基于C51单片机的简易计算器设计

基于单片机的简易设计原理

专业:通信专业 班级:通信1班 姓名:刘民 学号:1304041127

摘要:按下键盘,通过键盘扫描程序,在LCD 液晶显示屏上显示按键的操作过程,最终显示计算结果,实现计算器的基本功能。本文详细介绍LCD 显示屏、矩阵键盘与C51单片机接口的应用,并介绍如何通过C51单片机实现计算器的算法。 关键字:C51单片机,键盘,LCD 液晶,计算器

一、设计任务:

本次实验是要以51系列单片机为核心实现一个简易计算器,它的结构简单,外部主要由4*4矩阵键盘和一个液晶显示屏构成,内部由一块STC90C51单片机构成,通过软件编程可实现简单加、减、乘、除、清除结果。实现对计算器的设计,具体设计如下:

1、采用6位显示,最大显示值为“999999”,设计16个按键的矩阵键盘,按键包括‘0~9’、‘+’、‘-’、‘*’、‘/’、‘=’、‘C ’。

2、加减法做四字节运算;乘法做双字节运算;除法被除数为四字节,除数为两字节。

3、当运算结果超出显示范围时,显示ERROR !。

4、上述运算输入值均为整数,当结果带有小数时,可以采用四舍五入方式处理,也可以带小数显示。

二 、方案论证

经分析,计算器电路包括三个部分:显示电路、、4*4键扫描电路、单片机微控制电路。具体如下:

⒈)LCD 显示电路

LCD1602作为一个成熟的产品,使用简单,模式固定,便于移植到各

种类型的程序,但是初学者往往要注意结合LCD 本身的时序图来完善初始化程序。又以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,故采用LCD.

⒉)4*4键盘扫描电路(中断式,扫描式,反转式)

用户设计行列键盘接口,一般常采用3 种方法读取键值。一种是中

断式,外两种是扫描法和反转法。

扫描法:

对键盘上的某一行送低电平,其他行及列全为高电平,然后读取列值,检查各列线点评的变化,如果某列线电平为低电平,就可以确定此行此列交叉点处的按键被按下,采用延时去抖动。 ⒊) 单片机微控制电路

微控制电路就是以AT89C51为核心的控制核心,主要注意晶振电路的接法和复位电路的接法。

三 硬件电路的设计

3.1 硬件设计电路框图

线路原理框图

3.2、系统模块图:

四、键盘接口电路:

计算器输入数字和其他功能按键要用到很多按键,矩阵键盘采用四条I/O 线作为行线,四条I/O 线作为列线组成键盘,在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4×4个。这种行列式键盘结构能有效地提高

单片机系统中I/O 口的利用率。

矩阵键盘的工作原理:

计算器的键盘布局如图1所示:一般有16个键组成,在单片机中正好可以用一个P 口实现16个按键功能,这种形式在单片机系统中也最常用。

图2 键盘接口电路图

五、LCD 显示 LCD 显示器介绍

有字符型液晶显示模块(SMC1602A )和点阵式液晶显示模块(TCM12232A 、TCM12864N )下面以SMC1602A 为例介绍字符型液晶显示模块的功能及应用。

(一)、字符型液晶显示模块的引脚及功能

在1602液晶内部有字模发生存储器CGROM 及显示数据存储器DDRAM 。其中,字模发生存储器CGROM 主要用来存储192个常用字符的字模编码,包含标准的ASCII 码。DDRAM 是显示数据存储器共80个字节,分别对应1602液晶显示器的两行。第一行地址为0X00H~0X27H,共40个字节;第二行地址为0X40H~67H,共40个字节。 RAM 地址映像如下图:

(二):字符型液晶显示模块的控制操作

在1602读回的状态字中,D7位为状态BF ,当BF=1时表示忙碌, 此时不能进行写操作。当BF=0时表示状态为空闲,可以进行写操作。 (2)写操作:

(3)初始化命令字:

a. 工作方式设置指令

DL 设置与MCU 的接口方式。DL=1表示数据宽度为8位,DB0~DB7有效。 DL=0表示数据宽度为4位,DB4~DB7有效。N 设置显示字符行数。 N=0表示显示一行字符,N=1表示显示两行字符。F 设置显示字符字体, 一般为0。F=0表示显示5X8点阵字体,F=1表示显示5X11点整字体。

b. 显示状态设置

D 为画面显示状态位。D=1表示显示功能开,D=0表示显示功能关。 C 为光标显示状态位。C=1表示有光标,C=0表示无光标。

B 闪烁显示状态位。B=1表示光标闪烁,B=0表示光标不闪烁。

c. 输入方式设置指令

该指令的操作主要是设置显示字符的输入方式。即在操作数据写入/读出 后,AC 数据地址指针的修改方式。I/D=1时,AC 为自动加一计数器, I/D=0时,AC 为自动减一计数器。S 设置写入字符时是否允许画面滚动。 S=1时允许画面/光标滚动,S=0时禁止画面/光标滚动。

d. 光标或画面滚动设置指令

S/C滚动对象选择位。S/C=1时画面滚动,S/C=0时光标滚动。 R/L滚动方向选择位。R/L=1时向右滚动,R/L=0时向左滚动。

e.

清屏指令

执行清屏指令后,DDRAM 内容为空白的ASCII 码20H ,光标归位在 左上方,地址计数器AC=0.

f.

光标复位指令

执行光标复位指令后,AC=0,DDRAM 中的值不变。

g.DDRAM 地址设置指令

当需要向某一地址中写入数据时,先写入地址,再写入数据。

程序图

五、运算模块(单片机控制):

MCS-51 单片机是在一块芯片中集成了CPU 、RAM 、ROM 、定时器/计数器和多功能I/O等一台计算机所需要的基本功能部件。如果按功能划分,它由如下功能部件组成,即微处理器(CPU )、数据存储器(RAM )、程序存储器(ROM/EPROM)、并行I/O 口、串行口、定时器/计数器、中断系统及特殊功能寄存器(SFR )。

单片机是靠程序运行的,并且可以修改。通过不同的程序实现不同的功能,尤其是特殊的独特的一些功能,通过使用单片机编写的程序可以实现高智能,高效率,以及高可靠性!因此我们采用单片机作为计算器的主要功能部件,可以很快地实现运算功能。

六:设计心得、体会、总结

我的题目简易计算器的设计,对于我们这些实践中的新手来说,这是一次考验,怎样才能找到课堂所学与实际应用的最佳结合点?怎样让自己的计划更具有程序性,而不会忙无一用?这都需要我们所要考虑和努力的。这次设计我学到了很多,在设计过程中怎样去克服心理上的不良情绪。不仅巩固了所学知识,而且学到了很多书上学不到的知识,掌握了一种系统的学习方法,可以进行一些简单的编程。这次设计使我懂得了理论与实际结合很重要,只有理论知识是远远不够的,从而提高自己的实际动手能力和独立思考的能力,同时在设计过程中发现自己的不足,加强巩固,有利于后续的单片机考试。

调试过程中也遇到了很多问题,例如,液晶显示明明定义了两行显示,但实际中却只有一行,最后竟查资料发现,液晶内部自检时间比单片机慢,需要延时多定义,避免未完成自检就执行指。

主要参考文献

《单片机原理与接口技术》,李升主编,北京大学出版社,2011年7月

《单片机原理及应用实验指导书》,屈波等编,2012年2月25日 《微处理器综合实训系统模块化设计》戴建 编 2012年2月 《单片机原理及应用》,赵德安等编,机械工业出版社,2009年

附原理图

附:硬件设计电路的元件清单

void write_com(uchar com) //写指令 //***P1.0~P1.3接行*******P1.4~P1.7接列.

{ ******* P0接LCD******************//

附源代码

#include #define uchar unsigned char uchar code dis1[]="!rorre";//后面使用倒序显示 uchar code dis2[]="!rorre htam"; sbit busy=P0^7; sbit RS=P2^2; sbit RW=P2^1; sbit EN=P2^0; char i,j,temp,num; long a,b,c; uchar flag,fuhao; uchar code table[]={ 7,8,9,0, 4,5,6,0, 1,2,3,0, 0,0,0,0 }; uchar code table1[]={ 7,8,9,0x2f-0x30, 4,5,6,0x2a-0x30, 0x01-0x30,0,0x3d-0x30,0x2b-0x30 }; void delay(uchar z) //延时

{ uchar x,y; for(x=z;x>0;x--) for(y=0;y

} void ready() //忙检测 { do { P0=0xff; RS=0; RW=1; EN=0; delay(5); EN=1; } while(busy==1); } P0=com; RS=0; RW=0; EN=0; ready(); EN=1; delay(10); } void write_data(uchar m) //写数据 {P0=m; RS=1; RW=0; EN=0; ready(); EN=1; }

void inital() //初始化 { EN=1; write_com(0x38); //【设置LCD 为16X2

显示,5X7点阵, 八位数据接口】 delay(10); write_com(0x38); //【LCD 内检较单片机慢,

为防止未完成内检就执行指令,延迟,再写指令以完成内检】 write_com(0x0c); //无光标 write_com(0x06); //光标后移 write_com(0x80); write_com(0x01); //清屏 i=0; j=0; a=0; //第一个参与运算的数 b=0; //第二个参与运算的数 c=0; flag=0; //flag表示是否有符号键按下 fuhao=0; //fuhao表征按下的是哪个符号 } void keyscan() //键盘扫描程序

{

P1=0xfe; //将某一行置低,列全为高 if(P1!=0xfe) //判断是否有键按下 {

delay(20); //延时去抖动 if(P1!=0xfe) //重新确认 {

temp=P1&0xf0; //【行全置低,判断列是

否变化】

switch(temp) {

case 0xe0:

num=0; break; case 0xd0:

num=1; break; case 0xb0:

num=2; break; case 0x70:

num=3; break; } } while(P1!=0xfe);

if(num==0||num==1||num==2)

//如果按

下的是'7','8' 或'9

{

if(j==1) //确认一次计算完毕,清屏 { write_com(0x01); j=0; }

if(flag==0) //没有按过符号键 {

a=a*10+table[num]; }

else //如果按过符号键 {

b=b*10+table[num]; } }

else //如果按下的是'/' { flag=1;

fuhao=4; }

i=table1[num]; write_data(0x30+i); }

P1=0xfd; if(P1!=0xfd) {

delay(20); if(P1!=0xfd)

{ temp=P1&0xf0; switch(temp) { case 0xe0:

num=4 ; break; case 0xd0:

num=5; break; case 0xb0:

num=6; break;

case 0x70:

num=7; break; } }

while(P1!=0xfd);

if(num==4||num==5||num==6) //如

果按下是'4','5' 或'6

{

if(j==1) {

write_com(0x01); j=0; }

if(flag==0) {

a=a*10+table[num]; } else {

b=b*10+table[num];

} } else { flag=1; fuhao=3; }

i=table1[num]; write_data(0x30+i); } P1=0xfb; if(P1!=0xfb) {delay(20); if(P1!=0xfb) {

temp=P1&0xf0; switch(temp) {

case 0xe0:

num=8; break; case 0xd0:

num=9; break; case 0xb0:

num=10; break; case 0x70:

num=11; break; } }

while(P1!=0xfb);

if(num==8||num==9||num==10) //如果

按下的是'1','2' 或'3

{

if(j==1)

{ write_com(0x01); j=0; }

if(flag==0)

{ a=a*10+table[num]; } else

{

b=b*10+table[num]; } } else {

flag=1; fuhao=2; }

i=table1[num]; write_data(0x30+i); }

P1=0xf7; if(P1!=0xf7) { delay(20); if(P1!=0xf7) {

temp=P1&0xf0; switch(temp) { case 0xe0:

num=12; break; case 0xd0:

num=13; break; case 0xb0:

num=14; break; case 0x70:

num=15; break; } }

while(P1!=0xf7); switch(num)

{ case 12: //按下的是" 清零" { write_com(0x01); a=0; b=0; flag=0; fuhao=0; }

break;

case 13: //写'0'

{ if(j==1) //确认一次计算完毕,清屏 { write_com(0x01); j=0; }

if(flag==0) {

a=a*10;

write_data(0x30); }

if(flag==1) { b=b*10;

write_data(0x30); } }

break; case 14:

{ write_data(0x3d); // 写'=' j=1;

if(fuhao==1) //'写+'

{ write_com(0x80+0x4f); //【也可写成成write_com(0xc0+0x0f); 定义第二行】

write_com(0x04); // 光标前移 c=a+b;

if(c==0)

{write_data(0x30);} while(c!=0)

{ write_data(0x30+c%10); c=c/10; } a=0; b=0; flag=0; fuhao=0; } else

if(fuhao==2) //写负号'-' { write_com(0x80+0x4f); write_com(0x04); if(a-b>=0) c=a-b; else c=b-a; if(c==0)

{write_data(0x30);} while(c!=0) {

write_data(0x30+c%10); c=c/10; } if(a-b

write_data(0x2d); //写负号"-" a=0; b=0; flag=0; fuhao=0; } else

if(fuhao==3) //按下乘号按键 { write_com(0x80+0x4f); write_com(0x04); c=a*b; if(c==0)

{write_data(0x30);}

if(c>999999) //六位显示,最大显示'999999' 超

出显示 ‘error! ’

{

i=0;

while(dis1[i]!='\0') {write_data(dis1[i]); i++;

} }

if(c

write_data(0x30+c%10); c=c/10; }

a=0;b=0;flag=0;fuhao=0; } else

if(fuhao==4) //按下除号按键

{ write_com(0x80+0x4f); //重新定位 write_com(0x04); //光标前移

if(b==0) //错误 math error! {

i=0;

while(dis1[i]!='\0') {write_data(dis1[i]); i++;

} } else

{ i=0;

c=(long)(((float)a/b)*1000); while(c!=0) {

write_data(0x30+c%10); c=c/10; i++;

if(i==3) //精确到小数点后三位 write_data(0x2e); //写小数点 }

if(a/b

write_data(0x30); } a=0; b=0; flag=0; fuhao=0; } }

break; case 15: {

write_data(0x30+table1[num]); // '+' flag=1; fuhao=1; }

break; } } }

void main() {

inital();

while(1) {

keyscan(); } }

基于单片机的简易设计原理

专业:通信专业 班级:通信1班 姓名:刘民 学号:1304041127

摘要:按下键盘,通过键盘扫描程序,在LCD 液晶显示屏上显示按键的操作过程,最终显示计算结果,实现计算器的基本功能。本文详细介绍LCD 显示屏、矩阵键盘与C51单片机接口的应用,并介绍如何通过C51单片机实现计算器的算法。 关键字:C51单片机,键盘,LCD 液晶,计算器

一、设计任务:

本次实验是要以51系列单片机为核心实现一个简易计算器,它的结构简单,外部主要由4*4矩阵键盘和一个液晶显示屏构成,内部由一块STC90C51单片机构成,通过软件编程可实现简单加、减、乘、除、清除结果。实现对计算器的设计,具体设计如下:

1、采用6位显示,最大显示值为“999999”,设计16个按键的矩阵键盘,按键包括‘0~9’、‘+’、‘-’、‘*’、‘/’、‘=’、‘C ’。

2、加减法做四字节运算;乘法做双字节运算;除法被除数为四字节,除数为两字节。

3、当运算结果超出显示范围时,显示ERROR !。

4、上述运算输入值均为整数,当结果带有小数时,可以采用四舍五入方式处理,也可以带小数显示。

二 、方案论证

经分析,计算器电路包括三个部分:显示电路、、4*4键扫描电路、单片机微控制电路。具体如下:

⒈)LCD 显示电路

LCD1602作为一个成熟的产品,使用简单,模式固定,便于移植到各

种类型的程序,但是初学者往往要注意结合LCD 本身的时序图来完善初始化程序。又以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,故采用LCD.

⒉)4*4键盘扫描电路(中断式,扫描式,反转式)

用户设计行列键盘接口,一般常采用3 种方法读取键值。一种是中

断式,外两种是扫描法和反转法。

扫描法:

对键盘上的某一行送低电平,其他行及列全为高电平,然后读取列值,检查各列线点评的变化,如果某列线电平为低电平,就可以确定此行此列交叉点处的按键被按下,采用延时去抖动。 ⒊) 单片机微控制电路

微控制电路就是以AT89C51为核心的控制核心,主要注意晶振电路的接法和复位电路的接法。

三 硬件电路的设计

3.1 硬件设计电路框图

线路原理框图

3.2、系统模块图:

四、键盘接口电路:

计算器输入数字和其他功能按键要用到很多按键,矩阵键盘采用四条I/O 线作为行线,四条I/O 线作为列线组成键盘,在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4×4个。这种行列式键盘结构能有效地提高

单片机系统中I/O 口的利用率。

矩阵键盘的工作原理:

计算器的键盘布局如图1所示:一般有16个键组成,在单片机中正好可以用一个P 口实现16个按键功能,这种形式在单片机系统中也最常用。

图2 键盘接口电路图

五、LCD 显示 LCD 显示器介绍

有字符型液晶显示模块(SMC1602A )和点阵式液晶显示模块(TCM12232A 、TCM12864N )下面以SMC1602A 为例介绍字符型液晶显示模块的功能及应用。

(一)、字符型液晶显示模块的引脚及功能

在1602液晶内部有字模发生存储器CGROM 及显示数据存储器DDRAM 。其中,字模发生存储器CGROM 主要用来存储192个常用字符的字模编码,包含标准的ASCII 码。DDRAM 是显示数据存储器共80个字节,分别对应1602液晶显示器的两行。第一行地址为0X00H~0X27H,共40个字节;第二行地址为0X40H~67H,共40个字节。 RAM 地址映像如下图:

(二):字符型液晶显示模块的控制操作

在1602读回的状态字中,D7位为状态BF ,当BF=1时表示忙碌, 此时不能进行写操作。当BF=0时表示状态为空闲,可以进行写操作。 (2)写操作:

(3)初始化命令字:

a. 工作方式设置指令

DL 设置与MCU 的接口方式。DL=1表示数据宽度为8位,DB0~DB7有效。 DL=0表示数据宽度为4位,DB4~DB7有效。N 设置显示字符行数。 N=0表示显示一行字符,N=1表示显示两行字符。F 设置显示字符字体, 一般为0。F=0表示显示5X8点阵字体,F=1表示显示5X11点整字体。

b. 显示状态设置

D 为画面显示状态位。D=1表示显示功能开,D=0表示显示功能关。 C 为光标显示状态位。C=1表示有光标,C=0表示无光标。

B 闪烁显示状态位。B=1表示光标闪烁,B=0表示光标不闪烁。

c. 输入方式设置指令

该指令的操作主要是设置显示字符的输入方式。即在操作数据写入/读出 后,AC 数据地址指针的修改方式。I/D=1时,AC 为自动加一计数器, I/D=0时,AC 为自动减一计数器。S 设置写入字符时是否允许画面滚动。 S=1时允许画面/光标滚动,S=0时禁止画面/光标滚动。

d. 光标或画面滚动设置指令

S/C滚动对象选择位。S/C=1时画面滚动,S/C=0时光标滚动。 R/L滚动方向选择位。R/L=1时向右滚动,R/L=0时向左滚动。

e.

清屏指令

执行清屏指令后,DDRAM 内容为空白的ASCII 码20H ,光标归位在 左上方,地址计数器AC=0.

f.

光标复位指令

执行光标复位指令后,AC=0,DDRAM 中的值不变。

g.DDRAM 地址设置指令

当需要向某一地址中写入数据时,先写入地址,再写入数据。

程序图

五、运算模块(单片机控制):

MCS-51 单片机是在一块芯片中集成了CPU 、RAM 、ROM 、定时器/计数器和多功能I/O等一台计算机所需要的基本功能部件。如果按功能划分,它由如下功能部件组成,即微处理器(CPU )、数据存储器(RAM )、程序存储器(ROM/EPROM)、并行I/O 口、串行口、定时器/计数器、中断系统及特殊功能寄存器(SFR )。

单片机是靠程序运行的,并且可以修改。通过不同的程序实现不同的功能,尤其是特殊的独特的一些功能,通过使用单片机编写的程序可以实现高智能,高效率,以及高可靠性!因此我们采用单片机作为计算器的主要功能部件,可以很快地实现运算功能。

六:设计心得、体会、总结

我的题目简易计算器的设计,对于我们这些实践中的新手来说,这是一次考验,怎样才能找到课堂所学与实际应用的最佳结合点?怎样让自己的计划更具有程序性,而不会忙无一用?这都需要我们所要考虑和努力的。这次设计我学到了很多,在设计过程中怎样去克服心理上的不良情绪。不仅巩固了所学知识,而且学到了很多书上学不到的知识,掌握了一种系统的学习方法,可以进行一些简单的编程。这次设计使我懂得了理论与实际结合很重要,只有理论知识是远远不够的,从而提高自己的实际动手能力和独立思考的能力,同时在设计过程中发现自己的不足,加强巩固,有利于后续的单片机考试。

调试过程中也遇到了很多问题,例如,液晶显示明明定义了两行显示,但实际中却只有一行,最后竟查资料发现,液晶内部自检时间比单片机慢,需要延时多定义,避免未完成自检就执行指。

主要参考文献

《单片机原理与接口技术》,李升主编,北京大学出版社,2011年7月

《单片机原理及应用实验指导书》,屈波等编,2012年2月25日 《微处理器综合实训系统模块化设计》戴建 编 2012年2月 《单片机原理及应用》,赵德安等编,机械工业出版社,2009年

附原理图

附:硬件设计电路的元件清单

void write_com(uchar com) //写指令 //***P1.0~P1.3接行*******P1.4~P1.7接列.

{ ******* P0接LCD******************//

附源代码

#include #define uchar unsigned char uchar code dis1[]="!rorre";//后面使用倒序显示 uchar code dis2[]="!rorre htam"; sbit busy=P0^7; sbit RS=P2^2; sbit RW=P2^1; sbit EN=P2^0; char i,j,temp,num; long a,b,c; uchar flag,fuhao; uchar code table[]={ 7,8,9,0, 4,5,6,0, 1,2,3,0, 0,0,0,0 }; uchar code table1[]={ 7,8,9,0x2f-0x30, 4,5,6,0x2a-0x30, 0x01-0x30,0,0x3d-0x30,0x2b-0x30 }; void delay(uchar z) //延时

{ uchar x,y; for(x=z;x>0;x--) for(y=0;y

} void ready() //忙检测 { do { P0=0xff; RS=0; RW=1; EN=0; delay(5); EN=1; } while(busy==1); } P0=com; RS=0; RW=0; EN=0; ready(); EN=1; delay(10); } void write_data(uchar m) //写数据 {P0=m; RS=1; RW=0; EN=0; ready(); EN=1; }

void inital() //初始化 { EN=1; write_com(0x38); //【设置LCD 为16X2

显示,5X7点阵, 八位数据接口】 delay(10); write_com(0x38); //【LCD 内检较单片机慢,

为防止未完成内检就执行指令,延迟,再写指令以完成内检】 write_com(0x0c); //无光标 write_com(0x06); //光标后移 write_com(0x80); write_com(0x01); //清屏 i=0; j=0; a=0; //第一个参与运算的数 b=0; //第二个参与运算的数 c=0; flag=0; //flag表示是否有符号键按下 fuhao=0; //fuhao表征按下的是哪个符号 } void keyscan() //键盘扫描程序

{

P1=0xfe; //将某一行置低,列全为高 if(P1!=0xfe) //判断是否有键按下 {

delay(20); //延时去抖动 if(P1!=0xfe) //重新确认 {

temp=P1&0xf0; //【行全置低,判断列是

否变化】

switch(temp) {

case 0xe0:

num=0; break; case 0xd0:

num=1; break; case 0xb0:

num=2; break; case 0x70:

num=3; break; } } while(P1!=0xfe);

if(num==0||num==1||num==2)

//如果按

下的是'7','8' 或'9

{

if(j==1) //确认一次计算完毕,清屏 { write_com(0x01); j=0; }

if(flag==0) //没有按过符号键 {

a=a*10+table[num]; }

else //如果按过符号键 {

b=b*10+table[num]; } }

else //如果按下的是'/' { flag=1;

fuhao=4; }

i=table1[num]; write_data(0x30+i); }

P1=0xfd; if(P1!=0xfd) {

delay(20); if(P1!=0xfd)

{ temp=P1&0xf0; switch(temp) { case 0xe0:

num=4 ; break; case 0xd0:

num=5; break; case 0xb0:

num=6; break;

case 0x70:

num=7; break; } }

while(P1!=0xfd);

if(num==4||num==5||num==6) //如

果按下是'4','5' 或'6

{

if(j==1) {

write_com(0x01); j=0; }

if(flag==0) {

a=a*10+table[num]; } else {

b=b*10+table[num];

} } else { flag=1; fuhao=3; }

i=table1[num]; write_data(0x30+i); } P1=0xfb; if(P1!=0xfb) {delay(20); if(P1!=0xfb) {

temp=P1&0xf0; switch(temp) {

case 0xe0:

num=8; break; case 0xd0:

num=9; break; case 0xb0:

num=10; break; case 0x70:

num=11; break; } }

while(P1!=0xfb);

if(num==8||num==9||num==10) //如果

按下的是'1','2' 或'3

{

if(j==1)

{ write_com(0x01); j=0; }

if(flag==0)

{ a=a*10+table[num]; } else

{

b=b*10+table[num]; } } else {

flag=1; fuhao=2; }

i=table1[num]; write_data(0x30+i); }

P1=0xf7; if(P1!=0xf7) { delay(20); if(P1!=0xf7) {

temp=P1&0xf0; switch(temp) { case 0xe0:

num=12; break; case 0xd0:

num=13; break; case 0xb0:

num=14; break; case 0x70:

num=15; break; } }

while(P1!=0xf7); switch(num)

{ case 12: //按下的是" 清零" { write_com(0x01); a=0; b=0; flag=0; fuhao=0; }

break;

case 13: //写'0'

{ if(j==1) //确认一次计算完毕,清屏 { write_com(0x01); j=0; }

if(flag==0) {

a=a*10;

write_data(0x30); }

if(flag==1) { b=b*10;

write_data(0x30); } }

break; case 14:

{ write_data(0x3d); // 写'=' j=1;

if(fuhao==1) //'写+'

{ write_com(0x80+0x4f); //【也可写成成write_com(0xc0+0x0f); 定义第二行】

write_com(0x04); // 光标前移 c=a+b;

if(c==0)

{write_data(0x30);} while(c!=0)

{ write_data(0x30+c%10); c=c/10; } a=0; b=0; flag=0; fuhao=0; } else

if(fuhao==2) //写负号'-' { write_com(0x80+0x4f); write_com(0x04); if(a-b>=0) c=a-b; else c=b-a; if(c==0)

{write_data(0x30);} while(c!=0) {

write_data(0x30+c%10); c=c/10; } if(a-b

write_data(0x2d); //写负号"-" a=0; b=0; flag=0; fuhao=0; } else

if(fuhao==3) //按下乘号按键 { write_com(0x80+0x4f); write_com(0x04); c=a*b; if(c==0)

{write_data(0x30);}

if(c>999999) //六位显示,最大显示'999999' 超

出显示 ‘error! ’

{

i=0;

while(dis1[i]!='\0') {write_data(dis1[i]); i++;

} }

if(c

write_data(0x30+c%10); c=c/10; }

a=0;b=0;flag=0;fuhao=0; } else

if(fuhao==4) //按下除号按键

{ write_com(0x80+0x4f); //重新定位 write_com(0x04); //光标前移

if(b==0) //错误 math error! {

i=0;

while(dis1[i]!='\0') {write_data(dis1[i]); i++;

} } else

{ i=0;

c=(long)(((float)a/b)*1000); while(c!=0) {

write_data(0x30+c%10); c=c/10; i++;

if(i==3) //精确到小数点后三位 write_data(0x2e); //写小数点 }

if(a/b

write_data(0x30); } a=0; b=0; flag=0; fuhao=0; } }

break; case 15: {

write_data(0x30+table1[num]); // '+' flag=1; fuhao=1; }

break; } } }

void main() {

inital();

while(1) {

keyscan(); } }


相关文章

  • 电子信息工程毕业设计题目大全
  • 1 压力容器液位测量 2 多功能遥控小车 3基于RS232的仓库多点温度.湿度.气 4压检测系统 5自动控制升降旗系统 6基于RS485的温度报警系统 7基于模糊算法的水温控制系统的设计 8多分机电话交换机 9简易火灾自动报警系统 10基于 ...查看


  • 简易数字温度计的设计与制作1
  • 简易数字温度计的设计与制作 来源:PCB下载站 作者:郇玉龙 赵宁 摘 要:单片机在日用电子产品中的应用越来越广泛,温度则是人们日常生活中常常需要测量和控制的一个量.本文作者采用AT89C51单片机和温度传感器AD590从硬件和软件两方面介 ...查看


  • 单片机简易计算器的设计-C语言
  • 基于AT89C51单片机简易计算器的设计 [摘 要]单片机的出现是计算机制造技术高速发展的产物,它是嵌入式控制系统的核心,如今,它已广泛的应用到我们生活的各个领域,电子.科技.通信.汽车.工业等.本设计是基于51系列单片机来进行的数字计算器 ...查看


  • 基于51单片机的可调歌音乐盒设计
  • 本科学年论文 学 院 物理电子工程学院 专 业 电子科学与技术 年 级 2009级 姓 名 张家义 论文题目 基于51单片机的音乐播放器设计 指导教师 仓玉萍 职称 讲师 成 绩 2012年6月5日 目 录 摘要 ............. ...查看


  • 基于单片机的简易逻辑分析仪论文(经典)
  • 目 录 第1节 引 言„„„„„„„„„„„„„„„„„„„„„„„„„„„„„3 1.1 系统概述„„„„„„„„„„„„„„„„„„„„„„„„„„„3 1.1.1系统的特点„„„„„„„„„„„„„„„„„„„„„„„„4 1.1.2 ...查看


  • 基于51单片机电子秤设计
  • 摘要 电子秤是日常生活中常用的称重设备,广泛应用于超市.大中型商场.物流配送中心.电子秤在结构和原理上取代了以杠杆平衡为原理的传统机械式称量工具.相比传统的机械式称量工具,电子秤具有称量精度高.装机体积小.应用范围广.易于操作使用等优点,在 ...查看


  • 毕业设计_基于单片机的简易逻辑分析仪
  • 基于单片机的简易逻辑分析仪 目 录 第1节 引 言„„„„„„„„„„„„„„„„„„„„„„„„„„„„„3 1.1 系统概述„„„„„„„„„„„„„„„„„„„„„„„„„„„3 1.1.1系统的特点„„„„„„„„„„„„„„„„„ ...查看


  • 2013全国电子大赛论文
  • 2013全国电子设计大赛瑞萨杯 2013年全国大学生电子设计竞赛 简易旋转倒立摆控制及控制装置( [本科组] 2013年9月4日 C题) 摘 要 旋转倒立摆是一个具有多变量.高阶.非线性.强耦合等系统特性的本征不稳定系统,涉及有关力学.数学 ...查看


  • 基于51单片机的简易计算器
  • 课程设计(论文) 说明书 题 目:基于单片机简易计算器的设计 院 (系): 专 业: 学生姓名:学 号: 指导教师: 职 称: 2011年 12月 18日 摘 要 简易计算器是一种非常广泛日常工具,对现代社会越来越流行.它可以进行一些简易的 ...查看


热门内容