简易计算器课程设计.docx

上传人:b****0 文档编号:9043859 上传时间:2023-05-16 格式:DOCX 页数:25 大小:412.41KB
下载 相关 举报
简易计算器课程设计.docx_第1页
第1页 / 共25页
简易计算器课程设计.docx_第2页
第2页 / 共25页
简易计算器课程设计.docx_第3页
第3页 / 共25页
简易计算器课程设计.docx_第4页
第4页 / 共25页
简易计算器课程设计.docx_第5页
第5页 / 共25页
简易计算器课程设计.docx_第6页
第6页 / 共25页
简易计算器课程设计.docx_第7页
第7页 / 共25页
简易计算器课程设计.docx_第8页
第8页 / 共25页
简易计算器课程设计.docx_第9页
第9页 / 共25页
简易计算器课程设计.docx_第10页
第10页 / 共25页
简易计算器课程设计.docx_第11页
第11页 / 共25页
简易计算器课程设计.docx_第12页
第12页 / 共25页
简易计算器课程设计.docx_第13页
第13页 / 共25页
简易计算器课程设计.docx_第14页
第14页 / 共25页
简易计算器课程设计.docx_第15页
第15页 / 共25页
简易计算器课程设计.docx_第16页
第16页 / 共25页
简易计算器课程设计.docx_第17页
第17页 / 共25页
简易计算器课程设计.docx_第18页
第18页 / 共25页
简易计算器课程设计.docx_第19页
第19页 / 共25页
简易计算器课程设计.docx_第20页
第20页 / 共25页
亲,该文档总共25页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

简易计算器课程设计.docx

《简易计算器课程设计.docx》由会员分享,可在线阅读,更多相关《简易计算器课程设计.docx(25页珍藏版)》请在冰点文库上搜索。

简易计算器课程设计.docx

简易计算器课程设计

 

1、封面—————————————————————P1

2、目录—————————————————————P2

3、前言—————————————————————P3

4、关键字————————————————————P3

5、原理与总体方案————————————————P3

6、硬件设计———————————————————P6

7、调试—————————————————————P10

8、测试与分析——————————————————P11

9、总结—————————————————————P13

10、附件—————————————————————P14

前言

近几年,随着大规模集成电路的发展,各种便携式嵌入式设备,具有十分广阔的市场前景。

嵌入式系统是一种专用的计算机系统,作为装置或设备的一部分。

通常,嵌入式系统是一个控制程序存储在ROM中的嵌入式处理器控制板。

事实上,所有带有数字接口的设备,如手表、微波炉、录像机、汽车等,都使用嵌入式系统,有些嵌入式系统还包含操作系统,但大多数嵌入式系统都是是由单个程序实现整个控制逻辑。

在嵌入式系统中,数据和命令通过网络接口或串行口经过ARM程序处理后,或显示在LCD上,或传输到远端PC上。

本文通过周立功的LPC2106芯片完成的简易计算器,正是对嵌入式应用的学习和探索。

一、摘要:

计算器一般是指“电子计算器”,是能进行数学运算的手持机器,拥有集成电路芯片。

对于嵌入式系统,以其占用资源少、专用性强,在汽车电子、航空和工控领域得到了广泛地应用。

本设计就是先通过C语言进行相应程序的编写然后在ADS中进行运行最后导入PROTUES进行仿真。

最后利用ARM中的LPC2106芯片来控制液晶显示器和4X4矩阵式键盘,从而实现简单的加、减、乘、除等四则运算功能。

关键字:

中断,扫描,仿真,计算

 

二、原理与总体方案:

主程序在初始化后调用键盘程序,再判断返回的值。

若为数字0—9,则根据按键的次数进行保存和显示处理。

若为功能键,则先判断上次的功能键,根据代号执行不同功能,并将按键次数清零。

程序中键盘部分使用行列式扫描原理,若无键按下则调用动态显示程序,并继续检测键盘;若有键按下则得其键值,并通过查表转换为数字0—9和功能键与清零键的代号。

最后将计算结果拆分成个、十、百位,再返回主程序继续检测键盘并显示;若为清零键,则返回主程序的最开始。

电路设计与原理:

通过LPC2106芯片进行相应的设置来控制LCD显示器。

而通过对键盘上的值进行扫描,把相应的键值通过MM74C922芯片进行运算从而让ARM芯片接收。

1.系统整体流程图:

 

N

Y

2.

 

3.寄存器初始化:

 

2)仿真设计

仿真电路图:

仿真图形:

1.计算加法2.计算减法(结果为负数)

3.计算减法(结果为正数)4.计算乘法

5.计算除法(除法只能进行整除,无小数)

注:

