单片机课程设计论文简易计算器_第1页
单片机课程设计论文简易计算器_第2页
单片机课程设计论文简易计算器_第3页
单片机课程设计论文简易计算器_第4页
单片机课程设计论文简易计算器_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 电气信息学院单片机课程设计报告课题名称 4位数加法运算器的设计 专业班级 学 号 学生姓名 指导教师 评 分 目录自己写,不想写也可以不写,设计目标实现方法自己写。总结自己写。写完将红字删除。2012年 1月 3日 至 1 月 10 日目录第一章 绪 论.1第二章 方案论证与设计.22.1 设计目标和实现方法.22.2 方案论证与设计.2第三章 主体设计部分.3第四章 硬件设计.54.1 总体硬件设计.54.2 单片机接口电路说明.54.3 键盘接口电路.84.4 LCD显示模块.114.5 运算模块(单片机控制).124.6 软件设计.124.6.1主函数设计.124.6.2 键盘中断程序

2、设计.174.6.3 LCD显示程序.194.6.4 头文件< calc.h > .21第五章 仿真及调试.22总 结.23参考文献.24 - 25 -第一章 绪 论随着社会的发展,科学的进步,人们的生活水平在逐步的提高,尤其是微电子技术的发展,犹如雨后春笋般的变化电子产品的更新速度快就不足惊奇了, 单片机的应用已经越来越贴近生活,用单片机来实现一些电子设计也变得容易起来近年来,单片机以其体积小、价格廉、面向控制等独特优点,在各种工业控制、仪器仪表、设备、产品的自动化、智能化方面获得了广泛的应用与此同时,单片机应用系统的可靠性成为人们越来越关注的重要课题影响可靠性的因素是多方面的,

3、如构成系统的元器件本身的可靠性、系统本身各部分之间的相互耦合因素等其中系统的抗干扰性能是系统可靠性的重要指标本设计采用80c51 芯片,实现了利用单片机进行了一个简单计算器设计允许对输入数据进行加减乘除运算及LCD 显示如果设计对象是更为复杂的计算器系统,其实际原理与方法与本设计基本相同LCD液晶显示器是 Liquid Crystal Display 的简称,LCD 的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置TFT(薄膜晶体管),上基板玻璃上设置彩色滤光片,通过TFT上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的现在LCD已经替

4、代CRT成为主流,价格也已经下降了很多,并已充分的普及故采用LCD设计的关键所在,必须非常熟悉单片机的原理与结构,同时还要对整个设计流程有很好的把握,将单片机和其他模块完整的衔接本设计是基于51系列单片机来进行的数字计算器系统设计,可以完成计算器的键盘输入,进行加、减、乘、除基本四则运算,并在LCD上显示相应的结果;设计电路采用AT89C51单片机为主要控制电路,显示采用字符LCD静态显示;软件方面使用C语言编程,并用PROTUES仿真 。第二章 方案论证与设计2.1设计目标和实现方法为了满足计算器的基本要求,可以基本的运算(加减乘除),数据归零和出错警告提示,我们采用基于单片机设计计算器,并

5、用LCD显示器显示数据,4*4 的矩阵键盘实现数据输入分别对键盘输入检测模块;LCD显示模块;算术运算模块;错误处理及提示模块进行设计,并用Visio画系统方框图,keil与protues仿真分析其设计结果2.2方案论证与设计根据功能和指标要求,本系统选用MCS 51 单片机为主控机通过扩展必要的外围接口电路,实现对计算器的设计具体设计考虑如下:本系统选用AT89C51单片机为主控机通过扩展必要的外围接口电路,实现对计算器的设计,具体设计如下:(1)由于设计的计算器要进行四则运算,为了得到较好的显示效果,经综合分析后,最后采用LCD 显示数据和结果(2)采用键盘输入方式,键盘包括数字键(09)

6、、符号键(+、-、×、÷)、清除键(onc)和等号键(=),故只需要16 个按键即可,设计中采用集成的计算键盘(3)在执行过程中,开机显示零,等待键入数值,当键入数字,通过LCD显示出来,当键入+、-、*、/运算符,计算器在内部执行数值转换和存储,并等待再次键入数值,当再键入数值后将显示键入的数值,按等号就会在LCD上输出运算结果(4)错误提示:当计算器执行过程中有错误时,会在LCD上显示相应的提示,如:当输入的数值或计算得到的结果大于计算器的表示范围时,计算器会在LCD上提示E.第三章、主体设计部分(1)、系统模块图:(2)、算术运算程序流程图:(3)、系统总流程图:第四

