单片机实训报告———简易计算器姓名***学号***专业***学校***指导教师 ***实训时间2014.06.23-2014.06.29目录中文摘要............................................................1 关键词.............................................................1 1 实训任务.........................................................1 1.1 主要功能设计................................................11.2 任务目的....................................................12 整体设计方案.....................................................1 2.1 方案论证....................................................12.2 系统框图....................................................23 控制软件设计....................................................2 3.1 程序时序总图...............................................2 3.2 液晶显示软件设计............................................3 3.3 键盘输入软件设计...........................................53.4 计算函数设置...............................................74 软件调试........................................................8 个人小结...........................................................8参考文献...........................................................9附录...............................................................9摘要:计算器是人们的日常生活中是最常见的电子产品之一,它应用极广、发展迅猛,并且不断出现着拥有更加强大功能的计算器。
为了解和研究计算器,本次实训设计制作了一个简易计算器,能够在五位的计算围进行“+”、“-”、“*”、“/”的基本运算,能进行负数的精确结果显示。
该计算器以AT89C51单片机芯片作为核心。
采用LCD1602工业字符液晶进行显示。
完成的计算器经过检验能够完整的实现预设功能,各种细节完善,具有很高的使用价值。
关键词:单片机;简易计算器;AT89C51;LCD16021实训任务1.1 主要功能设计以AT89C51单片机芯片为核心来制作一个简易计算器,外部由4*4矩阵键盘和一个LCD1602工业字符型液晶显示屏构成,部由一块AT89C51单片机构成,通过软件编程可实现简单加减乘除。
1.2 任务目的通过本次实训提高我们的单片机硬件设计、软件编程能力,自主学习到更多的单片机应用知识。
2 整体设计方案2.1 方案论证计算器电路包括三个部分:显示电路、4*4键扫描电路、单片机微控制电路。
具体如下:(1)LCD显示电路LCD1602作为一个成熟的产品,使用简单,模式固定,便于移植到各种类型的程序,但是初学者往往要注意结合LCD本身的时序图来完善初始化程序。
又以其微功耗、体积小、显示容丰富、超薄轻巧的诸多优点,故采用LCD.(2)4*4键盘扫描电路对键盘上的某一行送低电平,其他行为高电平,然后读取列值。
若列值中有一位是低,则表明该行与低电平对应列的键被按下;否则,扫描下一行。
根据读到的值组合就可以查表 1 得到的键码,因为编程的方式,本次实训采用逐行扫描来读取键值,方便程序编写。
(3)单片机微控制电路:微控制电路就是以AT89C51为核心的控制核心,主要注意晶振电路的接法和复位电路的接法。
2.2 系统框图系统框图3 控制软件设计:实训中采用C语言对单片机进行编程,采用的是自下而上的设计方式,先设计出每一个模块(子程序),然后再慢慢扩大,最后组成程序。
3.1 程序总时序图3.2 液晶显示软件设计(1)显示流程开始液晶初始化调用显示字序液晶显示结束(2)1602液晶显示时序图,通过时序图,所有编程问题都可以得以解决。
(3)由时序图可以写出液晶的初始化函数、功能设置函数、清屏函数、写指令函数、写数据函数。
void delay1() //采用软件实现延时,5个机器周期{_nop_();_nop_();_nop_();}void int1() //LCD初始化{lcd_w_cmd(0x3c);lcd_w_cmd(0x0c);lcd_w_cmd(0x01);lcd_w_cmd(0x06);lcd_w_cmd(0x80);}unsigned char lcd_r_start() //读状态字{unsigned char s;RW=1;delay1();RS=0;delay1();E=1;delay1();s=P1;delay1();E=0;delay1();RW=0;delay1();return(s);}void lcd_w_cmd(unsigned char ) //写命令字{unsigned char g;do{g=lcd_r_start();g=g&0x80;delay(2);}while(g!=0);RW=0;delay1();RS=0;delay1();E=1;delay1();P1=;delay1();E=0;delay1();RW=1;delay(255);}void lcd_w_dat (unsigned char dat) //写数据{unsigned char g;do{g=lcd_r_start();g=g&0x80;delay(2);}while(g!=0);RW=0;delay1();RS=1;delay1();E=1;delay1();P1=dat;delay1();E=0;delay1();RW=1;delay(255);}3.3 键盘输入软件设计(1)键盘输入程序运行时序图(2)键盘扫描程序unsigned char scan_key(){unsigned char i,temp,m,n,k;bit find=0;P0=0xff;k=0x01;for(i=0;i<4;i++){P2=~k;temp=~P0;temp=temp&0x0f;k<<=1;if(temp!=0x00){m=i;find=1;switch(temp){case 0x01:n=0;break;case 0x02:n=1;break;case 0x04:n=2;break;case 0x08:n=3;break;default:break;}}}if(find==0) return 0xff;else return(n*4+m);}3.4 计算函数设置因为只有16个健,所以计算上只设计了加减乘除的功能,下面是几个计算的程序unsigned int jian() //减法函数{if(a>=b){q=0;return(a-b);}if(a<b){q=1;return(b-a);}if(a2[i]<10&&m==0) /第一个数{a=a*10+a2[i];}if(a2[i]!=14&&a2[i]>9) //四则运算的判断{m=1; w=a2[i];}if(a2[i]<10&&m==1) //第二个数{b=b*10+a2[i];}if(a2[i]==13||o==1) //清零{o=0;lcd_w_cmd(0x01);lcd_w_cmd(0x80);a=0;b=0;wan=0;qian=0;bai=0;shi=0;ge=0;m=0;sum=0;}if(a2[i]==14) //等号{l++;p=jian(); //调用减法函数switch(w){case 10:sum=a/b;break; //除法case 11:sum=a*b;break; //乘法case 12:sum=p;if(q==1)lcd_w_dat('-');break; //减法case 15:sum=a+b;break; //加法default:break;}wan=sum/10000; //万位qian=(sum-wan*10000)/1000; //千位bai=(sum-wan*10000-qian*1000)/100; //百位shi=(sum-wan*10000-qian*1000-bai*100)/10; //十位ge=sum%10; //个位if(wan!=0) //万位显示{lcd_w_dat(a1[wan]);lcd_w_dat(a1[qian]);lcd_w_dat(a1[bai]);lcd_w_dat(a1[shi]);lcd_w_dat(a1[ge]);}if(wan==0&&qian!=0) //千位显示{lcd_w_dat(a1[qian]);lcd_w_dat(a1[bai]);lcd_w_dat(a1[shi]);lcd_w_dat(a1[ge]);}if(wan==0&&qian==0&&bai!=0) //百位显示{lcd_w_dat(a1[bai]);lcd_w_dat(a1[shi]);lcd_w_dat(a1[ge]);}if(wan==0&&qian==0&&bai==0&&shi!=0) //十位显示{lcd_w_dat(a1[shi]);lcd_w_dat(a1[ge]);}if(wan==0&&qian==0&&bai==0&&shi==0) //个位显示{lcd_w_dat(a1[ge]);}if(l%2!=0) //换行{lcd_w_cmd(0xc0);}if(l%2==0) //换屏{lcd_w_cmd(0x80);o=1;}a=0;b=0;wan=0;qian=0;bai=0;shi=0;ge=0;m=0;sum=0; //运算完一次全部清零}4 软件调试:(1)编程前先画了流程图,这样思路清晰,能按部就班的完成。