本设计不能进行连续运算,只能进行当次运算,且只能进行单行显示。

进行除法时会自动取整,无小数。

显示器上不会显示加减乘除等运算符号,只有操作数和操作结果。

三、硬件设计:

器件

件数

LPC2106

1个

LED

1个

KEYPAD

1个

电源

若干

电源地

若干

电线

若干

3.1元件清单:

 

注:

无实物,以电路设计图为依准。

3.2键盘接口电路:

计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在这种情况下,编程会很简单,但是会占用大量的I/O口资源,因此在很多情况下都不采用这种方式,而是采用矩阵键盘的方案。

矩阵键盘采用四条I/O线作为行线,四条I/O线作为列线组成键盘,在行线和列线的每个交叉点上设置一个按键。

这样键盘上按键的个数就为4×4个。

这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。

矩阵键盘的工作原理:

计算器的键盘布局如图2.1所示:

一般有16个键组成,在单片机中正好可以用一个P口实现16个按键功能,这种形式在单片机系统中也最常用。

图2.1矩阵键盘布局图

电路中采用4*4键盘作为输入电路模块的话,电路连线会比较简单,而且这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。

但是在硬件电路设计的过程中,实验室没有提供矩阵键盘,所以我们将4*4的矩阵键盘换成了16个独立按键。

采用独立按键的方式的话,会占用大量的I/O口资源,但是在这种情况下,编程会很简单。

矩阵键盘内部电路图如图2.2所示。

图2.2矩阵键盘内部电路图

3.3显示模块:

本设计采用LCD1液晶显示屏来显示输出数据。

通过D0-D7引脚向LCD1写指令字或写数据以使LCD1实现不同的功能或显示相应数据。

LCD1管脚图如图2.3所示。

图2.3LCD1管脚图

3.4各模块的特性与作用:

3.4.1LPC2106的特性及引脚功能:

✧LPC2106是基于一个支持实时仿真和跟踪的32位ARMCPU的微处理器,并带有256kB嵌入的高速Flash存储器。

128位宽度的存储器接口和独特的加速结构使32位代码能够最大时钟速率下运行,并具有广泛应用。

含向量中断控制器,多个串行接口,两个三十二位定时器,片内晶振的操作频率范围:

10MHZ-25MHZ,两个低功耗模式:

空闲和掉电.

CPU操作电压范围:

1.65V-1.95V

图2.4LPC2106管脚图

管脚说明:

V3、V18:

供电电压

Vss、DBGSEL:

接地

XTAL1:

反向振荡放大器的输入及内部时钟工作电路的输入。

XTAL2:

来自反向振荡器的输出。

P0.0-P0.14作为GPIO接口,P0.15作为EINT2接口。

3.4.2LCD的特性:

✧LCD显示屏可以采用字符显示,当使用字符显示方式时,可以直接用外码作为输入数据,由显示屏自动给出显示字模数据,而无需由微处理器提供字模。

3.4.3数字式键盘的特性:

✧数字式键盘的实质仍是行列式键盘,4根行线和4根列线通过下拉电阻接地,在其表面贴有标示对应按键的膜,使得易于观察和操作,更加贴近使用者的需求。

3.4.4MM74C922的特性及其引脚功能:

MM74C922具有功耗低,电压为3-5V,三态门输出,与LPTTL兼容,输出锁存按下最后的键,用一个电容器就可以消除键盘抖动,两键轮回,行具有上拉功能,具有芯片内或芯片外时钟,最大开关电阻为管脚说明:

A-D为行键扫描电平输出端,1-4为列键输入读取端;

OSC为振荡器的外接引线端,可用外部的输入脉冲或电容器;

OE为数据输出端,低电平有效;DAV为数据输出有效,高电平有效;VCC为电源端,接3-5V;GND为接地端。

✧本设计中选用LPC2106的P0.0~P0.10与LCD显示屏相连,它们所输出信号控制显示屏上的显示,其中P0.0~P0.7分别接显示屏的D0~D7,P0.8~P0.10分别接显示屏的RS、RW、E接口;选用LPC2106的P0.11~P0.14连续4个IO口与芯片MM74C922和计算器键盘相连,可通过反转法检测到按下按键的键码,再通过查键盘对应的字符编码使LCD显示,其中A~D依次接键盘的4根行线,1~4依次接键盘的4根列线。

管脚说明:

A-D为行键扫描电平输出端,1-4为列键输入读取端;

OSC为振荡器的外接引线端,可用外部的输入脉冲或电容器;

OE为数据输出端,低电平有效;DAV为数据输出有效,高电平有效;VCC为电源端,接3-5V;GND为接地端。

