基于AVR单片机的计算器程序

合集下载

单片机简易计算器程序代码

单片机简易计算器程序代码
{i=table1[num];fuhao=2;if(eq==0){ gz++;write_date(0x30+i);}
else{write_com(0x01);write_date(0x41) ;write_date(0x4e);write_date(0x53);write_date(0x30+i);a=daan;gz=gz+4;}
{fuhao=3;i=table1[num];if(eq==0){gz++; write_date(0x30+i);}
else {write_com(0x01);write_date(0x41) ;write_date(0x4e);write_date(0x53);write_date(0x30+i);a=daan;gz=gz+4;}
}//3表示乘号已按
if(g==1)
{g=0;gg(gz);fuhao=6;if(eq==0){gz=gz+3;write_date(0x43);write_date(0x4f);write_date(0x53);}
else{write_com(0x01);write_date(0x43);write_date(0x4f);write_date(0x53);write_date(0x4e);write_date(0x41) ;write_date(0x4e);write_date(0x53);b=daan;gz=gz+6;}
if(g==0)
{
write_com(0x01);
a=0;
b=0;
flag=0;
fuhao=0;
eq=0;
ad=0;bd=0;afd=0;bfd=0;

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

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

基于单片机的简易计算器的设计引言:计算器作为一种常见的便携式计算设备,在我们的生活中扮演着重要的角色。

基于单片机的简易计算器凭借其小巧的体积、低功耗和简单易用的特点,成为了很多人的选择。

本文将介绍一种基于单片机的简易计算器的设计。

一、设计思路设计思路如下:1.显示部分设计使用4位共阴数码管来作为计算结果的显示和反馈。

单片机通过控制不同的引脚,将待显示的数字依次输出到数码管的不同位上,实现显示。

2.控制部分设计使用独立按键作为用户输入,并通过行列扫描的方式进行检测。

通过分析用户输入的按键,识别出相应的操作,并进行相应的计算。

根据不同的按键组合,可以实现加、减、乘、除等运算。

二、硬件设计1.单片机选择为了实现计算器的功能,选择一种性能良好、资源丰富的单片机是很重要的。

根据需求,选择一款采用8051内核的单片机,如AT89S51或AT89C51、这两款单片机具有5V供电、8位数据总线、4KB内存和32个I/O口等特点,并且广泛应用于各种嵌入式开发领域。

2.数码管显示设计为了显示计算结果,采用4位共阴数码管。

通过将各段控制端接通高电平或低电平,实现不同数字的显示。

3.按键设计使用独立按键作为用户输入,通过行列扫描的方式进行检测。

使用矩阵键盘可以减少I/O口的使用,避免使用太多的引脚。

4.电源设计计算器可以通过外接电源供电,同时还可以使用电池作为备用电源。

为了延长电池寿命,可以使用低功耗的工作模式,并在无操作时自动进入休眠状态。

5.外设接口设计为了增加计算器的功能,可以添加一些扩展模块,如蓝牙模块、USB 接口等。

这样可以实现与其他设备的通信和数据传输。

三、软件设计1.按键检测和解码将行列扫描的结果通过软件进行解码,识别用户输入的按键。

通过判断不同的按键组合,可以实现加、减、乘、除等运算。

2.计算实现根据用户输入的数字和操作符,进行相应的计算。

将结果显示到数码管上,并可以通过串口输出到其他设备。

3.界面设计设计简洁、友好的用户界面,提供用户输入和计算结果的显示。

基于AVR单片机的计算器程序

基于AVR单片机的计算器程序

基于AVR单片机的计算器程序在当今的数字化世界中,计算器已成为我们日常生活和工作中不可或缺的工具。

尽管市面上存在许多不同类型的计算器,但基于AVR单片机的计算器程序具有更高的灵活性和可定制性。

本文将介绍如何使用AVR单片机开发一个简单的计算器程序。

一、硬件需求1、AVR单片机:选择一个适合你需求的AVR单片机,如ATmega328P,ATmega128等。

2、按键:你需要为每个数字和操作符提供按键。

3、LED或其他显示设备:用于显示计算器的输出结果。

4、编程器和调试器:用于将程序烧录到单片机上,并进行调试。

二、软件需求1、AVR-GCC:用于编写、编译和链接AVR单片机的程序。

2、AVR-Libc:这是AVR单片机的标准C库。

3、一个文本编辑器或集成开发环境(IDE):用于编写和调试程序。

三、程序设计1、定义按键和LED的接口:你需要定义每个按键和LED与单片机的接口。

这通常涉及设置单片机的特定引脚为输入或输出模式。

2、编写按键处理函数:然后,你需要编写一个函数来处理按键的输入。

这个函数应该能够检测按键的按下和释放,并相应地更新计算器的状态。

3、编写计算逻辑:接下来,你需要编写逻辑来处理各种计算操作。

这可能包括加减乘除、括号、取余等操作。

4、编写显示更新函数:你需要编写一个函数来更新LED上的显示内容。

这个函数应该根据当前的状态来决定显示什么结果。

四、调试和测试在完成程序设计后,你需要使用调试器将程序烧录到单片机上,并进行测试。

你可以通过单步执行程序来检查每个函数是否按预期工作,并确保计算器的整体行为符合预期。

五、结论基于AVR单片机的计算器程序具有很高的灵活性和可定制性,使大家可以根据需要开发出各种不同的计算器。

通过使用AVR单片机,大家可以控制整个系统的硬件和软件,从而能够创建出满足大家特定需求的计算器。

尽管这是一个复杂的项目,但只要大家掌握了AVR单片机的基础知识,大家就可以成功地完成这个项目。

基于单片机的简单计算器

基于单片机的简单计算器

基于单片机的简单计算器计算器是我们日常生活中常用的工具之一,用于进行各种数学运算。

在计算机科学领域,我们可以利用单片机来制作一个简单的计算器,以满足计算需求。

本文将介绍基于单片机的简单计算器的实现过程和相关原理。

一、项目概述我们将利用单片机的计算能力和显示功能来制作这个简单计算器。

用户可以通过按键来输入数字和运算符,计算器将会实时显示计算结果。

在本项目中,我们将使用8051系列单片机和LCD显示屏来实现这个计算器。

二、系统设计1.硬件设计本项目所需的硬件主要包括单片机、键盘和显示屏。

我们可以使用8051系列的单片机,例如AT89C52、键盘可以通过矩阵键盘来实现,显示屏采用16x2字符型LCD显示屏。

2.软件设计在单片机上实现计算器功能,我们需要编写相应的软件程序。

该程序主要包括以下几个部分:(1)初始化设置:设置单片机的IO口模式和状态,初始化LCD显示屏。

(2)键盘扫描:通过轮询方式检测键盘输入,获取用户按键信息。

(3)数字显示:将用户输入的数字显示在LCD屏幕上。

(4)运算处理:根据用户输入的数字和运算符进行相应的运算操作。

(5)结果显示:将运算结果显示在LCD屏幕上。

三、主要功能模块介绍1.初始化设置在初始化设置模块中,我们需要设置单片机的IO口模式和状态,将其中的一组IO口作为输入端口用于键盘扫描,另一组IO口作为输出端口用于LCD显示屏控制。

同时需要初始化LCD显示屏,使其处于工作状态。

2.键盘扫描键盘扫描模块需要使用IO口作为输入端口来检测键盘输入。

通过按下不同的按键,会在IO口上产生不同的信号。

我们可以使用轮询方式来检测IO口的状态,获取用户按键信息。

3.数字显示在数字显示模块中,我们需要将用户输入的数字显示在LCD屏幕上。

可以使用LCD显示屏的库函数来实现这个功能。

我们可以将用户输入的数字存储在内存中,并通过LCD库函数将其显示在屏幕上。

4.运算处理运算处理模块需要根据用户输入的数字和运算符进行相应的运算操作。

基于单片机的简易计算器

基于单片机的简易计算器

基于单片机的简易计算器基于单片机的简易计算器是一种将计算功能集成到微型芯片中的设备。

单片机是一种具有集成电路功能的集成电路,它包含了中央处理器、内存以及输入输出接口等。

单片机的体积小,成本低,功能强大,适用于各种消费电子产品以及嵌入式设备。

简易计算器是一种通过按键输入数字和运算符,然后在显示屏上显示计算结果的设备。

它通常具有加法、减法、乘法和除法等基本运算功能。

在这篇文章中,我们将介绍基于单片机的简易计算器的设计和实现。

首先,我们需要选择合适的单片机。

在设计计算器时,我们需要考虑到单片机的存储容量、算术运算能力以及输入输出接口等。

一个常见的选择是使用8051系列单片机,它具有足够的存储容量和算术运算能力,同时也有丰富的外设接口,便于与按键和显示屏等设备进行连接。

其次,我们需要设计按键输入和显示屏输出的电路。

在按键输入方面,我们可以使用矩阵按键的方式进行设计,这样可以节省输入引脚的数量。

在显示屏输出方面,我们可以选择使用LCD显示屏,它可以提供清晰的显示效果,并且可以显示多行文字和数字。

接下来,我们需要考虑计算器的逻辑和算法。

计算器的逻辑通常是按照先输入数字,再输入运算符,最后输出结果的顺序进行设计。

在输入运算符之后,计算器将根据当前的数字和运算符进行相应的运算,并将结果输出到显示屏上。

这一过程可以使用状态机进行控制,以实现按键输入和结果计算的顺序控制。

最后,我们需要进行软件编程和硬件调试。

软件编程方面,我们需要编写适当的程序代码,实现按键输入、结果计算和结果显示等功能。

硬件调试方面,我们需要将设计好的电路连接到单片机上,并进行相应的测试和调试,以确保计算器的各项功能正常工作。

在设计和实现基于单片机的简易计算器时,需要注意以下几点。

首先,要考虑到计算器的功能需求和性能要求,以选择合适的单片机和外设接口。

其次,要进行合理的硬件设计和软件编程,以保证计算器的稳定性和可靠性。

最后,要进行充分的测试和调试,以确保计算器的各项功能正常工作。

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

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

基于单片机的简易计算器设计引言:计算器是一种广泛应用的电子设备,可以进行各种数学计算。

基于单片机的计算器是一种使用单片机作为核心处理器的计算器。

本文将介绍如何设计一个基于单片机的简易计算器。

一、设计思路:1.硬件设计:选择适合的单片机,LCD显示屏,按键开关和电源电路,将它们连接在一起组成计算器的硬件。

2.软件设计:使用单片机的编程语言编写程序,实现计算器功能,如加法、减法、乘法、除法等运算,以及清零、退格、等号等功能。

二、硬件设计:选择单片机:在设计单片机计算器时,我们可以选择MCU,如STC89C52、ATmega32等。

这些单片机性能稳定,功能强大,适合用于计算器的设计。

LCD显示屏:选择合适尺寸和接口的LCD显示屏,用于显示计算结果和输入的数字。

按键开关:选择合适的按键开关,用于接收用户的按键输入,如数字、运算符等。

电源电路:设计适合的电源电路,为计算器提供稳定的电源。

三、软件设计:1.初始化功能:启动计算器时,进行相关初始化操作,如清屏、设置计算器状态等。

2.数字输入功能:通过按键输入,将数字输入到计算器中,同时刷新LCD显示屏上的内容。

3.运算功能:根据用户输入的数字和运算符,进行相应的运算操作,如加法、减法、乘法、除法等。

4.清零功能:按下清零按钮时,将计算器的状态重置为初始状态。

5.退格功能:当用户输入错误时,可以通过按下退格按钮,删除最后一个输入的数字或运算符。

6.等号功能:用户按下等号按钮时,计算器将完成运算,并将结果显示在LCD屏上。

7.错误处理功能:当用户输入错误时,计算器应该给出合适的错误提示。

四、程序实现:1.确定单片机的引脚分配,将LCD显示屏、按键开关和单片机的引脚连接起来。

2.使用单片机的编程语言编写程序,实现计算器的功能。

3.根据运算符和数字的不同,确定相应的运算方法,并在LCD显示屏上显示结果。

4.使用条件语句和循环结构,实现计算器的控制逻辑。

5.通过编程实现按键响应功能,当用户按下相应按键时,执行相应的操作。

基于单片机的简易计算器设计原理图及程序代码

基于单片机的简易计算器设计原理图及程序代码
dsp[1]=0;
for(i=2;i<9;i++)
dsp[i]=12;
c=0;
}
while(dsp[0]==15&&c==0)
{
dsp[0]=keyscan();
if(dsp[0]==14||dsp[0]<10)
{
dsp[0]=14;
dsp[1]=0;
for(i=2;i<9;i++)
dsp[i]=12;
r[3]=(x%10000)/1000;
r[4]=(x%100000)/10000;
r[5]=(x%1000000)/100000;
r[6]=(x%10000000)/1000000;
r[7]=x/10000000;
}
}
if(k==13)
{
if(y==0)
{
BEEP=0;
r[0]=11;
r[1]=11;
if(k==10)
{
x=x+y;
if(x>99999999)
{
BEEP=0;
r[0]=11;
r[1]=11;
r[2]=10;
r[3]=12;
r[4]=12;
r[5]=12;
r[6]=12;
r[7]=12;
}
else
{
r[0]=x%10;
r[1]=(x%100)/10;
r[2]=(x%1000)/100;
P2=0xff;
}
}
ET0=1;
}
x=10000*x;
x=x+a[0]+a[1]*10+a[2]*100+a[3]*1000+a[5]*100000+a[6]*1000000+a[7]*10000000;

AVR汇编百例 - 计算程序

AVR汇编百例 - 计算程序

;范例9 ;16位整数被乘数*16位小数乘数-->16位整数积,精确到0.5 MUL165: RCALL MUL16 ;先得到32位积SBRS R14,7 ;积小数部分最高位为1,将整数部分加1RET ;否则返回LDI R17,255SUB R13,R17SBC R12,R17 ;以减去-1($FFFF)替代加1RET;范例10 ;32位被除数/16位除数-->16位商,精确到1DIV16: LDI R16,16 ;(r12r13r14r15)/(r10r11)-->r14r15DLOOP: LSL R15ROL R14ROL R13ROL R12 ;被除数左移1位BRCS DI1SUB R13,R11SBC R12,R10 ;移出位为0,被除数高位字减去除数试商BRCC DI2 ;够减,本位商为1ADD R13,R11ADC R12,R10 ;否则恢复被除数RJMP DI3 ;本位商0DI1: SUB R13,R11SBC R12,R10 ;移出位为1,被除数高位字减去除数DI2: INC R15 ;本位商1DI3: DEC R16BRNE DLOOPRET;范例11 ;32位被除数/16位除数-->16位商,精确到0.5;可能产生溢出!例$7FFFC000/$8000=$FFFF.8->$10000! DIV165: RCALL DIV16 ;(r12r13r14r15)/(r10r11)-->r14r15LSL R13ROL R12 ;余数乘2BRCS D165 ;有进位,转5入SUB R13,R11SBC R12,R10 ;否则,余数乘2减去除数BRCS D164 ;不够减,转4舍D165: CLR R13 ;否则将商增1SECADC R15,R13ADC R14,R13ADC R13,R13 ;若有溢出,溢出位在R13中RETD164: CLR R13RET;范例12 ;32位整数/16位整数->16整数+16位小数->4字节浮点数;(r12r13r14r15)/(r10r11)-->r12r13r14r15DIV16F: RCALL DIV16 ;先做整数除法MOV R9,r15MOV R8,r14 ;保存整数部分CLR R15CLR R14RCALL DIV16 ;除得小数部分MOV R11,R15MOV R15,R14MOV R13,R8MOV R14,R9 ;整数部分在r13r14,小数部分在r15r11LDI R17,$90 ;预设阶码$90(整数为16位)MOV R12,R17LDI R17,32 ;设32次右移DIV16L: SBRC R13,7RJMP NMLDN ;最高位为1,已完成规格化LSL R11 ;否则继续右移R13,R14,R15,R11ROL R15ROL R14ROL R13DEC R12 ;阶码减1DEC R17BRNE DIV16LCLR R12 ;右移达32次,浮点数为零,置零阶RETNMLDN: SBRS R11,7RJMP DIVRT ;欲舍去部分(R11)最高位为0,转4舍RCALL INC3 ;否则尾数部分增1BRNE DIVRTINC R12 ;尾数增1后变为0,改为0.5,并将阶码增1 DIVRT: LDI R17,$7F ;将尾数最高位清除,表示正数(负数不要清除)AND R13,R17 ;规格化浮点数在R12(阶码)R13R14R15(尾数)中RET;范例13 ;(R16,R12,R13,R14,R15)/(R10,R11)-->R13,R14,R15DIV24: CLR R16 ;32位整数/16位整数->24位整数,要求(R10)不为0;否则;要求(R12)<(R11)DIV40: LDI 17,24 ;40位整数/16位整数->24位整数要求(R16,R12)LXP: LSL R15 ; <(R10,R11)ROL R14ROL R13ROL R12ROL R16BRCC LXP1SUB R12,R11 ;右移后C=1 够减SBC R16,R10 ;被除数减去除数RJMP DIV0 ;本位商为1LXP1: SUB R12,R11 ;C=0SBC R16,R10 ;被除数减去除数试商BRCC DIV0 ;C=0 够减,本位商1ADD R12,R11ADC R16,R10 ;否则恢复被除数,本位商0RJMP DIV1DIV0: INC R15 ;记本位商1DIV1: DEC R17BRNE LXPLSL R12ROL R16BRCS GINC ;C=1,5入SUB R12,R11SBC R16,R10BRCS RET3 ;不够减,舍掉GINC: RCALL INC3 ;将商增1RET3: RET;范例14 ;定点整数(最大$FFFFFFFF)开平方子程序INTSQR: LDI R16,17 ;SQR(R12,R13,R14,R15)-->(r15r8r9) CLR R8 ;R8,R9存储平方根CLR R9 ;r10,r11,r12,r13,r14,r15CLR R10 ; r8, r9(根) r16 (counter)CLR R11 ;r10,r11:被开平方数扩展字节LDI R17,$40SQR0: SUB R12,R17SBC R11,R9SBC R10,R8BRCS SQR1SEC ;试根够减,本位根1RJMP SQR2SQR1: ADD R12,R17ADC R11,R9ADC R10,R8CLC ;否则恢复被开平方数,本位根0SQR2: DEC R16BRNE SQR3 ;when the No.17bit of root be getting SQR20:ADC R9,R15 ;R15 HA VE BEEN CLEARED!ADC R8,R15ADC R15,R15 ;将开出之根4舍5入,使根最大可达65536(=$10000)!RET ;for example:sqr.($ffff0001)≈$10000SQR3: ROL R9ROL R8 ;记本位根LSL R15ROL R14ROL R13ROL R12ROL R11ROL R10 ;被开平方数连同其扩展字节左移一位LSL R15ROL R14ROL R13ROL R12ROL R11ROL R10 ;被开平方数连同其扩展字节再次左移一位/左移2位开出1位根BRCS SQR20 ;被开平方数左移2位后,若进位置位,则仅表明第17位根;已被提前开出且该位根=1,将平方根增1,开平方结束。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<avr/io.h>#include<util/delay.h> //延时函数的头文件#include<avr/interrupt.h> // 中断函数的头文件#define uint unsigned int#define uchar unsigned char#define BIT(k) (1<<k) //利用上ICC软件的优点#define DI PORTC //夜晶的数据输入端#define No_key 255 //没有按键按下的返回值#define key_port PORTD //键盘输入#define key_ddr DDRD#define key_pin PIND //宏定义方便以后程序移植#define lone_key_port PORTB //独立键盘接口用于输入小数点#define lone_key_ddr DDRB#define lone_key_pin (PINB&BIT(0)) //读取独立键盘接口的电平#define rs_0 PORTA&=~BIT(0) //RS复位#define rs_1 PORTA|=BIT(0) //RS置位#define en_0 PORTA&=~BIT(1) //使能端复位#define en_1 PORTA|=BIT(1) //使能端置位const uchar table1[]=" You are welcome!"; // 初始显示字符const uchar table2[]="ERROR!"; //出错提示字符uchar a[7]={0,0,0,0,0,0,0},b[11]={0,0,0,0,0,0,0},a1[5]={0,0,0,0,0},b1[5]={0,0,0,0,0}; //用来存储输入的两个数字,位数不可超过10位uchar aa,bb,cc,dd; //用来记数输入的位数uchar sym; //用来保存符号uchar flag;//起动标志uchar fuhao; //符号标志uchar deflag1 ; //小数点标志uchar deflag2 ; //小数点标志uchar overflag; //数值溢出标志uchar allowflag=1; //符号允许标志,用于禁止连续两个符号的输出uchar negative; //负数标志,当是负数要作相应的处理long temp3,temp4; //计算的数值得数用其中一个变量存储即可,不用再浪费存开辟其他变量float temp1, temp2;const unsigned char key_table[16] ={7, 8, 9, 10,4, 5, 6, 11,1, 2, 3, 12,50,0, 21,13}; // 键盘编码可根据具体情况而设定void port_init(); //端口初始化void device_init(); //夜晶初始化void time_init(); //定时器初始化void wright_(uchar ); //夜晶写指令函数void wright_data(uchar date) ; //夜晶写数据函数void lcd_handle(uchar temp); //夜晶显示处理,该显示什么,不该显示什么uchar keyscan(); //键盘扫描void judgechar(uchar t); //判断字符为符号还是数字void decimal(uchar de) ; //判断是不是小数点,只能出现两个小数点,且不能连续出现void reset() ; //复位函数void calculate(void); //对数值进行计算void result(long value); //显示结果void flow_clew() ; //溢出提示函数int main(){port_init();device_init();time_init(); //初始化while(1){flow_clew() ; //溢出提示函数,一旦扫描到出错就会显示错误}}/***********中断服务程序***********/volatile unsigned int i; //中断服务程序中要使用全局变量,且要加volatile SIGNAL(SIG_OVERFLOW0){TCNT0=205; //重装初值i=keyscan(); //返回键盘扫描值if(i!=No_key) //确认有按键按下{if(i==50){wright_(0x01) ; //清显示_delay_ms(10); //延时等待清屏指令完成wright_(0x80);wright_data('0'); //重新显示0reset(); //初始化flag=1; // 标志起动}if(i<50&&flag) //条件为已经启动而且输入的是有效字符{judgechar(i); //判断是不是操作符,要是则要作相应的处理decimal(i); //判断是不是小数点输入,要是则要作相应的处理lcd_handle(i) ; //对输入的数据进行合理存储并加以显示}if(i==21) //按下了等号键{wright_data('='); //显示等号calculate(); //计算数值result(temp1); //拆分数值后显示结果}}}/*******定时器初始化*********/void time_init(){TCNT0=205; //初值255-205=50 50微秒TIMSK|=(1<<TOIE0);sei(); //开启总中断TCCR0|= (1<<CS01);//8分频8M/8=1M}/****端口初始化****/void port_init(){DI=0xff;DDRA|=BIT(0);DDRA|=BIT(1);//输出状态lone_key_ddr&=~BIT(0);lone_key_port|=BIT(0); //独立键盘接口设置为输入,并打开上拉电阻DDRD=0; //全部设为输入,有个上拉电阻,可以输入高电平DDRB=0xff;}/*******夜晶初始化********/void device_init(){en_0; //使能端拉低wright_(0x38) ; //初始化格式wright_(0x0c) ; //0x0e打开光标0x0c不显示光标0x0e光标不闪,0x0f光标闪wright_(0x01) ; //清显示wright_(0x80);for(i=0;i<17;i++){wright_data(table1[i]);_delay_ms(20);}}/******夜晶写入指令的函数***********/void wright_(uchar ){rs_0; //低电平时写指令DI=;_delay_ms(1);en_1;_delay_ms(1);en_0;}/******夜晶写入数据的函数**********/void wright_data(uchar data){rs_1; //高电平时写数据DI=data;_delay_ms(1);en_1;_delay_ms(1);en_0;}/**********4x4矩阵键盘及一个独立键盘的扫描函数*********/uchar keyscan(void){unsigned char temp,temp1,key,row,column;key_ddr = 0x0f;// 高四位输入列线/低四位输出到行线key_port = 0xf0;// 高四位打开上拉电阻/低四位输出低电平上拉电阻会把电平拉高if(lone_key_pin==0){_delay_ms(5); //延时消抖if(lone_key_pin==0){_delay_ms(90); //等待松手return(31);}}if((key_pin & 0xF0)!= 0xF0) // 作初检查有否键按下,没有,就返回如果列线不全为1,可能有键按下{_delay_ms(5);// 延时去抖动if((key_pin & 0xF0)!= 0xF0) //确认有按键按下{_delay_ms(1000); //延时等待松手for(row=0,key_port=0b11111110;row<4;row++){for(column=0,temp=0b11101111;column<4;column++)// 设置列线初始值1110{if((key_pin & 0xF0)==(temp & 0xF0))// 输入列线,查看这列有否键按下{key=4*row+column;// 键编码=4*行输入值+列扫描值key=key_table[key];// 键盘编码转换键值return (key);}temp<<=1;// 列线左移1位}key_port=((key_port<<1)|0x01);//行线扫描值左移1位,扫描下一行}}}return (No_key);}/****对键盘扫描返回值进行判断是不是为符号*******/void judgechar(uchar t) //用带参数的函数可以减少键盘扫描次数{if(t>9&&t<14&&allowflag) //符号围{fuhao=1; //标志为符号,为后面的程序作决断算完后再将其清零allowflag=0;//禁止下一个符号的输入,只能输入一个符号if(t==10) //输入的是减号{wright_data('/');}if(t==11) //输入的是减号{wright_data('*');}if(t==12) //输入的是减号{wright_data('-');}if(t==13) //输入的是减号{wright_data('+');}sym=t; //把符号的编号保存下来,方便以后调用}}/*****夜晶显示处理,该显示什么,不该显示什么*****/void lcd_handle(uchar temp) //用带参数的函数可以减少键盘扫描次数{if(temp>=0&&temp<10) //以下处理仅对数字有效{if(fuhao) //表示已经写了符号了,提示是输入第二个数了{if(deflag2) //判断为小数部分{if(dd<=3){wright_data('0'+temp); //输入一个数就显示一个数b1[++dd]=temp; //保存小数点后面的数字}elseoverflag=1;}else //整数部分if(bb<=5) //条件为位数还不足六位{wright_data('0'+temp); //输入一个数就显示一个数b[++bb]=temp; //输入的是第二个数保存的是整数部分}elseoverflag=1; //数值溢出}else // 输入的是第一个数{if(deflag1) //判断为小数部分{if(cc<=3){wright_data('0'+temp); //输入一个数就显示一个数a1[++cc]=temp; //保存小数点后面的数字}elseoverflag=1;}else //整数部分if(aa<=5) //条件为位数还不足六位{if(aa==0){wright_(0x80); //从每个位置起写}wright_data('0'+temp); //输入一个数就显示一个数a[++aa]=temp; // 保存的是整数部分}elseoverflag=1; //数值溢出}}}/*********重新初始化的函数*********/void reset() //按下复位键后变量要全部变到初始状态{uchar k;for(k=1;k<7;k++){a[k]=0;b[k]=0;}overflag=0; //溢出标志复位flag=0; //启动标志复位allowflag=1; //符号允许标志置位fuhao=0; //符号已使用标志复位aa=0;bb=0; //元素个数清零sym=0; // 符号的编码置0;}/***********对数值进行计算,a[],b[]存储的是数,sym操作符编号***********/void calculate(void){switch(aa) //根据位数代入对应的公式{case 1: temp1=a[aa];break;case 2: temp1=a[2]+a[1]*10;break;case 3: temp1=a[3]+a[2]*10+a[1]*100;break;case 4: temp1=a[4]+a[3]*10+a[2]*100+a[1]*1000;break;case 5: temp1=a[5]+a[4]*10+a[3]*100+a[2]*1000+a[1]*10000;break;case 6: temp1=a[6]+a[5]*10+a[4]*100+a[3]*1000+a[2]*10000+a[1]*100000;}switch(bb) //根据位数代入对应的公式{case 1: temp2=b[bb];break;case 2: temp2=b[2]+b[1]*10;break;case 3: temp2=b[3]+b[2]*10+b[1]*100;break;case 4: temp2=b[4]+b[3]*10+b[2]*100+b[1]*1000;break;case 5: temp2=b[5]+b[4]*10+b[3]*100+b[2]*1000+b[1]*10000;break;case 6: temp2=b[6]+b[5]*10+b[4]*100+b[3]*1000+b[2]*10000+b[1]*100000;}temp3=a1[1]*1000+a1[2]*100+a1[3]*10+a1[4];temp4=b1[1]*1000+b1[2]*100+b1[3]*10+b1[4]; //小数部分放大10000倍temp1=temp1+temp3/10000.0;temp2=temp2+temp4/10000.0; //整数与小数的结合switch(sym) //判断输入的是哪个操作符并作相应的计算{case 10: temp1=temp1/temp2;break;case 11: temp1=temp1*temp2;break;case 12: temp1=temp1-temp2;break;case 13: temp1=temp1+temp2;break;}if(temp1>999999.9999) //数据溢出要作处理overflag=1;temp1*=10000; //变成整数处理,方便if(temp1<0){temp1=-temp1; //变负为正negative=1; //负数标志}}/*****把结果数值拆分显示*********/void result(long value){uchar we[10];uchar k;uchar j;we[10]=value/1000000000;we[9]=value/100000000%10;we[8]=value/10000000%10;we[7]=value/1000000%10;we[6]=value/100000%10;we[5]=value/10000%10;we[4]=value/1000%10;we[3]=value/100%10;we[2]=value/10%10;we[1]=value%10;if(negative){wright_data('-'); //要是得到的结果是个负数得先输入个负号}for(k=10;k>5;k--) //只能十位以上的数字进行检测,个位的不管是不是零都要显示{if(we[k]!=0){break; //确定第一个非零数字,只显示有效数字}}for(j=k;j>0;j--) //从第一个非零数字开始显示{if(j==4)wright_data('.'); //小数部分前面要加个小数点wright_data('0'+we[j]);_delay_ms(2);}}/**********溢出提示函数*******************/void flow_clew(){uchar num;-if(overflag){wright_(0x80+0x40+5);for(num=0;num<6;num++){wright_data(table2[num]);_delay_ms(2);}}}/***********判断是不是小数点**************/void decimal(uchar de){if(de==31){if(fuhao==0&&deflag1==0) //条件为正在输入的是第一个数且此数之前还没有小数点出现{wright_data('.'); //显示小数点deflag1=1; //不能再有下一个小数点了,置位可以防止有第二个小数点}if(fuhao&&deflag2==0) //条件为正在输入的是第一个数且此数之前还没有小数点出现{wright_data('.'); //显示小数点deflag2=1; //不能再有下一个小数点了,置位可以防止有第二个小数点}}}- . - 总结资料-。

相关文档
最新文档