单片机课程设计报告简易计算器源程序剖析Word下载.docx
《单片机课程设计报告简易计算器源程序剖析Word下载.docx》由会员分享,可在线阅读,更多相关《单片机课程设计报告简易计算器源程序剖析Word下载.docx(17页珍藏版)》请在冰豆网上搜索。
电源电路
键盘电路
单片机最小系统
前面叙述了该系统的设计说明,系统采用了比较简单的设计方案,所以该系统的硬件设计的总外围电路不会产生过多的干扰。
在下面的阐述中,对系统的外围电路分别予以介绍。
键盘部分采用编码键盘,显示部分采用LCD液晶显示屏完全能够很好的实现显示方面的要求。
2.2系统电路设计
2.2.1键盘电路
键盘可分为两类:
编码键盘和非编码键盘。
编码键盘是较多按键(20个以上)和专用驱动芯片的组合,当按下某个按键时,它能够处理按键抖动、连击等问题,直接输出按键的编码,无需系统软件干预。
通用计算机使用的标准键盘就是编码键盘。
在智能仪器中,使用并行接口芯片8279或串行接口芯片HD7279均可以组成编码键盘,同时还可以兼顾数码管的显示驱动,其相关的接口电路和接口软件均可在芯片资料中得到。
当系统功能比较复杂,按键数量很多时,采用编码键盘可以简化软件设计。
非编码键盘成本低廉。
从成本角度出发,本设计选用的是非编码键盘。
如图2-2-1
图2-2-1扫描键盘电路
2.2.2显示电路
当系统需要显示少量数据时,采用LCD液晶显示屏进行显示是一种经济实用的方法。
P0口作为液晶显示的数据端口,P3.5-P3.7口作为其控制端口,控制LCD液晶显示屏显示输出数据。
最终电路如图2-2-2所示:
图2-2-2LCD液晶显示屏显示
3软件设计
3.1主程序
主程序主要是用来对LCD液晶显示屏进行初始化的。
对输入按键判断,然后进行加减乘除,最后计算出结果,显示出计算结果。
流程图如图3-1所示:
3.2子程序
3.2.1键盘扫描子程序
键盘扫描子程序,首先读出P1的低四位,然后读出P1口的高四位。
然后键值并显示缓存。
然后将键如的值转换为ASCII码然后就可以软件来设置硬件按键各个键代表的内容。
读键程序使用的是反转法读键,不管键盘矩阵的规模大小,均进行两次读键。
第一次所有行线均输出低电平,从所有读入键盘信息(列信息);
第二次所有列线均输出低电平,从所有行线读入键盘信息(行信息)。
数字键按下则将相应的数字送入缓存区,功能键按下则执行相应的程序。
3.2.2显示模块子程序
显示模块程序首先要对显示模块进行初始化;
然后控制光标的位置;
定义液晶显示的控制端口,用SBIT指令完成;
然后设置清屏、关闭显示、归位、开显示、显示位置的首地址等等。
4安装与调试
将所有的元器件摆放在好,首先焊接51单片机的底座,确定简易计算器的键盘和液晶显示的排练位置,先将51单片机的底座焊接四周的四个点固定就好,之后再随需要焊接必要的底座引脚,接着焊接比较复杂的矩阵按键,,各个按键之间的连接,使用细导线。
在使用细导线焊接两个焊点时,先将两个焊点焊上焊锡。
之后加热焊锡再将细导线接入,使之固定。
之后再将单片机的晶振和复位电路焊入单片机的地座上。
确定最小单片机系统焊接完整后再将按键扫描接在单片机的P1口,后将各个细导线按顺序分别焊到单片机的P1端口的引脚处。
再将1602液晶显示的底座焊接在电路板上的相应位置上,从单片机和电源处将细导线按顺序分别焊接到液晶显示的底座上。
将51单片机烧入C语言程序,插入电路板上,再检查电路的接线和焊点处是否有焊错和虚焊,最重要的是要检查电路是否短路。
诺是没有错误则可以通电进行测试。
首先接上电源,打开开关,在液晶显示屏上显示出“0”则表示液晶显示是正常的,如果没有显示字符等,则可以查看电路中在液晶显示的第三个引脚上的接线是否正确,可改变其电压,使1602液晶显示的字符的亮度改变。
如显示正常则可测试矩阵按键,逐个按下没个按键,观察每个按键的功能是否正确。
如果正确则调试结束。
图4-1实物图(正面)
图4-2实物图(反面)
5性能测试与结果分析
将已经焊接好的简易计算器通电后,测试计算器的最大计算值与最小计算值。
经过测试计算器的最大运算值可以是9999*9999,最小的运算值可以是0。
经过接不同的电源测试,51单片机的工作电压范围为3V~5.5V。
实物效果图如图5-1所示:
图5-1实物效果图
6心得体会
在硬件的制作过程中我走了好多的弯路,主要是在系统还没有设计很有把握就开始动手制作了。
后来发现与设计的要求还有偏差,反复的改过了几次,浪费了大量的时间和体力。
感受到设计人员要有耐心,要认真的从要求开始研究。
软件的编写过程中费了很大的力气,因为软件的编写要求很高,要很细心,一不小心就会调用错误,很深刻的体会到作为软件编程人员是绝不能粗心大意的。
一个程序的完成的速度和质量高低与细心与否有着很大联系。
编程时,我充分使用了结构化的思想。
这样因为语句较少,程序调试比较方便,功能模块可以逐一的调试,充分体现了结构化编程的优势。
当每个模块都完成时,将其功能加到一起就完成了整体的设计。
参考文献:
[1[谭浩强.C语言程序设计[M].北京:
清华大学出版社,2000
[2[靳达.求是科技.单片机应用系统开发实例导航[M].:
人民邮电出版社,2006
[3[刘守义.单片机应用技术[M].:
西安电子科技大学出版社,2001
[4[林志琦.基于PROTEUS的单片机可视化软硬件仿真[M].北京:
北京航空航天大学出版社,2006
[5[胡汉才.单片机原理及接口技术.清华大学出版社,1996
[6[徐江海.单片机实用教程[M].北京:
机械工业出版社,2007
[7]张磊.C语言程序设计[M].北京:
高等教育出版社,2005
附录:
1电路图
2实物图(正反面)
实物图(正面)
实物图(反面)
3源程序
/*
接盘按键说明:
--------------------------------------------------
|1|2|3|+|
-------------
|4|5|6|-|
|7|8|9|*|
|C|0|=|/|
--------------------------------------------------*/
//操作简介
//按第一个数,再按'
+-*/'
再按'
='
显示出结果,然后按C清屏
//加最大9999+9999=19998
//减最大9999-0=9999
//乘最大9999*9999=99980001
//除1/9=0.1111保留小数点后4位
#include<
reg51.h>
#defineuintunsignedint
#defineucharunsignedchar
//--------LCD1602-------------------
//P00-07====D0-7
sbitrs=P2^7;
//指令or数据
sbitwela=P2^6;
//读or写
sbitlcden=P2^5;
//使能信号
//--------KEY-----------------------
//P1口
ucharcodetable[]="
"
;
longintdata_a,data_b;
//第一个数和第二个数
longintdata_c;
//计算结果
uchardispaly[10];
//显示缓冲
//************************************************************************/
//描述:
延时tus函数
voidLCD_Delay_us(unsignedintt)
{
while(t--);
//t=0,退出
}
延时tms函数
voidLCD_Delay_ms(unsignedintt)
unsignedinti,j;
for(i=0;
i<
t;
i++)//执行t次循环
for(j=0;
j<
113;
j++)//执行113次循环
;
1602液晶写指令
voidwrite_com(ucharcom)//1602液晶写指令
rs=0;
//写指令
lcden=0;
//使能1602
P0=com;
//写入指令com
LCD_Delay_ms
(1);
//延时1ms
lcden=1;
//使能1602
LCD_Delay_ms
(2);
//延时2ms
1602液晶写数据
voidwrite_date(uchardate)//1602液晶写数据
rs=1;
//写数据
P0=date;
//写入数据date
//延时2ms
指定x,y写入字符函数
voidW_lcd(unsignedcharx,unsignedchary,unsignedcharData)
{
if(y==0){write_com(0x80+x);
}//第一行
else{write_com(0xc0+x);
}//第二行
write_date(Data);
//写入数据
}
//指定x,y写入字符串函数
voidLCD_Write_String(unsignedcharx,unsignedchary,unsignedchar*s)
}//第一行
else{write_com(0xC0+x);
}//第二行
while(*s)//
{write_date(*s);
s++;
}//写入数据
初始化液晶,及画面初始化
voidinit_lcd(void)//初始化液晶,及画面初始化
wela=0;
//写液晶
write_com(0x38);
//8位总线,双行显示,5X7的点阵字符
LCD_Delay_us(100);
//延时100us
write_com(0x0c);
//开显示,无光标,光标不闪烁
write_com(0x06);
//光标右移动
write_com(0x01);
//清屏
write_com(0x80);
//DDRAM地址归0
反转法键盘扫描
shortkeycheckdown()/*反转法键盘扫描*/
shorttemp1,temp2,temp,a=0xff;
P1=0xf0;
/*输入行值(或列值)*/
LCD_Delay_ms(20);
/*延时*/
temp1=P1;
/*读列值(或行值)*/
P1=0xff;
P1=0x0f;
/*输入列值(或行值)*/
/*延时*/
temp2=P1;
/*读行值(或列值)*/
temp=(temp1&
0xf0)|(temp2&
0xf);
/*将两次读入数据组合*/
switch(temp)/*通过读入数据组合判断按键位置*/
{
case0x77:
a=0x0d;
break;
//按键/
case0x7b:
a=0x0e;
break;
//按键=
case0x7d:
a=0;
//按键0
case0x7e:
a=0x0f;
//按键CE
case0xb7:
a=0x0c;
//按键*
case0xbb:
a=0x9;
//按键9
case0xbd:
a=0x8;
//按键8
case0xbe:
a=0x7;
//按键7
case0xd7:
a=0x0b;
//按键-
case0xdb:
a=0x6;
//按键6
case0xdd:
a=0x5;
//按键5
case0xde:
a=0x4;
//按键4
case0xe7:
a=0x0a;
//按键+
case0xeb:
a=3;
//按键3
case0xed:
a=2;
//按键2
case0xee:
a=1;
//按键1
default:
a=0xff;
returna;
/*返回按键值*/
voiddisplay_a()//显示数据a
dispaly[3]=data_a%10000/1000;
//千
dispaly[2]=data_a%1000/100;
//百
dispaly[1]=data_a%100/10;
//十
dispaly[0]=data_a%10;
//个
write_com(0x80+0);
//显示数据a
if(data_a>
999){write_date('
0'
+dispaly[3]);
}//显示千位
99){write_date('
+dispaly[2]);
}//显示百位
9){write_date('
+dispaly[1]);
}//显示十位
write_date('
+dispaly[0]);
//显示个位
voiddisplay_b()//显示数据b
write_com(0x80+7);
//第一行
dispaly[3]=data_b%10000/1000;
dispaly[2]=data_b%1000/100;
dispaly[1]=data_b%100/10;
dispaly[0]=data_b%10;
if(data_b>
}//显示千位
99){write_date('
}//显示百位
9){write_date('
}//显示十位
write_date('
//计算结果
voiddisplay_c(x)
if(data_c<
100000000&
&
data_c>
-1)//溢出时显示错误
dispaly[8]=data_c%1000000000/100000000;
//万万
dispaly[7]=data_c%100000000/10000000;
//千万
dispaly[6]=data_c%10000000/1000000;
//百万
dispaly[5]=data_c%1000000/100000;
//十万
dispaly[4]=data_c%100000/10000;
//万
dispaly[3]=data_c%10000/1000;
//千
dispaly[2]=data_c%1000/100;
//百
dispaly[1]=data_c%100/10;
//十
dispaly[0]=data_c%10;
//个
write_com(0x80+6+0x40);
if(x==4)
{
if(data_c>
99999999){write_date('
+dispaly[8]);
}//显示万万
9999999){write_date('
+dispaly[7]);
}//千万
999999){write_date('
+dispaly[6]);
}//百万
99999){write_date('
+dispaly[5]);
}//十万
write_date('
+dispaly[4]);
//万
.'
);
}
else{
9999){write_date('
}//万
999){write_date('
}//千
99){write_date('
}//百
9){write_date('
}//十