✧本设计中选用LPC2106的P0.0~P0.10与LCD显示屏相连,它们所输出信号控制显示屏上的显示,其中P0.0~P0.7分别接显示屏的D0~D7,P0.8~P0.10分别接显示屏的RS、RW、E接口;选用LPC2106的P0.11~P0.14连续4个IO口与芯片MM74C922和计算器键盘相连,可通过反转法检测到按下按键的键码,再通过查键盘对应的字符编码使LCD显示,其中A~D依次接键盘的4根行线,1~4依次接键盘的4根列线。

四、调试:

4.1GPIO:

LPC2000系列ARM的GPIO具有如下特性:

a、可以独立控制每个GPIO口的方向(输入/输出模式);

b、可以独立设置每个GPIO的输出状态(高/低电平);

c、所有GPIO口在复位后默认为输入状态。

每个作为GPIO功能的引脚受到四个寄存器控制,分别为控制方向的IOxDIR、控制输出电平状态的IOxSET和IOxCLR、反映引脚电平状态的IOxPIN。

这四个寄存器构成一组,而一组寄存器控制着一个端口(P0、P1、P2或P3)。

注意事项:

引脚设置为输出方式时,输出状态由IOxSET和IOxCLR中最后操作的寄存器决定。

LPC2000系列ARM大部分的I/O引脚为推挽方式输出,但是具有

总线功能的I/O引脚为开漏输出(P0.2/3和P0.11/14)。

使用这些开漏输出的引脚作为GPIO功能,并用于高电平输出或者引脚状态输入时,要接上拉电阻才能正常使用。

推挽输出的I/O引脚正常拉出/灌入电流均为4mA,短时间极限值为40mA。

复位后,大部分引脚默认作为GPIO功能,并且均为输入状态。

但是,有部分引脚在复位后默认作为第二功能(如:

P0.27~P0.30在复位后默认为A/D输入引脚)。

4.2硬件和程序原理:

在键盘按键后,产生一个中断,mcu对键盘进行扫描,确定按下的键,如果不是等号,就把按下的字符依次存入数组,并在lcd显示表达式,如果是等号,就计算出数组中存入的表达式的值,并显示在lcd中。

计算表达式值的方法:

把表达式中的表示数值的字符转成数值存入一个数值数组,把表达式中的表示运算符的字符存入运算符数组;

关于四则运算优先级算法:

依次检索运算符数组,当遇到*号或者/号的时候,就先计算乘法或除法,算出结果后存入数值数组相应位置,然后删除此运算符和多余的数值,再重复检索,直到数值数组中只有一个数值为止,这个数值即是运算结果。

调用stdio.h库里的sprintf函数,把数值转化成字符数组,然后显示到lcd中。

 

五、测试与分析:

5.1ADS1.2新建工程:

5.2Proteus实时仿真:

六、总结:

对我们而言,知识上的收获重要,精神上的丰收更加可喜。

挫折是一份财富,经历是一份拥有。

这次实习必将成为我人生旅途上一个非常美好的回忆!

通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。

在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。

 

附件:

代码:

#include"config.h"

#include"math.h"

//宏定义

#defineLCD_RS1<<0

#defineLCD_RW1<<1

#defineLCD_E1<<2

#defineD71<<10//判断LCD忙碌

//函数声明

voidsystem_init(void);

voidLCDInit(void);

void__irqIRQ_EINT2(void);

intucKeyScan(void);

chartranslate();

voidarithmetic(longx,longy);

chartxt1[]="error!

",

txt2[]="dataoverflow",

txt3[]="";

//全局变量定义

longadd1=0,add2=0;

intoperators=0,iny=0;

uint8num=0,x,y,sign=0,count=0,k=0,repeat=0,flag=0;

unsignedintcode[4]={0x0E00000,0x0D00000,0x0B00000,0x0700000};//列线扫描电压,分为第1,2,3,4根列线

unsignedintucRow,ucLine;//行号,列号。

