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

下载本文档

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

文档简介

1、 单片机课程设计 题目名称基于51单片机的简易计算器学生学院_ 信息工程学院_专业班级信息工程(应用电子方向)12(2)班 姓 名_虞君权_ 学 号 3112002559 指导教师_ _李优新 _ 2015年1月152一、课程设计的内容本次课程设计的内容从下面两个方面任选一个:一是在学院的单片机实验平台上进行,开发一个基于单片机与PWM技术的灯光调节系统,主要开发内容为按键定义、输入与防抖动技术、PWM调节技术以及显示技术等程序设计。二是利用51系列单片机及必要的外围芯片、输入输出等接口电路设计开发一个简易的单片机系统,在此基础上,自行设计一个单片机应用程序来实现一些实用的功能。通过这些内容的

2、设计、开发、安装、调试等一系列工作,熟练掌握单片机系统的开发流程与工作机理,加深对所学课程知识的理解与把握,为将来相关的研究开发工作打下坚实的基础。二、设计内容本次实验的任务就是要以51系列单片机为核心实现一个简易计算器计算器,它的结构非常简单,外部主要由4*4矩阵键盘和一个液晶显示屏构成,内部由一块AT89C51单片机构成,通过软件编程可实现简单加减乘除。三、方案论证经分析,计算器电路包括三个部分:显示电路、4*4键扫描电路、单片机微控制电路。具体如下:1) LCD显示电路 LCD1602作为一个成熟的产品,使用简单,模式固定,便于移植到各种类型的程序,但是初学者往往要注意结合LCD本身的时

3、序图来完善初始化程序。又以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,故采用LCD.2) 4*4键盘扫描电路(中断式,扫描式,反转式)用户设计行列键盘接口,一般常采用3 种方法读取键值。一种是中断式,外两种是扫描法和反转法。中断式:在键盘按下时产生一个外部中断通知CPU,并由中断处理程序通过不同的地址读取数据线上的状态,判断哪个案件被按下。本实验采用中断式实现用户键盘接口。扫描法:对键盘上的某一行送低电平,其他行为高电平,然后读取列值。若列值中有一位是低,则表明该行与低电平对应列的键被按下;否则,扫描下一行。反转法:先将所有行扫描线输出低电平,读列值。若列值有一位是低,则表明有键按下,

4、读列值;然后所有列扫描线输出低电平,再读行值。根据读到的值组合就可以查表1 得到的键码。这个就仁者见仁智者见智了,不过如果熟悉了扫描式,建议果断升级自己的硬件(很简单加个74LS08与门),故采用节省CPU的中断式扫描电路。 ) 单片机微控制电路微控制电路就是以AT89C51为核心的控制核心,主要注意晶振电路的接法和复位电路的接法。四、硬件电路的设计21 硬件设计电路框图51系列单片机系统4*4键盘LCD显示 晶振电路复位电路线路原理框图22 硬件设计电路的元件清单器件名称数量AT89C511按键1710K电阻9电容22uF1LCD16021晶振12MHz1电容30pF25K电位器123 硬件

5、设计电路图将4*4的键盘直接接在P2口上,用P0口作为LCD的显示输出,P3.2口的INT0作为外部中断位。五、软件设计程序及描述本程序组成可分为3个模块:矩阵键盘模块,LCD显示模块,和运算模块开始初始化参数初始化LCD显示有键输入?读取键码LCD显示数字键清零键功能键状态清零输入数值数值送显示缓冲YN等待数值输入结果送显示缓冲根据上次功能键和输入的数据计算结果本次功能键?等待数值输入结果送显示缓冲等待数值输入结果送显示缓冲六、硬软件的调试及方法我个人遇到的主要问题出现在LCD1602上,要不是我自己买了块新的LCD恐怕我的结论,就只能在软件仿真实现了。硬件上:在不加芯片调试时,LCD160

6、2只显示一排全黑,一般说明该元件是好的。(但也不一定,我那时就一直认为我的元件没坏);给15,16管脚分别接上+5v和0v,测试背光是否完好;给VEE接上电位器,检查对比度是否可调;七、实验结果与性能达标我的计算器能准确进行包括整数及小数的加减乘除四则运算。八、实验改进与心得体会这个实验给我的感觉,硬件和软件上都不是很难。在将烧写进单片机芯片之前,进行过仿真,所以方便很多,觉得proteus软件在逻辑电路仿真中非常有用,特别是进行单片机的仿真。我在这次实验上,又加深了对单片机的认识和理解,感觉收获的更多。 下面是源代码:#include<reg51.h>#include <i

7、ntrins.h>#include<stdio.h>#include<stdlib.h>#include<math.h>sbit RS= P12;sbit RW = P11;sbit E = P10; /定义lcd端口,RS:数据、命令选择端,RW:读、写选择端sbit H1=P24;sbit H2=P25;sbit H3=P26;sbit H4=P27;char input,flag,f,i; /定义每次的输入input,和对输入的分类标志flagchar buf16="",num110="",num210=&

