嵌入式实验报告-简易计算器
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一目的及要求
1实验目的
根据计算器的原理设计一个具有加减乘除功能的简易计算器。
2实验要求
(1)数字和结果用数码管显示。
(2)数字、+-*/、=、C用4X4键盘实现。
(3)计算结果正确,有出错提示。
二实验原理框图
基本工作原理:
本设计利用数码管和4*4矩阵式键盘实现了简易计算器的功能。
接通电源,数码管显示全0。
计算时,通过键盘输入需要计算的数字,该数字显示在数码管上,当键入等号时,计算结果显示在数码管上。
进行第二次运算时,按C键清除键盘结果。
当计算出现错误时,LED灯亮报警。
当计算结果超出数码管显示出现溢出时,报警电路也会报警。
报警输出为--。
四系统软件设计
1.数据输入模块
原理:通过4*4矩阵模块输入数字,在数码管上显示出来。
2.运算模块
原理:四种运算同步运行,通过按键加、减、乘、除选择输出对应的计算结果,当按键等号时,将所得结果反馈给运算模块输入端。
3.输出模块
原理:通过按键等号来控制显示运算对象还是运算结果,当等号按下时,输出计算结果,否则显示当前输入的数据。
当输出结果溢出是LED亮四次,同时数码管显示都为--。
五实验调试
首先按清零键清零。
然后进行调试。
输入数据2,再按乘法键,输入第二个数字6,按等号键,数码管显示12;再按除法键,输入第二个数据3,按等号键,数码管显示4;再按加法键,输入第三个数据7,依次按等号键,数码管显示11;按减法键,输入第四个数据99,依次按等号键,数码管显示-88。
若输入超出显示管的最大值或者超出数码管的位数,结果溢出,LED亮报警,同时数码管显示都为--。
如输入999999加上2 ,结果就溢出,LED灯亮四次报警。
六程序
#include "LPC2468.h" /* LPC24xx definitions */ #include "type.h"
#include "irq.h"
#include "target.h"
#include "timer.h"
#include "fio.h"
#include "keyboard.h"
#include "SPI.h"
extern BYTE seg_buf[50]; // LPC2468开发板使用此数组的0~5显示六个数码管;LPC2478板使用1~6
BYTE seg_copy1[7];
BYTE seg_copy2[7];
unsigned long Num1 =0;/*第一个输入的数字*/
unsigned long Num2 =0;/*第二个输入的数字*/
unsigned long Num3 =0;/*第二个输入的数字*/
extern BYTE KEY; // LPC2468开发板使用此数组的0~5显示六个数码管;LPC2478板使用1~6
enum {
Add =1,
Dec,
Mut,
Div,
nofuntion
}funtion;
/******************************************************************** *********
** Main Function main()
********************************************************************* *********/
int main (void)
{
unsigned char counter = 0; /*计算输入的数字的个数,超过6个则报警,运算结果超过6位数也报警*/
unsigned char cal_allow = 1; /*允许输入数字标志*/
unsigned char input_allow = 1;/*允许输入数字标志*/
unsigned char funtion_type = 0;/*运算功能*/
unsigned char Ne_num = 0;/*负数标志*/
DWORD value=0,i=0;
TargetResetInit();
enable_timer(1);
SPI_Init(8); // SPI总线速率为28.8/8 = 3.6 MHz Seg_Init(); // 数码管初始化
LedsInit();
for(i=0;i<7;i++)
{
seg_copy1[i]=0;
seg_copy2[i]=0;
seg_buf[i]=0;
}
counter = 0;
cal_allow = 1;
input_allow = 1;
funtion_type = nofuntion;
while ( 1 )
{
value = KEY;
/*输入数字*/
if(value>0 && value<11)
{
if(counter < 6&&input_allow==1)
{
if(counter == 0) seg_buf[1] = value-1;
else
{
for(i=0;i<counter;i++)
{
seg_buf[counter+1-i] = seg_buf[counter-i]; }
seg_buf[1] = value-1;
}
counter++;
}
if(counter == 6)
{
input_allow = 0;
LedOn(1);LedOn(2);LedOn(3);LedOn(4);
}
}
/*如果是“C”键,则清除显示,清除计算标志*/
if(value == 11)
{
for(i=0;i<7;i++)
{
seg_copy1[i]=0;
seg_copy2[i]=0;
seg_buf[i]=0;
}
counter = 0;
Num1 = 0;
Num2 = 0;
Num3 = 0;
cal_allow = 1;
input_allow = 1;
Ne_num = 0;/*负数标志*/
funtion_type = nofuntion;
}
/*如果是“+”键,则显示结果*/
if(value == 13 )
{
if(cal_allow == 1)
{
for(i=0;i<7;i++)
{
seg_copy1[i] = seg_buf[i];/*备份第一次输入的数字*/
seg_buf[i]=0; /*显示清零以准备第二次输入数字*/
}
funtion_type = Add;
counter = 0; /*计数器清零允许第二次计数*/
cal_allow =1; /*再等号按下前不能再按第二次*/
input_allow = 1; /*允许第二次输入数据*/
}
else
{
input_allow = 0; /*禁止按下2次功能键时候输入数据*/
}
/*如果是“-”键,则显示结果*/
if(value == 14&& cal_allow == 1)
{
if(cal_allow == 1)
{
for(i=0;i<7;i++)
{
seg_copy1[i] = seg_buf[i];/*备份第一次输入的数字*/
seg_buf[i]=0; /*显示清零以准备第二次输入数字*/
}
funtion_type = Dec;
counter = 0; /*计数器清零允许第二次计数*/
cal_allow =1; /*再等号按下前不能再按第二次*/
input_allow = 1; /*允许第二次输入数据*/
}
else
{
input_allow = 0; /*禁止按下2次功能键时候输入数据*/ }
}
/*如果是“X”键,则显示结果*/
if(value == 15 && cal_allow == 1)
{
if(cal_allow == 1)
{
for(i=0;i<7;i++)
seg_copy1[i] = seg_buf[i];/*备份第一次输入的数字*/
seg_buf[i]=0; /*显示清零以准备第二次输入数字*/
}
funtion_type = Mut;
counter = 0; /*计数器清零允许第二次计数*/
cal_allow =1; /*再等号按下前不能再按第二次*/
input_allow = 1; /*允许第二次输入数据*/
}
else
{
input_allow = 0; /*禁止按下2次功能键时候输入数据*/ }
}
/*如果是“/”键,则显示结果*/
if(value == 16 && cal_allow == 1)
{
if(cal_allow == 1)
{
for(i=0;i<7;i++)
{
seg_copy1[i] = seg_buf[i];/*备份第一次输入的数字*/
seg_buf[i]=0; /*显示清零以准备第二次输入数字*/
}
funtion_type = Div;
counter = 0; /*计数器清零允许第二次计数*/
cal_allow =1; /*再等号按下前不能再按第二次*/
input_allow = 1; /*允许第二次输入数据*/
}
else
{
input_allow = 0; /*禁止按下2次功能键时候输入数据*/ }
}
/*如果是“=”键,则清除显示,清除计算标志*/
if(value == 12)
{
for(i=0;i<7;i++)
{
seg_copy2[i] = seg_buf[i];/*拷贝第二次输入的数字*/
}
/*把输入的数字串1合成运算数字*/
Num1 = seg_copy1[6]*100000+seg_copy1[5]*10000+
seg_copy1[4]*1000 +seg_copy1[3]*100+
seg_copy1[2]*10 +seg_copy1[1];
/*把输入的数字串2合成运算数字*/
Num2 = seg_copy2[6]*100000+seg_copy2[5]*10000+
seg_copy2[4]*1000 +seg_copy2[3]*100+
seg_copy2[2]*10 +seg_copy2[1];
switch(funtion_type)
{
case Add:
{
Num1 = Num1+Num2;/*计算结果存在Num1中*/
break;
}
case Dec:
{
if(Num1==Num2) Num1 = 0;
else if(Num1>Num2)
{
Num3 = Num1-Num2;/*计算结果存在Num1中*/ Num1 = Num3;
}
else if(Num2 > Num1)
{
Num3 = Num2-Num1;
Ne_num =1;
Num1 = Num3;
}
break;
}
case Mut:
{
Num3 = Num1*Num2;/*计算结果存在Num1中*/ Num1 = Num3;
break;
}
case Div:
{
if(Num1>=Num2&&Num2!=0)
{
Num3 = Num1/Num2;/*计算结果存在Num1中*/
}
Num1 = Num3;
break;
}
default:break;
}
/*显示结果*/
if(Num1>999999||(Ne_num ==1&&Num1>99999)||Num2 ==0) {
for(i=0;i<7;i++)
{
seg_copy1[i]=0;
seg_copy2[i]=0;
seg_buf[i]=10;/*显示横杠表示计算溢出错误!*/
}
for(i=0;i<5;i++)
{
LedOn(1);LedOn(2);LedOn(3);LedOn(4);
delayMs(1,200);
LedOff(1);LedOff(2);LedOff(3);LedOff(4);
delayMs(1,200);
}
}
else
{
seg_buf[1] = Num1%10;
seg_buf[2] = (Num1%100)/10;
seg_buf[3] = (Num1%1000)/100;
seg_buf[4] = (Num1%10000)/1000;
seg_buf[5] = (Num1%100000)/10000;
seg_buf[6] = Num1/100000;
if(Ne_num ==1)
{
seg_buf[6] = 10;/*显示负号*/
}
}
}
delayMs(1,200);
}
}
/******************************************************************** *********
** End Of File
********************************************************************* ********/
七实验现象
(1)运行成功以后的计算机界面如图一:
图一
(2)正确输入6+6=12的现象如图二和图三:
图二
图三
(3)当进行除操作且除数为0时的现象如图四:
图四
七实验小结
在设计计算机的过程中,我们遇到了很多问题,但是都通过查资料和请教同学得到了解决。
但是当涉及到一些复杂的函数运算以及循环递归嵌套调用时还是感觉到很困难,希望在以后的学习中把这些问题都解决。