单片机设计报告Word格式.docx

上传人:b****5 文档编号:21143193 上传时间:2023-01-27 格式:DOCX 页数:19 大小:271.42KB
下载 相关 举报
单片机设计报告Word格式.docx_第1页
第1页 / 共19页
单片机设计报告Word格式.docx_第2页
第2页 / 共19页
单片机设计报告Word格式.docx_第3页
第3页 / 共19页
单片机设计报告Word格式.docx_第4页
第4页 / 共19页
单片机设计报告Word格式.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

单片机设计报告Word格式.docx

《单片机设计报告Word格式.docx》由会员分享,可在线阅读,更多相关《单片机设计报告Word格式.docx(19页珍藏版)》请在冰豆网上搜索。

单片机设计报告Word格式.docx

三、硬件系统设计

3.1、STC89C52单片机最小系统

单片机最小系统就是支持主芯片正常工作的最小电路部分,包括主控芯片、复位电路和晶振电路。

主控芯片选取STC89C52RC芯片,因其具有良好的性能及稳定性,价格便宜应用方便。

晶振选取12MHz,晶振旁电容选取30pF。

采用按键复位电路,电阻分别选取100Ω和1K,电容选取22μF。

以下为单片机最小系统硬件电路图。

3.2、键盘接口电路

计算器所需按键有:

数字键:

’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’,’0’

功能键:

’+’,’-‘,’*’,’/’,’=’,’.(小数点)’

共计16个按键,采用4*4矩阵键盘,键盘的行和列之间都有公共端相连,四行和四列的8个公共端分别接P1.0~P1.7。

矩阵键盘扫描方式如下:

先对P1口写入0xf0,把低四位全部赋0,高四位全部赋1,然后检测P1口的高四位,如果高四位不是全部为1,则表示有键按下,再逐列扫描,判断是哪个键按下。

这样扫描P1口就可以完成对矩阵键盘的扫描,通过对16个按键进行编码,从而得到键盘的的各个按键的键值。

在本设计中,最重要的是要把键值转换为数值来进行计算

以下为键盘接口电路的硬件电路图

3.3、液晶显示电路

在本设计中,我们采用1602液晶作为显示模块,1602可以显示2行16个字符,有8位数据总线D0-D7,和RS、R/W、EN三个控制端口,工作电压为5V,并且带有字符对比度调节和背光。

1602外观如下图所示

1602引脚说明

编号

符号

引脚说明

1

VSS

电源地

9

D2

双向数据口

2

VDD

电源正极

10

D3

3

VL

对比度调节

11

D4

4

RS

数据/命令选择

12

D5

5

R/W

读/写选择

13

D6

6

E

模块使能端

14

D7

7

D0

15

BLK

背光源地

8

D1

16

BLA

背光源正极

VDD:

电源正极,4.5-5.5V,通常使用5V电压;

VL:

LCD对比度调节端,电压调节范围为0-5V。

接正电源时对比度最弱,接地电源时对比度最高,但对比度过高时会产生“鬼影”,因此通常使用一个1K的电位器来调整对比度,或者直接串接一个电阻到地,在本设计中,我们采用1k的电位器来调节对比度。

RS:

MCU写入数据或者指令选择端。

MCU要写入指令时,使RS为低电平;

MCU要写入数据时,使RS为高电平;

R/W:

读写控制端。

R/W为高电平时,读取数据;

R/W为低电平时,写入数据;

E:

LCD模块使能信号控制端。

写数据时,需要下降沿触发模块。

D0-D7:

8位数据总线,三态双向。

如果MCU的I/O口资源紧张的话,该模块也可以只使用4位数据线D4-D7接口传送数据。

本充电器就是采用4位数据传送方式;

BLA:

LED背光正极。

需要背光时,BLA串接一个限流电阻接VDD,BLK接地,实测该模块的背光电流为50mA左右;

BLK:

LED背光地端。

1602操作时序

(1)读操作时序

(2)写操作时序

(3)基本操作时序

本设计中,1602液晶电路部分如下:

3.4、整机电路如下页图:

四、系统程序设计部分

4.1、系统程序设计思想

在本设计中,程序设计是关键。

设计关键问题有如下几个:

1、实现按键扫描,和键值转换

2、把键值转换成数值进行计算

3、每按下一个键,液晶上便显示一个键值

4、把结果显示在液晶上

4.1.1按键扫描部分

在该部分中,我是用如下按键扫描方式的:

因为按键接口在P1口,因此,在初始状态下,我将P1口赋值为0xf0,即把高四位赋1,低四位赋0;

然后在检测高四位,如果高四位不是全1,则说明有键按下,此时在将低四位逐次赋0,然后检测高四位,判断是哪个按键按下。

流程图如下:

4.1.2键值转换成数值

因为在液晶中显示的字符,因此就有了把字符,或者说是字符串转换成数值的问题。

在本设计中,我是先将按键所送来的字符存放在一个数组里面,然后在把字符转换成数字。

因为计算器中是两个数字在进行计算,因此在这个数组里面是存放的是两个数字,还有运算符。

在区分的时候,我是以运算符为标志来区分两个数的,同时将两个数中的各个位上的数合成成一个浮点数来进行计算。

程序如下:

for(i=0;

i<

keycount-2;

i++)//将字符型数变为整型数,并存放于数组中

{if((keytemp[i]!

='

+'

)&

&

(keytemp[i]!

-'

*'

/'

))

{if(flag2==0)flag1=1;

}//初始时,flag2=0,未遇到‘+’时,则执行这句,遇到‘+’后,falg2=1,则不执行这句,保证‘+’后面的数存放到num2cal数组里面

else

{flag2=1;

flag1=0;

}

if(flag1==1)

{switch(keytemp[i])//转换第一个数,并存放到num1cal数组中

{case'

0'

:

num1cal[num1count]=0;

break;

case'

1'

num1cal[num1count]=1;

2'

num1cal[num1count]=2;

3'

num1cal[num1count]=3;

4'

num1cal[num1count]=4;

5'

num1cal[num1count]=5;

6'

num1cal[num1count]=6;

7'

num1cal[num1count]=7;

8'

num1cal[num1count]=8;

9'

num1cal[num1count]=9;

.'

num1cal[num1count]='

;

default:

}

num1count++;

//计算第一个数的位数,包含小数点

}

elseif(flag2==1)

{next=i+1;

//转换第二个数,并存放到num2cal数组中

switch(keytemp[next])

num2cal[num2count]=0;

num2cal[num2count]=1;

num2cal[num2count]=2;

num2cal[num2count]=3;

num2cal[num2count]=4;

num2cal[num2count]=5;

num2cal[num2count]=6;

num2cal[num2count]=7;

num2cal[num2count]=8;

num2cal[num2count]=9;

num2cal[num2count]='

num2count++;

//计算第二个数的位数,包含小数点

if(i==keycount-2)

{flag1=0;

flag2=0;

}

4.1.3键值显示部分

此部分需要用到1602液晶的驱动,同时要将每次按得的键值送给1602显示。

在此部分中,我是用一个死循环来构成的。

在死循环中,每按下一个键,就把键值送个液晶,当安按下的键值为‘=’时,表示数据输入结束,跳出死循环,进入键值转换和数字计算部分。

do{if(scan()==1)//扫描按键,并存入键值,显示键值

{keytemp[keycount]=keyvalue();

while(scan()==1);

writedata(keytemp[keycount]&

0x7f);

keycount++;

}

}while(keytemp[keycount-1]!

);

4.1.4结果显示部分

因为结束我是用浮点数的形式存放的,因此就必须在液晶上把浮点数显示出来。

在此,我调用了sprintf函数,将浮点数转换成字符串的形式,因为液晶上面显示的是字符串,因此也是有这个必要的。

那么问题就编程在液晶上面显示字符串的问题了。

考虑到字符串是以‘/0’结束的,因此可以用一个循环来显示字符串,当遇到’/0’后,循环结束。

字符串函数显示如下:

voidwritestring(uchar*str)//显示字符串函数

{while(*str!

\0'

{writedata(*str);

str++;

结果显示函数如下:

voiddisplayrlt(floataa)//显示结果数

{ucharab[10];

sprintf(ab,"

%3.7f"

aa);

write(0xc4);

writestring(ab);

4.1.5整机程序如下:

/**************************************************************************************************************************

writebyAron2011/12/1918:

06

calculatorprogramdisplaybyLCD

**************************************************************************************************************************/

#include"

reg51.h"

#include"

stdio.h"

#defineucharunsignedcharidata

#defineuintunsignedint

ucharword[]={"

error!

"

};

//显示出错

ucharbootinit1[]={"

dianzi093"

//开机界面1

ucharbootinit2[]={"

calculator"

//开机界面2

ucharpflag=0;

sbitRs=P3^0;

sbitRw=P3^1;

sbitEn=P3^2;

sbitbz=P3^3;

/********portdefinition

Rs=P3^0;

Rw=P3^1;

En=P3^2;

keypad:

P1;

/********************1602液晶函数***********************************/

voiddelay(ucharii)

{uintx,y;

for(x=0;

x<

ii;

x++)

for(y=0;

y<

500;

y++);

voidfbusy()//检查忙函数

{Rs=0;

Rw=1;

En=1;

En=0;

while(P2&

0x80){En=0;

En=1;

delay(5);

voidwrite(ucharj)//写命令函数

{fbusy();

Rs=0;

Rw=0;

P2=j;

voidwritedata(ucharj)//写数据函数

{fbusy();

Rs=1;

P2=j;

{

while(*str!

voidinit_lcd(void)//初始化函数

{write(0x01);

write(0x38);

write(0x0c);

write(0x06);

/********************************键盘函数*************************/

unsignedcharscan(void)//扫描函数

{unsignedchari;

P1=0xf0;

i=P1&

0xf0;

if(i!

=0xf0)

return1;

else

return0;

unsignedcharkeyvalue(void)//键值判断函数

{unsignedcharkeyv,temp;

uchari,j,k,flag=0;

ucharm,n;

if(scan()==1)

{for(i=0;

4;

i++)

{m=(0x01<

<

i);

P1=~m;

for(j=0;

j<

j++)

{k=P1|0x0f;

n=(0x10<

j);

if(k==(~n))

{keyv=j*4+i;

flag=1;

break;

if(n==0x80)n=0x10;

if(m==0x08)m=0x01;

if(flag==1)

break;

switch(keyv)

{case0:

{temp='

case1:

case2:

case3:

case4:

case5:

case6:

case7:

case8:

case9:

case10:

{temp='

case11:

case12:

case13:

case14:

case15:

default:

returntemp;

/***************************计算函数**********************/

floatbtnum(uchar*arr,ucharnum)//通过存放的数组来算的所输入的浮点数

{inti,k,m;

intintcnt=0;

intintnum=0;

floatdecnum=0,numa=0,num1=0,num2=0;

for(i=0;

num;

i++)//计数整数的个数

{if((arr[i]=='

))break;

elseintcnt++;

for(k=0;

k<

intcnt;

k++)//计算整数

{intnum*=10;

intnum+=arr[k];

for(m=0;

m<

num-intcnt-1;

m++)//计算小数

decnum=(arr[num-1-m]+decnum)/10;

numa=decnum+intnum;

//计算所输入的数

returnnuma;

floatcalculater(void)//计算函数

{ucharkeycount=0;

//按键次数计数

ucharnum1count=0,num2count=0;

//两次输入数的位数(包含小数点)

uchari,next,flag1=0,flag2=0;

ucharkeytemp[15];

ucharnum1cal[8];

//存放第一次输入的数

ucharnum2cal[8];

//存放第二次输入的数

floatnum1=0,num2=0,numrlt=0;

//第一次,第二次及计算后的数

do{if(scan()==1)//扫描按键,并存入键值,显示键值

i++)//将字符型数变为整型数,并存放于数组中

{if((keytemp[i]!

}//初始时,flag2=0,未遇到‘+’时,则执行这句,遇到‘+’后,falg2=1,则不执行这句,保证‘+’后面的数存放到num2cal数组里面

{switch(keytemp[i])//转换第一个数,并存放到num1cal数组中

//计算第一个数的位数,包含小数点

//转换第二个数,并存放到num2cal数组中

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

当前位置:首页 > 总结汇报 > 学习总结

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

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