/***********************************************************************

*名称:

DelayNS()

*功能:

长软件延时

*入口参数:

dly延时参数,值越大,延时越久

*出口参数:

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

voidDelayNS(uint32dly)

{uint32i;

for(;dly>0;dly--)

{

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

}

}

/***********************************************************************

*名称:

Busy()

*功能:

LCD是否忙碌

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

voidBusy()

{

while

(1)

{

IOCLR=LCD_RS;

IOSET=LCD_RW;

if(!

(IOPIN&D7))break;

}

}

/***********************************************************************

*名称:

Command()

*功能:

LCD命令

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

voidCommand(charcom)

{

Busy();

IOCLR=0x0FFF;

IOCLR=LCD_RS;

IOCLR=LCD_RW;

IOSET=LCD_E;

IOSET=com<<3;

IOCLR=LCD_E;

}

/***********************************************************************

*名称:

LCDInit()

*功能:

LCD初始化

*入口参数:

*出口参数:

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

voidLCDInit()

{

Command(0x0C);//显示开/关控制命令

Command(0x38);//功能设置命令:

数据线长度为8位

//Command(0x80);//地址命令

Command(0x06);//输入方式设置

}

/***********************************************************************

*名称:

write()

*功能:

LCD写数据

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

voidwrite(chardata)

{

Busy();

IOCLR=0x0FFF;

IOSET=LCD_RS;

IOCLR=LCD_RW;

IOSET=LCD_E;

IOSET=data<<3;

DelayNS

(1);

IOCLR=LCD_E;

}

/***********************************************************************

*名称:

display()

*功能:

LCD显示

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

voiddisplay(longa)

{

longtemp,b,c=-1;

uint8lenth=1,i,j;

//Command(0x01);

if(a<0)

{

a=a*c;

write('-');

}

temp=a;

while((temp=temp/10)!

=0)lenth++;

for(i=lenth;i>0;i--)

{

b=1;

for(j=0;j

write(0x30+a/b);

a=a%b;

}

}//为低电平,其他为高电平。

//主函数

intmain()

{

system_init();

LCDInit();

while

(1)

ucKeyScan();

return(0);

}

/***********************************************************************

*名称:

system_init()

*功能:

system初始化函数

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

voidsystem_init()

{

//引脚功能选择

PINSEL0=0x80000000;//设置P0.15为EINT2,其余为GPIO

PINSEL1=0x00000000;//设置P0.15~P0.31为GPIO

IODIR=0x0f007ff;//设置P0.0-P0.10,P0.20-P0.23为输出,其余为输入

IOCLR=0x80000000;

//向量中断初始化

VICIntSelect=0x00;//设置P0.15为IRQ中断

VICVectAddr0=(uint32)IRQ_EINT2;

VICVectCntl0=0x30;

VICIntEnable=1<<16;//使能EINT2

//外部中断初始化

EXTMODE=1<<2;//设置为EINT2下降沿触发

EXTPOLAR=0;

EXTINT=1<<2;//清除EINT2中断标志

}

 

/***********************************************************************

*名称:

ucKeyScan()

*功能:

键盘扫描函数当有外部中断2时调用此函数,使用列扫描的方式获取键码,键码

由2位数字组成。

高位为行号低位为列号。

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

intucKeyScan()

{

unsignedintucTemp=0;//扫描状态暂存。

for(ucLine=0;ucLine<4;ucLine++)//行扫描

{

IOSET=code[ucLine];//输出扫描电位。

IOCLR=(~code[ucLine])&0xF00000;

//ucTemp=IOPIN>>24;

if(ucTemp!

=0x0F)//判断该列是否有按键按下。

continue;

}//返回按键编码。

格式为2位数,高位为列号,低位为行号。

}

/***********************************************************************

*名称:

IRQ_EINT2()

*功能:

EINT2中断服务程序

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

void__irqIRQ_EINT2(void)

{

unsignedintucTemp2=0,a;

ucTemp2=IOPIN>>24;

switch(ucTemp2)

{

case0x0E:

ucRow=00;break;//判断列号。

case0x0D:

ucRow=10;break;

case0x0B:

ucRow=20;break;

case0x07:

ucRow=30;break;

default:

ucRow=40;break;

}

num=ucRow+ucLine;

if(repeat==1&num!

=23&x!

=3)//计算结束后,若输入数字,在输入前清屏

{

Command(0x01);

add1=add2=sign=0;

count=0;

repeat=0;

DelayNS(10);//延时让LCD反应

}

switch(num)

{

case00:

write('7');k=8;break;

case01:

write('4');k=5;break;

case02:

write('1');k=2;break;

case03:

Command(0x01);k=0;add1=add2=sign=0;break;

case10:

write('8');k=9;break;

case11:

write('5');k=6;break;

case12:

write('2');k=3;break;

case13:

write('0');k=1;break;

case20:

write('9');k=10;break;

case21:

write('6');k=7;break;

case22:

write('3');k=4;break;

case23:

if(repeat==0)//是否重复

{

write('=');

count=1;

repeat=1;

arithmetic(add1,add2);

}

elsecount=0;

break;

case30:

if(sign==0)

{

write('/');

sign=1;

}

break;

case31:

if(sign==0)

{

write('X');

sign=2;

}

break;

case32:

if(sign==0)

{

write('-');

sign=3;

}

break;

case33:

if(sign==0)

{

write

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

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2