C51单片机课设报告进制转换Word格式文档下载.docx
《C51单片机课设报告进制转换Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《C51单片机课设报告进制转换Word格式文档下载.docx(21页珍藏版)》请在冰豆网上搜索。
![C51单片机课设报告进制转换Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2022-11/30/2ea9c973-8248-43a5-ac7c-defaaf102b61/2ea9c973-8248-43a5-ac7c-defaaf102b611.gif)
1602LCD是指显示的
内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
液晶显示屏际实际选用的是QC1602ATprotues模拟电路图中的LM016功能基本相同。
3)按键输入模块:
按键输入模块由1块4*4矩阵键盘、8根数据线组成、2个独立按键。
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图1所示。
在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。
这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直
接用端口线则只能多出一键(9键)。
由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则
作为输入。
这样,当按键没有按下时,所有的输入端都是高电平,代表无键按下。
行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。
实际电路中使用的是集成的1块4*4矩阵键盘,跟protues模拟电路图中的
16个独立按键相比体积更小,实现的功能相同。
4)全局设计:
通过STC89C52的P3.0-P3.7口读入4*4矩阵键盘的按键输入数据,STC89C52的P0.0-P0.7先接入8位1k欧姆排阻作上拉电阻,再接入1602液晶屏幕的数据口D01-D07,输出数据到1602液晶屏幕,液晶屏幕显示读到的数据。
P2.1-P2.3口分别接入1602的RSRWE控制读写。
P2.4-P2.5口分别接入1独立按键最为“确定”键和“清零”键。
STC89C52的RST接VCCt源,即上点就复位。
XTAL1,XTAL2接12MHz无源晶振。
4、软件设计(包括流程图及程序)
1)程序流程图:
2)程序代码:
#include<
reg52.h>
//
intrins.h>
sbitRS=
:
P2A1;
定义端口
sbitRW:
=卩2八2;
sbitEN=
卩2八3;
sbitQL=
P2A4;
//外接清零端口
sbitQD=
=P2A5;
//外接确定端口
sbitwela=P2A7;
//
锁存器控制端定义
unsignedintqlbz=O;
unsignedintqdbz=O;
#defineRS_CLRRS=O
#defineRS_SETRS=1
#defineRW_CLRRW=0
#defineRW_SETRW=1
#defineEN_CLREN=0
#defineEN_SETEN=1
#defineDataPortP0
#defineKeyPortP3
unsignedcharcode
asc_code[]={'
0'
'
1'
2,3,'
4'
5'
6'
7'
8,'
9'
A'
B'
C,'
D'
E'
F'
};
〃
转换成液晶显示的字符
/*
uS延时函数
*/
voidDelayUs2x(unsignedchart)
{while(--t);
}
mS延时函数
*/
voidDelayMs(unsignedchart)
{
while(t--)
//大致延时1mS
DelayUs2x(245);
判忙函数
bitLCD_Check_Busy(void)
DataPort=OxFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return(bit)(DataPort&
0x80);
写入命令函数
voidLCD_Write_Com(unsignedcharcom){
while(LCD_Check_Busy());
//忙则等待
RW_CLR;
DataPort=com;
写入数据函数
----*/
voidLCD_Write_Data(unsignedcharData)
忙则等待
RS_SET;
DataPort=Data;
清屏函数
voidLCD_Clear(void)
LCD_Write_Com(0x01);
DelayMs(5);
写入字符串函数
voidLCD_Write_String(unsignedcharx,unsignedchary,unsignedchar*s)
if(y==0)
LCD_Write_Com(0x80+x);
else
LCD_Write_Com(0xC0+x);
while(*s)
LCD_Write_Data(*s);
s++;
写入字符函数
voidLCD_Write_Char(unsignedcharx,unsignedchary,unsignedcharData){
LCD_Write_Data(Data);
初始化函数
voidLCD」nit(void)
LCD_Write_Com(0x38);
/*显示模式设置*/
LCD_Write_Com(0x08);
/*
显示关闭*/
显示清屏*/
LCD_Write_Com(0x06);
显示光标移动设置*/
LCD_Write_Com(0x0C);
显示开及光标设置*/
按键扫描函数0,返回小键盘扫描键值
unsignedcharKeyScan(void)//
键盘扫描函数,使用行列反转扫描法
行列值中间变量行线输出全为0读入列线值
unsignedcharcord_h,cord_l;
KeyPort=0x0f;
cord_h=KeyPort&
0x0f;
if(cord_h!
=0x0f)//
先检测有无按键按下
去抖
读入列线值
输出当前列线值
读入行线值
DelayMs(100);
//if((KeyPort&
0x0f)!
=0x0f)
//KeyPort=cord_h|0xf0;
//cord」=KeyPort&
0xf0;
while((KeyPort&
0xf0)!
=0xf0);
〃等待松开并输出
return(cord_h+cord_l);
〃键盘最后组合码值
}return(0xff);
//返回该值
按键扫描函数1,返回确定键扫描键值
unsignedcharKeyScanQD(void)//键盘扫描函数
if(QD!
=1)//
//去抖
=1)
while(QD==0);
等待松开并输出
qdbz=1;
}return(0);
返回该值
按键扫描函数2,返回清零键扫描键值
unsignedcharKeyScanQL(void)//键盘扫描函数
if(QL!
while(QL==0);
qlbz=1;
按键值处理函数,返回扫键值
unsignedcharKeyPro(void)
switch(KeyScan())
case0x7e:
return1;
break;
//0按下相应的键显示相对应的码值
case0x7d:
return2;
//1
case0x7b:
return3;
//2
case0x77:
return4;
//3
case0xbe:
return5;
//4
case0xbd:
return6;
//5
case0xbb:
return7;
//6
case0xb7:
return8;
//7
case0xde:
return9;
//8
case0xdd:
return0;
//9
case0xdb:
return10;
//a
case0xd7:
return11;
//b
case0xee:
return12;
//c
case0xed:
return13;
//d
case0xeb:
return14;
//e
case0xe7:
return15;
//f
default:
return0xff;
主函数
voidmain(void)
unsignedinti,j,k,kk,Jz,num,n,t1,t2,a,b,x,y;
unsignedcharjinzhishu1[2],jinzhishu2[2];
unsignedchardushu[16];
unsignedchardushu2[16];
LCD」nit();
wela=1;
P0=0Xff;
wela=0;
〃关闭数码管
LCD_Write_Com(0x0F);
〃光标开,光标闪烁开
while⑴
LCD_Clear();
/*下为输入部分
A1:
jinzhishu1[1]='
'
;
jinzhishu1[2]='
LCD_Write_String(O,O,"
EnterINsystem"
);
i=0;
while(qdbz==O)
Jz=KeyPro();
if(Jz!
=Oxff)
LCD_Write_Char(i,1,asc_code[Jz]);
jinzhishu1[i]=asc_code[Jz];
i++;
KeyScanQD();
KeyScanQL();
if(qlbz==1)
qlbz=0;
LCD_Clear();
i=0;
j=0;
gotoA1;
if(i==2)qdbz=1;
qdbz=0;
LCD_Write_String(0,1,"
"
依次显示输入字符
a=10;
if(jinzhishu1[0]=='
&
jinzhishu1[1]=='
)
elseif(jinzhishu1[0]==2&
elseif(jinzhishu1[0]==8&
elseif(jinzhishu1[0]=='
LCD_Write_String(0,0,"
WrongINsystem"
while(qdbz==0)
A2:
for(i=0;
i<
16;
i++)
dushu2[i]='
dushu[i]='
EnterINnumber"
num=KeyPro();
if(num!
=0xff)
LCD_Write_Char(i,1,asc_code[num]);
dushu2[i]=num;
a=2;
a=8;
a=16;
gotoA2;
if(i==15)qdbz=1;
n=i;
A3:
jinzhishu2[1]='
jinzhishu2[2]='
EnterOUTsystem"
〃jinzhishu2[i]=asc_code[Jz];
gotoA3;
qdbz=O;
if(jinzhishu2[0]=='
jinzhishu2[1]=='
O'
)b=10;
elseif(jinzhishu2[0]=='
2'
'
)b=2;
elseif(jinzhishu2[0]==8&
)b=8;
)b=16;
else
WrongOUTsystem"
while(qdbz==0)
/*下为运算部分
n=n-1;
t2=dushu2[0];
for(j=0;
j<
n;
j++)
t1=t2*a;
t2=t1+dushu2[j+1];
x=t2;
//输入的10进制数先转为10进制
x>
=b;
y=x%b;
x=x/b;
dushu[j]=asc_code[y];
y=x;
k=j;
kk=j;
=kk;
i++,k--)
dushu2[i]=dushu[k];
dushu[i]=dushu2[i];
/*下为输出部分
TheOUTnumber"
LCD_Write_String(0,1,dushu);
5、调试过程(包括出现的问题及解决的方法,以及要改进的地方,体会)
1)硬件调试:
焊接最小系统板完成之后就开始测试是否有焊接错误,首先是检验单片机的底座针脚是否联通,通过LED丁测试证明了所有的底座针脚焊接无误。
接着开始焊接排阻,电容,晶振等器件。
最后引出两个针脚插座作为VCC和GND勺插口。
接下来焊接独立按键和VCCGND莫块,完成后通过LED丁测试按键效果,证明焊接无误。
焊接工作完成后开始连线,连接控制模块和显示模块,连接控制模块和按键模块,连接各模块VCCGND口至UVCC和GND勺专用插口。
烧录入液晶显示范例程序,按键显示范例程序,测试硬件部分正常。
2)软件调试:
先编写子函数程序:
延时函数、判忙函数、写入命令函数、写入数据函数、清屏函数、写入字符函数、写入字符穿函数、LCD初始化函数、4*4矩阵按键扫描函数、确定/清零键扫描函数、矩阵按键值处理函数。
最后开始编写进制转换的主函数程序。
通过Keil编译软件编
译,用STC_ISP_v479烧录程序到单片机,利用学习开发板的集成按键、显示屏模块测试代码。
最先遇到的问题是读入按键值的问题,由于需要循环扫描的速度很快,实时监听键盘,多导致不能在同一个循环同时保持LCD的单个字符输出。
最后为了让LCD的逐一输出正常,在实时扫描的循环体内内嵌入一个判断语句,把LCD输出语句放入判断内,这样既保证了键
盘的实时监听,也保证了LCD显示屏的单个字符逐一正常输出。
接下来遇到的问题是键盘接收到的字符不能直接用于显示,由于读到的是有按键值处理函数的返回值,而显示的值却是要求ASCII型字符。
所以最后决定在开头编写转码函数表,把返回的1-16char型数字转成ASCII型的“0-9”“A-F”。
如此就使得LCD能够显示所希望得到的字符。
但再往下进行进制转换的具体实施发现,转成的ASCII码无法进行加减乘除运算,而原先的返回值是char型,也不确定是否能进行运算,同时也开始考虑int型变量是否需要使用。
最后经查阅资料发现,无论是char还是int型,都能直接被读取为机器语言进行运算,唯一区别是char型是1个字节,int型是2个字节的变量。
于是通过字符型数组储存读到的
按键返回值,并进行运算
通过之前积累的编程经验,采用的转进制方法是通过把所有进制数都转成十进制数作为中间数,然后在把中间数转为需要的进制数。
实施的初步阶段没有什么大问题,但是遇到大于255的10进制数的时候,发现运算出现了溢出,再次查阅资料发现了char型变量最多能
够表示0-255的10进制数,于是将此部分运算的中间变量设为int型,这样能够容纳的范围就变成了0-65535.
最后是输出运算的结果让LCD这其中也费了一番功夫,把底层运算的结果转成能够在LCD上显示的ASCII型又用到了转码过程。
到此软件调试基本告一段落,期间遇到的细节上的小问题数不胜数,最后在经过无数次修改程序烧录调试后得到了圆满解决。
最终软件调试成功时的烧录统计次数:
127
实验结果(将运行结果拍照)
输入2进制
输入2进制数100011110
输出8进制
输出8进制数436
最终实物连线图