c51的简易计算器单片机课程设计.docx

上传人:b****6 文档编号:4717870 上传时间:2022-12-07 格式:DOCX 页数:19 大小:608.11KB
下载 相关 举报
c51的简易计算器单片机课程设计.docx_第1页
第1页 / 共19页
c51的简易计算器单片机课程设计.docx_第2页
第2页 / 共19页
c51的简易计算器单片机课程设计.docx_第3页
第3页 / 共19页
c51的简易计算器单片机课程设计.docx_第4页
第4页 / 共19页
c51的简易计算器单片机课程设计.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

c51的简易计算器单片机课程设计.docx

《c51的简易计算器单片机课程设计.docx》由会员分享,可在线阅读,更多相关《c51的简易计算器单片机课程设计.docx(19页珍藏版)》请在冰豆网上搜索。

c51的简易计算器单片机课程设计.docx

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);

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1