7、章、硬件设计4.1、总体硬件设计:本设计选用AT89C51单片机为主控单元; 显示部分:采用LCD静态显示;按键部分:采用4*4键盘;用MM74C922为4*4键盘扫描IC,读取输入的键值总体设计效果如下图:4.2、单片机接口电路说明:1、手动上电复位电路:当VCC上电时,C充电,在10K电阻上出现电压,使得单片机复位;几个毫秒后,C充满,10K电阻上电流降为0,电压也为0,使得单片机进入工作状态工作期间,按下S,C放电S松手,C又充电,在10K电阻上出现电压,使得单片机复位几个毫秒后,单片机进入工作状态2、内部时钟模式电路:当单片机工作于内部时钟模式的时候,只需在XTAL1和XTAL2引脚连

8、接一个晶体振荡器或者陶瓷振荡器,并接两个电容后接地即可,在使用时对于电容的选择有一定的要求:当外接晶体振荡器的时候,电容值一般选择C1=C2=30+10pF或30-10pF;当外接陶瓷振荡器的时候,电容值一般选择C1=C2=40+10pF或40-10pF;3、AT89C51单片机引脚介绍:VCC: 供电电压 GND:接地 P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流当P0口的管脚第一次写1时,被定义为高阻输入P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须

9、被拉高 P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故在FLASH编程和校验时,P1口作为第八位地址接收 P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入并因此作为输入时,P2口的管脚被外部拉低,将输出电流这是由于内部上拉的缘故P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位在给出地址“1”时,它利用

10、内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容P2口在FLASH编程和校验时接收高八位地址信号和控制信号 P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流当P3口写入“1”后,它们被内部上拉为高电平,并用作输入作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故 P3口也可作为AT89C51的一些特殊功能口:P3.0 RXD(串行输入口) P3.1 TXD(串行输出口) P3.2 /INT0(外部中断0) P3.3 /INT1(外部中断1) P3.4 T0(记时器0外部输入) P3.5 T1(记时器1

11、外部输入) P3.6 /WR(外部数据存储器写选通) P3.7 /RD(外部数据存储器读选通) P3口同时为闪烁编程和编程校验接收一些控制信号 RST:复位输入当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间 ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节在FLASH编程期间,此引脚用于输入编程脉冲在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6因此它可用作对外部输出的脉冲或用于定时目的然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲如想禁止ALE的输出可在SFR8EH地址上置0此时, ALE只有在执行MOV

12、X,MOVC指令是ALE才起作用另外,该引脚被略微拉高如果微处理器在外部执行状态ALE禁止,置位无效 /PSEN:外部程序存储器的选通信号在由外部程序存储器取指期间,每个机器周期两次/PSEN有效但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现 /EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器在FLASH编程期间,此引脚也用于施加12V编程电源(VPP) XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入 XTAL2:来自

13、反向振荡器的输出4、单片机与复位、时钟电路连接电路图:4.3、键盘接口电路:计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在这种情况下,编程会很简单,但是会占用大量的I/O 口资源,因此在很多情况下都不采用这种方式,而是采用矩阵键盘的方案矩阵键盘采用四条I/O 线作为行线,四条I/O 线作为列线组成键盘,在行线和列线的每个交叉点上设置一个按键这样键盘上按键的个数就为4×4个这种行列式键盘结构能有效地提高单片机系统中I/O 口的利用率矩阵键盘的工作原理:计算器的键盘布局如图1所示:一般有16个键组成,在单片机中正好可以用一个P口实现16个按键功能,这种形式在单片机

14、系统中也最常用图 1 矩阵键盘布局图矩阵键盘内部电路图如图所示:我们在设计中还使用了6264静态RAM芯片,如图所示: Intel 6264的容量为8KB,是28引脚双列直插式芯片,采用CMOS工艺制造A12A0(address inputs):地址线,可寻址8KB的存储空间D7D0(data bus):数据线,双向,三态OE(output enable):读出允许信号,输入,低电平有效WE(write enable):写允许信号,输入,低电平有效CE1(chip enable):片选信号1,输入,在读/写方式时为低电平CE2(chip enable):片选信号2,输入,在读/写方式时为高电平

