单片机设计报告Word格式.docx
- 文档编号:21143193
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:19
- 大小:271.42KB
单片机设计报告Word格式.docx
《单片机设计报告Word格式.docx》由会员分享,可在线阅读,更多相关《单片机设计报告Word格式.docx(19页珍藏版)》请在冰豆网上搜索。
三、硬件系统设计
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数组中
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 设计 报告