8、quot;",result16="",sign; float temp;void delay(unsigned char x) /延时函数 unsigned char y; for(;x>0;x-) for(y=0;y<=110;y+) ;void delay_4nop()/延时函数 _nop_(); _nop_(); _nop_(); _nop_();void keyscan() /矩阵键盘扫描函数 P2=0XF7; if(H1=0) delay(10); if(H1=0) input='0' /扫描按键0,下面同理 flag=1;

9、while(H1=0); P2=0XF7; if(H2=0) delay(10); if(H2=0) input='.' flag=1; while(H2=0); P2=0XF7; if(H3=0) delay(10); if(H3=0) input='=' flag=3; while(H3=0); P2=0XF7; if(H4=0) delay(10); if(H4=0) input='/' flag=2; while(H4=0); P2=0XFB; if(H1=0) delay(10); if(H1=0) input='1'

10、flag=1; while(H1=0); P2=0XFB; if(H2=0) delay(10); if(H2=0) input='2' flag=1; while(H2=0); P2=0XFB; if(H3=0) delay(10); if(H3=0) input='3' flag=1; while(H3=0); P2=0XFB; if(H4=0) delay(10); if(H4=0) input='*' flag=2; while(H4=0); P2=0XFD; if(H1=0) delay(10); if(H1=0) input='

11、;4' flag=1; while(H1=0); P2=0XFD; if(H2=0) delay(10); if(H2=0) input='5' flag=1; while(H2=0); P2=0XFD; if(H3=0) delay(10); if(H3=0) input='6' flag=1; while(H3=0); P2=0XFD; if(H4=0) delay(10); if(H4=0) input='-' flag=2; while(H4=0); P2=0XFE; if(H1=0) delay(10); if(H1=0) in

12、put='7' flag=1; while(H1=0); P2=0XFE; if(H2=0) delay(10); if(H2=0) input='8' flag=1; while(H2=0); P2=0XFE; if(H3=0) delay(10); if(H3=0) input='9' flag=1; while(H3=0); P2=0XFE; if(H4=0) delay(10); if(H4=0) input='+' flag=2; while(H4=0); bit lcd_bz()/测试lcd是否忙碌,result=1表

13、示忙,=0表示不忙bit BF;RS = 0;RW = 1;E = 1; delay_4nop();BF =(bit)(P0 & 0x80);E = 0;return BF;void lcd_wcmd(unsigned char cmd)/对lcd写指令while(lcd_bz();/当LCD不忙碌时才写入指令RS = 0;RW = 0;E = 0;delay_4nop();P0 = cmd;delay_4nop();E = 1; delay_4nop(); /当E由1变为0时开始执行指令E = 0;void lcd_wdat(unsigned char dat) /对lcd写数据wh

14、ile(lcd_bz();/当LCD不忙碌时才写入指令RS = 1;RW = 0;E = 0; delay_4nop();P0 = dat;delay_4nop();E = 1;delay_4nop();E = 0;void lcd_init() /lcd初始化lcd_wcmd(0x38); /8位总线,双行显示,显示5*7的点阵字符delay(4);lcd_wcmd(0x0c); /开lcd显示,无光标,光标不闪烁delay(4);lcd_wcmd(0x06); /光标右移,屏幕上的所有文字不移动delay(4);lcd_wcmd(0x01); /清显示delay(4);void lcd_d

15、isplay(char a)/lcd显示输入输出结果的函数 unsigned char j; delay_4nop(); lcd_wcmd(0x00+0x80);/设置显示的位置 j = 0; while(aj!= '0') delay_4nop();lcd_wdat(aj);/显示的内容j+; delay_4nop();void null(char *a) /清空一个字符数组的函数 unsigned char j=0; while(*(a+j)!='0') *(a+j)='0' j+; void copy(char *a,char *b) /将

16、指针b所指字符串复制到指针a所指字符串 unsigned char j=0; while(*(b+j)!='0') *(a+j)=*(b+j);j+; void simplify_result(char *a) /去除结果的尾数中多余的零和小数点的函数 unsigned char j=15; while(*(a+j)='0')|(*(a+j)='0')|(*(a+j)='.')&&(j>0) if(*(a+j)='0') *(a+j)='0' else if(*(a+j)=&#

17、39;.') *(a+j)='0' break; j-; temp_to_buf()/将运算结果temp转移到buf()显示出来,并准备好下一次运算的函数 unsigned char j; sprintf(result,"%.5f",temp); null(buf); sign='0' simplify_result(result); copy(buf,result); j=0; while(bufj!='0') j+; i=j; null(result); null(num1); null(num2); temp=0

18、; lcd_wcmd(0x01); return(result,buf,num1,num2,temp,i);void equal_deal() /等号的运算处理 unsigned char j; for(j=f+1;bufj!='0'j+) /将符号之后的数装进字符串num2num2j-f-1=bufj; switch(sign) /根据之前输入的运算符号进行相应处理 case '+': temp=strtod(num1,NULL)+strtod(num2,NULL);/strtod()为将字符串转换为浮点数的函数 break;case '-': temp=strtod(num1,NULL)-strtod(num2,NULL); break;case '*': temp=strtod(num1,NULL)*strtod(num2,NULL); break; case '

温馨提示

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

评论

0/150

提交评论