15、VCC:+5V工作电压GND:信号地Intel 6264的操作方式由OE,WE, CE1 , CE2的共同作用决定 写入:当WE和CE1为低电平,且OE和CE2为高电平时,数据输入缓冲器打开,数据由数据线D7D0写入被选中的存储单元 读出:当OE和CE1为低电平,且WE和CE2为高电平时,数据输出缓冲器选通,被选中单元的数据送到数据线D7D0上 保持:当CE1为高电平,CE2为任意时,芯片未被选中,处于保持状态,数据线呈现高阻状态此外,还用了74ls373八D锁存器,如图:内部引脚图如下:当三态允许控制端 OE 为低电平时,Q0Q7为正常逻辑状态,可用来驱动负载或总线当 OE 为高电平时,Q0

16、Q7 呈高阻态,即不驱动总线,也不为总线的负载,但锁存器内部的逻辑操作不受影响当锁存允许端 LE 为高电平时,Q 随数据 D 而变当 LE 为低电平时,D 被锁存在已建立的数据电平当 LE 端施密特触发器的输入滞后作用,使交流和直流噪声抗扰度被改善 400mV4.4、LCD显示模块:本设计采用LCD液晶显示器来显示输出数据通过D0-D7引脚向LCD写指令字或写数据以使LCD实现不同的功能或显示相应数据 LCD模块4.5、运算模块(单片机控制):MCS-51 单片机是在一块芯片中集成了CPU、RAM、ROM、定时器/计数器和多功能I/O等一台计算机所需要的基本功能部件如果按功能划分,它由如下功能

17、部件组成,即微处理器(CPU)、数据存储器(RAM)、程序存储器(ROM/EPROM)、并行I/O 口、串行口、定时器/计数器、中断系统及特殊功能寄存器(SFR)单片机是靠程序运行的,并且可以修改通过不同的程序实现不同的功能,尤其是特殊的独特的一些功能,通过使用单片机编写的程序可以实现高智能,高效率,以及高可靠性!因此我们采用单片机作为计算器的主要功能部件,可以很快地实现运算功能4.6、软件设计:4.6.1主函数设计:/* 主程序calc.c * * 2012/1/8 */#include <intrins.h>#include <reg51.h>#include &q

18、uot;calc.h"/定义变量static data LONG lvalue;static data LONG rvalue;static data CHAR currtoken;static data CHAR lasttoken;static data CHAR lastpress;static xdata CHAR outputbufferMAX_DISPLAY_CHAR;VOID main (VOID)/给变量初始化并调用汇编程序初始化LCD显示器; lvalue = 0; rvalue = 0; currtoken = '=' lasttoken = &#

19、39;0' initialise(); / 初始化LCD显示器 calc_output(OK); calc_evaluate(); VOID calc_evaluate() CHAR data key; INT data i; CHAR xdata numberMAX_DISPLAY_CHAR; CHAR xdata *bufferptr; / 程序开始前先清除所有缓冲区. for (i = 0; i <= MAX_DISPLAY_CHAR; i+) numberi = ' ' bufferptr = number; for (;) key = calc_getk

