c51的简易计算器单片机课程设计.docx
- 文档编号:8133503
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:19
- 大小:608.12KB
c51的简易计算器单片机课程设计.docx
《c51的简易计算器单片机课程设计.docx》由会员分享,可在线阅读,更多相关《c51的简易计算器单片机课程设计.docx(19页珍藏版)》请在冰豆网上搜索。
c51的简易计算器单片机课程设计
单片机课程设计
题目名称基于51单片机的简易计算器
学生学院____信息工程学院_______
专业班级信息工程(应用电子方向)12
(2)班
姓名______虞君权__________
学号3*********
指导教师______李优新___
2015年1月15
一、课程设计的内容
本次课程设计的内容从下面两个方面任选一个:
一是在学院的单片机实验平台上进行,开发一个基于单片机与PWM技术的灯光调节系统,主要开发内容为按键定义、输入与防抖动技术、PWM调节技术以及显示技术等程序设计。
二是利用51系列单片机及必要的外围芯片、输入输出等接口电路设计开发一个简易的单片机系统,在此基础上,自行设计一个单片机应用程序来实现一些实用的功能。
通过这些内容的设计、开发、安装、调试等一系列工作,熟练掌握单片机系统的开发流程与工作机理,加深对所学课程知识的理解与把握,为将来相关的研究开发工作打下坚实的基础。
二、设计内容
本次实验的任务就是要以51系列单片机为核心实现一个简易计算器计算器,它的结构非常简单,外部主要由4*4矩阵键盘和一个液晶显示屏构成,内部由一块AT89C51单片机构成,通过软件编程可实现简单加减乘除。
三、方案论证
经分析,计算器电路包括三个部分:
显示电路、4*4键扫描电路、单片机微控制电路。
具体如下:
1)LCD显示电路
LCD1602作为一个成熟的产品,使用简单,模式固定,便于移植到各种类型的程序,但是初学者往往要注意结合LCD本身的时序图来完善初始化程序。
又以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,故采用LCD.
2)4*4键盘扫描电路(中断式,扫描式,反转式)
用户设计行列键盘接口,一般常采用3种方法读取键值。
一种是中断式,外两种是扫描法和反转法。
中断式:
在键盘按下时产生一个外部中断通知CPU,并由中断处理程序通过不同的地
址读取数据线上的状态,判断哪个案件被按下。
本实验采用中断式实现用户键盘接口。
扫描法:
对键盘上的某一行送低电平,其他行为高电平,然后读取列值。
若列值中有一
位是低,则表明该行与低电平对应列的键被按下;否则,扫描下一行。
反转法:
先将所有行扫描线输出低电平,读列值。
若列值有一位是低,则表明有键按下,
读列值;然后所有列扫描线输出低电平,再读行值。
根据读到的值组合就可以查表1得到的
键码。
这个就仁者见仁智者见智了,不过如果熟悉了扫描式,建议果断升级自己的硬件(很简单加个74LS08与门),故采用节省CPU的中断式扫描电路。
⒊)单片机微控制电路
微控制电路就是以AT89C51为核心的控制核心,主要注意晶振电路的接法和复位电路的接法。
四、硬件电路的设计
2.1硬件设计电路框图
2.2硬件设计电路的元件清单
器件名称
数量
AT89C51
1
按键
17
10K电阻
9
电容22uF
1
LCD1602
1
晶振12MHz
1
电容30pF
2
5K电位器
1
2.3硬件设计电路图
将4*4的键盘直接接在P2口上,用P0口作为LCD的显示输出,P3.2口的INT0作为外部中断位。
五、软件设计程序及描述
本程序组成可分为3个模块:
矩阵键盘模块,LCD显示模块,和运算模块
六、硬软件的调试及方法
我个人遇到的主要问题出现在LCD1602上,要不是我自己买了块新的LCD恐怕我的结论,就只能在软件仿真实现了。
硬件上:
在不加芯片调试时,LCD1602只显示一排全黑,一般说明该元件是好的。
(但也不一定,我那时就一直认为我的元件没坏);给15,16管脚分别接上+5v和0v,测试背光是否完好;给VEE接上电位器,检查对比度是否可调;
七、实验结果与性能达标
我的计算器能准确进行包括整数及小数的加减乘除四则运算。
八、实验改进与心得体会
这个实验给我的感觉,硬件和软件上都不是很难。
在将烧写进单片机芯片之前,进行过仿真,所以方便很多,觉得proteus软件在逻辑电路仿真中非常有用,特别是进行单片机的仿真。
我在这次实验上,又加深了对单片机的认识和理解,感觉收获的更多。
下面是源代码:
#include
#include
#include
#include
#include
sbitRS=P1^2;
sbitRW=P1^1;
sbitE=P1^0;//定义lcd端口,RS:
数据、命令选择端,RW:
读、写选择端
sbitH1=P2^4;
sbitH2=P2^5;
sbitH3=P2^6;
sbitH4=P2^7;
charinput,flag,f,i;//定义每次的输入input,和对输入的分类标志flag
charbuf[16]="",num1[10]="",num2[10]="",result[16]="",sign;
floattemp;
voiddelay(unsignedcharx)//延时函数
{
unsignedchary;
for(;x>0;x--)
for(y=0;y<=110;y++)
;
}
voiddelay_4nop()//延时函数
{
_nop_();
_nop_();
_nop_();
_nop_();
}
voidkeyscan()//矩阵键盘扫描函数
{
P2=0XF7;
if(H1==0)
{
delay(10);
if(H1==0)
{
input='0';//扫描按键0,下面同理
flag=1;
}
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';
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='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)
{
input='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)
;
}
}
bitlcd_bz()//测试lcd是否忙碌,result=1表示忙,=0表示不忙
{
bitBF;
RS=0;
RW=1;
E=1;
delay_4nop();
BF=(bit)(P0&0x80);
E=0;
returnBF;
}
voidlcd_wcmd(unsignedcharcmd)//对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;
}
voidlcd_wdat(unsignedchardat)//对lcd写数据
{
while(lcd_bz());//当LCD不忙碌时才写入指令
RS=1;
RW=0;
E=0;
delay_4nop();
P0=dat;
delay_4nop();
E=1;
delay_4nop();
E=0;
}
voidlcd_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);
}
voidlcd_display(chara[])//lcd显示输入输出结果的函数
{
unsignedcharj;
delay_4nop();
lcd_wcmd(0x00+0x80);//设置显示的位置
j=0;
while(a[j]!
='\0')
{
delay_4nop();
lcd_wdat(a[j]);//显示的内容
j++;
}
delay_4nop();
}
voidnull(char*a)//清空一个字符数组的函数
{
unsignedcharj=0;
while(*(a+j)!
='\0')
{
*(a+j)='\0';
j++;
}
}
voidcopy(char*a,char*b)//将指针b所指字符串复制到指针a所指字符串
{
unsignedcharj=0;
while(*(b+j)!
='\0')
{
*(a+j)=*(b+j);
j++;
}
}
voidsimplify_result(char*a)//去除结果的尾数中多余的零和小数点的函数
{
unsignedcharj=15;
while(((*(a+j)=='\0')||(*(a+j)=='0')||(*(a+j)=='.'))&&(j>0))
{
if(*(a+j)=='0')
*(a+j)='\0';
elseif(*(a+j)=='.')
{
*(a+j)='\0';
break;
}
j--;
}
}
temp_to_buf()//将运算结果temp转移到buf()显示出来,并准备好下一次运算的函数
{
unsignedcharj;
sprintf(result,"%.5f",temp);
null(buf);
sign='\0';
simplify_result(result);
copy(buf,result);
j=0;
while(buf[j]!
='\0')
j++;
i=j;
null(result);
null(num1);
null(num2);
temp=0;
lcd_wcmd(0x01);
return(result,buf,num1,num2,temp,i);
}
voidequal_deal()//等号的运算处理
{
unsignedcharj;
for(j=f+1;buf[j]!
='\0';j++)//将符号之后的数装进字符串num2[]
num2[j-f-1]=buf[j];
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'/':
temp=strtod(num1,NULL)/strtod(num2,NULL);
break;
case'\0':
temp=strtod(buf,NULL);
default:
break;
}
temp_to_buf();
}
voidmain()
{
unsignedcharj;
lcd_init();//初始化LCD
delay(10);
while
(1)
{
flag=0;
keyscan();
if(flag==1)//当输入为数字时,将其装进buf[]
{
buf[i]=input;
i++;
}
if(flag==2)//当输入为+-*/符号时的处理
{
if(sign!
='\0')//若之前有输入过符号,先对前面的式子进行处理
equal_deal();
sign=input;
buf[i]=input;
f=i;
for(j=0;j num1[j]=buf[j]; i++; } if(flag==3) { switch(input) { case'=': //输入为=号时的处理 equal_deal(); break; default: break; } } delay (1); simplify_result(result);//去除运算结果中多余的0和小数点 lcd_display(buf);//将输入或运算结果显示出来 delay(10); } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- c51 简易 计算器 单片机 课程设计