1、单片机简易计算器 简易计算器的设计报告 报告名称 简易计算器设计 学生姓名 黄新潮 严祎乐 所在系别 计算机科学与信息管理系 所在班级 计算机102 二一三年十一月 简易计算器的设计报告一、设计任务1. 设计任务:用51单片机设计实现一个简易计算器,2. 设计要求:(1) 要求LCD显示。(2) 矩阵键盘输入。(3) 能进行2位数的加减乘除运算。(4) 除法精确到小数点两位。(5) 具有溢出报错功能。 二、系统设计方案 按照系统设计的功能的要求,初步确定设计系统由单片机主控模块、四位一体数码管显示模块、键扫描接口电路共三个主要模块组成。主控芯片使用51系列AT89C51单片机,键盘电路采用4*
2、4矩阵键盘电路。显示模块采用四位一体共阳极数码管。 三、硬件系统设计 1.单片机最小系统单片机最小系统就是支持主芯片正常工作的最小电路部分,包括主控芯片、复位电路和晶振电路。 2键盘接口电路计算器所需按键有: 键:1,2,3,4,5,6,7,8,9,0 功能键:+, - , *, / , = , R( 清零)共计16个按键,采用4*4矩阵键盘,键盘的行和列之间都有公共端相连,四行采用端口P0.0P0.3,四列采用端口P3.0P3.3,通过8个端口的的高低电平完成对矩阵键盘的控制。通过对16个按键进行编码,从而得到键盘的口地址,对比P1口德扫描结果和各按键的地址,我们就可以得到是哪个键按下,从而
3、完成键盘的功能。计算器输入数字和其他功能按键要用到很多按键,如果采用独立按键的方式,在这种情况下,编程会很简单,但是会占用大量的I/O 口资源,因此在很多情况下都不采用这种方式。为此,我们引入了矩阵键盘的应用,采用四条I/O 线作为行线,四条I/O 线作为列线组成键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为44个。这种行列式键盘结构能有效地提高单片机系统中I/O 口的利用率,如图所示: 键盘按键 键盘电路 3数码管显示采用4位一体的数码管对计算数据和结果进行显示,这里选取共阳数码管,利用NPN三极管对数码管进行驱动,为了节省I/O资源,采取动态显示的方法来显示计算数据
4、及结果。利用SN74LS244N锁存器来实现数码管的动态显示,P1口输出显示值,P2.0P2.3为位选端口。通过锁存器对段选信号的锁存,最终得到对数码管输入数据的控制。 四软件设计部分根据选题要求,系统编程如下所示:LCD部分:#include lcd.h#include key.hsbit BEEP=P36;#include #define uchar unsigned char/* LCD1602驱动程序 */*/sbit RS=P32; /寄存器选择位,将RS位定义为P2.0引脚sbit RW=P33; /读写选择位,将RW位定义为P2.1引脚sbit E =P34; /使能信号位,将E
5、位定义为P2.2引脚sbit BF=P17; /忙碌标志位,将BF位定义为P0.7引脚/*/*函数功能:延时1ms(3j+2)*i=(333+2)10=1010(微秒),可以认为是1毫秒*/void delay1ms() unsigned char i,j; for(i=0;i10;i+) for(j=0;j33;j+) ; /*函数功能:延时若干毫秒入口参数:n*/ void delay_lcd(unsigned char n) unsigned char i; for(i=0;in;i+) delay1ms(); /*函数功能:判断液晶模块的忙碌状态返回值:result。result=1,
6、忙碌;result=0,不忙*/ unsigned char BusyTest(void) bit result; RS=0; /根据规定,RS为低电平,RW为高电平时,可以读状态 RW=1; E=1; /E=1,才允许读写 _nop_(); /空操作 _nop_(); _nop_(); _nop_(); /空操作四个机器周期,给硬件反应时间 result=BF; /将忙碌标志电平赋给result E=0; return result; /*函数功能:将模式设置指令或显示地址写入液晶模块入口参数:dictate*/void WriteInstruction (unsigned char dic
7、tate) while(BusyTest()=1); /如果忙就等待 RS=0; /根据规定,RS和R/W同时为低电平时,可以写入指令 RW=0; E=0; /E置低电平(根据表8-6,写指令时,E为高脉冲, / 就是让E从0到1发生正跳变,所以应先置0 _nop_(); _nop_(); /空操作两个机器周期,给硬件反应时间 P1=dictate; /将数据送入P0口,即写入指令或地址 _nop_(); _nop_(); _nop_(); _nop_(); /空操作四个机器周期,给硬件反应时间 E=1; /E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); /
8、空操作四个机器周期,给硬件反应时间 E=0; /当E由高电平跳变成低电平时,液晶模块开始执行命令 /*函数功能:指定字符显示的实际地址入口参数:x*/ void WriteAddress(unsigned char x) WriteInstruction(x|0x80); /显示位置的确定方法规定为80H+地址码x /*函数功能:将数据(字符的标准ASCII码)写入液晶模块入口参数:y(为字符常量)*/ void WriteData(unsigned char y) while(BusyTest()=1); RS=1; /RS为高电平,RW为低电平时,可以写入数据 RW=0; E=0; /E置
9、低电平(根据表8-6,写指令时,E为高脉冲, / 就是让E从0到1发生正跳变,所以应先置0 P1=y; /将数据送入P0口,即将数据写入液晶模块 _nop_(); _nop_(); _nop_(); _nop_(); /空操作四个机器周期,给硬件反应时间 E=1; /E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); /空操作四个机器周期,给硬件反应时间 E=0; /当E由高电平跳变成低电平时,液晶模块开始执行命令 delay_lcd(5); /*函数功能:对LCD的显示模式进行初始化设置*/void LcdInitiate(void) delay_lcd(15
10、); /延时15ms,首次写指令时应给LCD一段较长的反应时间 WriteInstruction(0x38); /显示模式设置:162显示,57点阵,8位数据接口 delay_lcd(5); /延时5ms WriteInstruction(0x38); delay_lcd(5); WriteInstruction(0x38); delay_lcd(5); WriteInstruction(0x0C); /显示模式设置:显示开,无光标,不闪烁 delay_lcd(5); WriteInstruction(0x06); /显示模式设置:光标右移,字符不移 delay_lcd(5); WriteIn
11、struction(0x01); /清屏幕指令,将以前的显示内容清除 delay_lcd(5); /*函数功能:连续显示字符串*/void LcdWriteString(unsigned char address,unsigned char *Date) WriteAddress(address); while(*Date != 0) WriteData(*Date); /写数据 Date+; /地址+ delay_lcd(5); /适当延时 void ClearScreen() LcdWriteString(0x00, ); LcdWriteString(0x40, );void Delay
12、() unsigned int i; for(i=0;i32000;i+); void Welcome() unsigned int beep_delay; uchar j; ClearScreen(); BEEP=0; for(beep_delay=0;beep_delay5000;beep_delay+); BEEP=1; LcdWriteString(0x10,Welcome); LcdWriteString(0x50,Caculate); for(j=0;j 0; n-) for (m = 300; m 0; m-); unsigned char Keycan(void) /按键扫描程
13、序 P1.0-P1.3为行线 P1.4-P1.7为列线 unsigned char rcode, ccode; P2 = 0xF0; / 发全0行扫描码,列线输入 if(P2&0xF0) != 0xF0) / 若有键按下 delay1();/ 延时去抖动 if(P2&0xF0) != 0xF0) rcode = 0xFE; / 逐行扫描初值 while(rcode&0x10) != 0) P2 = rcode; / 输出行扫描码 if(P2&0xF0) != 0xF0) / 本行有键按下 ccode = (P2&0xF0)|0x0F; do;while(P2&0xF0) != 0xF0); /
14、等待键释放 return (rcode) + (ccode); / 返回键编码 else rcode = (rcode999) pos=-1; ClearScreen();/清屏 LcdWriteString(0x40,ERROR: OVERFLOW );Beep(); temp_number1=0; else if(flag_point=1) LcdWriteString(0x40, ); count_point+; KeyDispaly(pos,key_press); point_num = KeyToNum(key_press); for(i=0;i99) pos=-1; ClearSc
15、reen(); LcdWriteString(0x40,ERROR: OVERFLOW );Beep(); temp_number2=0; else if(flag_point=1) LcdWriteString(0x00, ); count_point+; KeyDispaly(pos+0x40,key_press); point_num = KeyToNum(key_press); for(i=0;icount_point;i+) point_num = point_num*0.1; temp_number2 = temp_number2+key_press; void Plus(void
16、) count_point=0; if(flag_plus|flag_minus|flag_multiply|flag_divide|flag_result)return; pos=pos+2;/空一格 LcdWriteString(0x40, ); KeyDispaly(pos,PLUS); pos+; KeyDispaly(pos, ); if(tab_num=0) tab_num=1; flag_plus=1; else / tab_num=0; / flag_plus=1; void Minus(void) count_point=0; if(flag_plus|flag_minus|flag_multiply|flag_divide|flag_result)return; pos=pos+2;/空一格 LcdWriteString(0x40, ); KeyDispaly(pos,MINUS); pos+; KeyDispaly(pos, ); if(tab_num=0) tab_num=1; flag_minus=1; els
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1