20、ey(); if (calc_testkey(key) / 按键测试为1是数字,将其写入缓冲区. / 数字的大小限制,主要是数字的数目. if (bufferptr != &numberMAX_DISPLAY_CHAR - 2) *bufferptr = key; calc_display(number); bufferptr+; else / 否则就是运算符. /分配值. if (lasttoken = '0') lvalue = calc_asciidec (number); else rvalue = calc_asciidec (number); /清除缓冲.

21、bufferptr = number; for (i = 0;i <= MAX_DISPLAY_CHAR; i+) numberi = ' ' /处理运算符. currtoken = key;if (currtoken = 'C') calc_opfunctions(currtoken); else calc_opfunctions(lasttoken); / 清除输出缓冲,为下一个运算符做准备. for (i = 0;i <= MAX_DISPLAY_CHAR;i+) outputbufferi = ' ' bufferptr =

22、number;/ 处理等于号,只需要保留以前的值.if (currtoken != 0x3D) lasttoken = currtoken; lastpress = key; VOID calc_opfunctions (CHAR token)/ 运算符的处理操作,左值保存结果. CHAR data result; switch(token) / 加. case '+' : if (currtoken = '=' ) | (lastpress >= 0x30) && (lastpress <=0x39) lvalue += rvalu

23、e; result = calc_chkerror(lvalue); else result = SLEEP; break; / 减.case '-' : if (currtoken = '=' ) | (lastpress >= 0x30) && (lastpress <=0x39) lvalue -= rvalue; result = calc_chkerror(lvalue); else result = SLEEP;break; / 乘.case '*' : if (currtoken = '='

24、; ) | (lastpress >= 0x30) && (lastpress <=0x39) lvalue *= rvalue; result = calc_chkerror(lvalue); else result = SLEEP;break;/ 除. case '/' : if (currtoken = '=' ) | (lastpress >= 0x30) && (lastpress <=0x39) if (rvalue) lvalue /= rvalue; result = calc_chkerr

25、or(lvalue); else result = ERROR; else result = SLEEP;break;/ 清零. case 'C' : lvalue = 0; rvalue = 0; currtoken = '0' lasttoken = '0' result = OK; break;default : result = SLEEP; calc_output(result); INT calc_chkerror (LONG num)/ 检查最低位数和最高位数从-9999到+9999 if (num >= -9999) &am

26、p;& (num <= 9999) return OK; else return ERROR; VOID calc_output (INT status)/ 根据操作状态输出 switch (status) case OK : calc_display(calc_decascii(lvalue); break; case SLEEP : break;case ERROR : calc_display("E "); break; default : calc_display("E "); break; LONG calc_asciidec (

27、CHAR *buffer)/ 将ASCII码转换为浮点数. LONG data value; LONG data digit; value = 0; while (*buffer != ' ') digit = *buffer - 48; value = value*10 + digit; buffer+; return value; CHAR *calc_decascii (LONG num)/ 将浮点数转换成ASCII码. LONG data temp = num; CHAR xdata *arrayptr = &outputbufferMAX_DISPLAY_CH

28、AR; LONG data divisor = 10; LONG data result; CHAR data remainder,asciival; INT data i; / 如果计算结果是0,直接将0插入缓冲区即可. if (!temp) *arrayptr = 48; goto done; / 处理负数. if (temp < 0) outputbuffer0 = '-' temp -= 2*temp; for (i=0 ; i < sizeof(outputbuffer) ; i+) remainder = temp % divisor; result =

29、 temp / divisor; / 运行结束,将空格插入缓冲区 if (!remainder) && (!result) *arrayptr = ' ' else asciival = remainder + 48; *arrayptr = asciival; temp /= 10; / 为“-“保存一个空间; if (arrayptr != &outputbuffer1) arrayptr-; done: return outputbuffer; CHAR calc_testkey (CHAR key)/ 测试按键是数字还是运算符;返回1代表数字,0

30、代表运算符; if (key >= 0x30) && (key <= 0x39) return 1; else return 0; /* 输入输出部分函数 */CHAR calc_getkey (VOID)/使用*Keypad_Read* 汇编文件函数扫描键和返回按下的键的 ASCII 值 CHAR data mykey; do mykey = input(); while (mykey = 0); /等待按键; return mykey; VOID calc_display (CHAR bufMAX_DISPLAY_CHAR)/ 使用输出和 *LCD_Write*

31、 的汇编文件输出LCD的值 INT data i = 0; clearscreen(); for (i ; i <= MAX_DISPLAY_CHAR ; i+) if (bufi != ' ') output(bufi); /输出LCD的值; 4.6.2、键盘中断程序设计:/* 控制按键的汇编 * *keypad.asm * * 2012/1/8 */NAME KEYPAD; 从键盘读出一个字符然后返回到R7中.;设立部分无参输入程序.?PR?input?KEYPAD SEGMENT CODEPUBLICinput?DT?input?KEYPAD SEGMENT DAT

32、ARSEG ?DT?input?KEYPAD ; 局部变量的输出程序段.KEY_ROW1equ0EFhKEY_ROW2equ0DFhKEY_ROW3equ0BFhKEY_ROW4equ07Fhkeyflags:ds16RSEG ?PR?input?KEYPAD ; 输出程序的代码段.input:keyscan:push DPHpush DPLmov R0,#keyflags ; R0 处理按键的切换字节mov R1,#KEY_ROW1; R1 处理键盘的行地址mov R2,#4; R2 计数行ksrow:mov P2,R1; 将行地址给P2口nopmov A,P1; 从P1口读取列地址mov

33、R3,#4; 每行按键用R3计数anl A,#3Fhks0:rrc A; 移动到下一位mov R4,A; R4 保存行数据jc ks1; 如果没有按键就跳到ks1mov A,R0; 测试按键是否已被按下mov R0,#1; 按下之后将R0给#0,标志按下jz ksnew; 如果有新的按键按下就跳转到ksnewjmp ks2ks1:mov R0,#0; 没有按键就标记为0ks2:inc R0; R0自增,进入这行里面的下一个按键的循环mov A,R4djnz R3,ks0mov A,R1; 将R1循环移位去处理下一行rl A mov R1,Adjnz R2,ksrowclr Amov R7,A;

34、 如果没有按键,返回0.jmp ksendksnew:mov DPTR,#keycodes;发现有新的按键按下:mov A,R0; 按键的标志从R0取出clr Csubb A,#keyflagsmovc A,A+DPTRmov R7,A; 将按键给R7.ksend:mov P2,#0FFhpop DPLpop DPHret;按键表keycodes:db '7','8','9', '/'db'4','5','6', '*'db'1','2'

35、;,'3', '-'db'C','0','=', '+'END4.6.3、LCD显示程序:/* LCD显示的汇编代码 * * 时间2013/1/8 * * */NAME LCD;设置代码段和输出:LCD SEGMENT CODERSEG LCD PUBLIC _output PUBLIC initialise PUBLIC clearscreen;LCD寄存器地址.LCD_CMD_WRequ 00hLCD_DATA_WRequ01hLCD_BUSY_RDequ02hLCD_DATA_RDequ03h

36、LCD_PAGEequ80h;LCD命令LCD_CLSequ1LCD_HOMEequ2LCD_SETMODEequ4LCD_SETVISIBLEequ8LCD_SHIFTequ16LCD_SETFUNCTIONequ32LCD_SETCGADDRequ64LCD_SETDDADDRequ128; LCD显示器的初始化.initialise: mov A,#030h;1 line, 8 bitscall wrcmdmov A,#LCD_SETVISIBLE + 4call wrcmdmov A,#LCD_SETDDADDR+15; 从显示器的右边开始显示;call wrcmdmov A,#LCD

37、_SETMODE + 3; 自动递增,显示左移. call wrcmd ret;写数据之前之前先将R7里面的参数写到累加器中保存;_output:mov A,R7call wrdataret;清空LCD显示重新初始化;clearscreen:mov A,#LCD_CLScall wrcmdmov A,#LCD_SETDDADDR + 15call wrcmdret;*;* SUBROUTINES *;*;写命令的子程序:wrcmd:mov P2,#LCD_PAGEmov R0,#LCD_CMD_WRmovx R0,Ajmp wtbusy; 该子程序将一个字符写到LCD显示器里.wrdata:M

38、OV P2,#LCD_PAGEMOV R0,#LCD_DATA_WRMOV A,R7MOVX R0,A;子程序等待繁忙的状态.wtbusy:MOV R1,#LCD_BUSY_RDMOVX A,R1JB ACC.7,wtbusy ret END4.6.4、头文件< calc.h >:typedef void VOID;typedef int INT;typedef unsigned short WORD;typedef char CHAR;typedef unsigned char BYTE;typedef float FLOAT;typedef double DOUBLE;type

39、def long LONG;/定义ASCII字符在显示屏上可以容纳的最大数量.#define MAX_DISPLAY_CHAR 9/错误的处理状态enum ERROR OK = 0, SLEEP = 1, ERROR = 2;/* 函数原型 */VOID calc_evaluate();/Operator indirect function.VOID calc_opfunctions (CHAR token);/Utility functions.CHAR calc_testkey (CHAR ch);LONG calc_asciidec (CHAR *buffer);CHAR *calc_decascii (LONG num);INT calc_chkerror (LONG num);VOID calc_output (INT status);/ I/O functions.CHAR calc_getkey (VOID);VOID calc_display (CHAR bufMAX_DISPLAY_CHAR);/Assembly Function prototypes.void initialise();char input ();char output(char ch);void cle

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论