单片机课程设计报告.docx
- 文档编号:4269093
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:16
- 大小:147.75KB
单片机课程设计报告.docx
《单片机课程设计报告.docx》由会员分享,可在线阅读,更多相关《单片机课程设计报告.docx(16页珍藏版)》请在冰豆网上搜索。
单片机课程设计报告
单片机原理及应用
实习报告
课程设计
学生姓名
所在专业
电气工程及其自动化专业
所在班级
任课老师
学号
成绩
评语
1、内容提要(摘要)3
2、正文3
(1)课题的意义、本人所做的工作、系统的主要功能及工作流程3
(2)硬件电路原理描述4
(3)软件设计流程及描述5
(4)系统测试7
(5)结论7
3、心得体会8
4、附录9
(1)系统总硬件电路原理图9
(2)系统源程序代码9
一、内容提要(摘要)
本次单片机课程设计我选择做一个小型简易计算器,该设计需要满足的内容是:
设计一个4×4的键盘,完成简单的四则运算,可以实现连续运算,有条件还可以考虑复杂的数序运算。
本次设计会用到proteus进行电路图的仿真,用到keil软件进行程序的编写和编译。
指导老师召开实习动员会,会议上同学们需要上交具体实现方案,验证方案的合理性。
实习环节由学生自行完成,最后统一时间验收和答辩。
二、正文
(1)课题的意义、本人所做的工作、系统的主要功能及工作流程
①课题意义:
计算器是人们生活中最常见且最简易的电子产品之一,不同的计算器有不同的动能。
一般的计算器可以实现四则运算以及其他数学运算,为了研究和了解计算器的工作原理,本次设计我选择做一个简易计算器。
在做这个设计的背景下可以将单片机的理论知识运用于实践中。
②本人所做的工作:
本人主要做了两方面的工作,一是计算器的电路图仿真搭建,二是实现计算器功能的程序编写。
电路图仿真是用proteus来完成的,在这个过程中调动了51芯片、按键、数码管来完成电路图的搭建。
实现计算器的代码是我在同学的指导下逐渐完成的,这个过程中也在网络山查找了很多资料来完善程序。
③系统的主要功能:
该简易计算机系统可以实现简单的四则运算,同时可以在不清屏的条件下继续运算。
④工作流程:
首先是分析该课题要求的功能如何实现,然后开始着手写各部分的代码。
完成了程序的编写之后进行编译和调试,程序大致没问题后生成hex文件,接着开始电路图的搭建。
电路图的搭建好后就载入hex文件试运行,运行后发现问题继续调试程序和调整电路,直到完成要求为止。
(2)硬件电路原理描述
该电路主要由AT89C51芯片、由16个按键组成的4*4键盘、数码管和外部晶振组成。
其中最主要的部分是AT89C51芯片,它起到控制和运算的作用。
外部晶振充当该系统的时钟电路,它的主要作用是向芯片提供基准频率,它就像个标尺一样,如果系统的工作频率不稳定的话会造成其他设备工作频率的不稳定。
数码管是一个显示四位的数码管,在使用之前要对它的数模进行定义。
数码管右下角的管脚控制显示的位数,当第一个管脚高电平的时候,表示可以显示4位数;当第二个管脚高电平的时候,表示可以显示3位数,以此类推,总共可以显示的范围是4位。
由16个按键组成的4*4键盘的工作原理是采用了线反转法,线反转法的具体原理是:
将行线作为输出线,列线作为输入线。
将输出线全部置0,此时列线中呈现低电平的就是按键所在的x列,如果全部不为0的话就说明没有按键按下。
然后再将列线作为输出线,行线作为输入线,置输出线全部为0,此时行线中呈现低电平的就是按键所在的y行。
由此可以确定按键的位置(x,y)。
由该仿真电路我们可以看到数码管的接通显示引脚接在芯片的P2口上,这是将P2口作为了输出口来使用,而P1口连接了矩阵键盘,作为输入口来使用。
而P3口的高四位用来控制数码管显示的位数。
(3)软件设计流程及描述
在开始编写程序之前,先将所需要的KEIL软件下载安装好,然后才开始写程序。
写程序的时候,我先确定主函数的主体内容,将要实现的功能先囊括在里面,然后在逐一在主函数之外编写子函数,在遇到不能实现的功能是请求同学的帮助或者上网查找资料。
在开始编写主程序之前,我先考虑到了键值获取的程序。
在这个系统中我运用了线反转法来获取键位,然后定义一个数组来确定键位所代表的数字或符号是什么。
简易计算机的显示是主要的问题,其次是它的计算功能。
所以在编写主函数的时候要确定运算符号是否按下了,第一位用于运算的数是否也按下了,第二位数是否按下了,等于号是否按下了,这个判断就需要通过一个获取键位的子函数来获取信息了。
因为数码管只有四位,所以还要考虑运算是否会超出显示范围,当超出了显示范围后通过程序设定屏幕显示FFFF的字样。
当第一位数、运算符号、第二位数和等于号都被按下之后,就开始调用子函数来进行运算。
在加减乘除运算中,最复杂的是除法,因为除法的结果可能是带小数位的,也可能是不带小数位的。
所以在编写这部分的主函数和子函数的时候要注意到这一点。
整数除法运算和显示我编写在一个名为dis()的子函数中,而商带有小数的除法运算和显示我编写在了一个名为div()的子函数中。
在这两个子函数中又分别讨论了商是不同位数的情况,例如在小数除法运算和显示中分别就千位带小数、百位带小数、十位带小数、个位带小数进行讨论。
(4)系统测试
经过测试,发现该简易计算机的系统可以完成简单的四则运算,由于屏幕显示无法进行连续运算,但是可以在前一次计算的结果在再进行四则运算。
当完成一次计算之后按下清除键C,会发现屏幕清屏了,但是再次运算的时候按下第一个运算的数字不显示,按下运算符号也不显示,按下第二个数显示了,最后按等于号结果是可以正确地显示出来的。
这里说明了一个问题,在做键位清零的时候还不够完善,以至于进行第二次运算的时候无法显示参与运算的数字和符号。
当第一位数超过了4位数时,屏幕会自动归0,第二位数也是这样的。
当计算结果超过了4位数时,屏幕会显示FFFF。
由于该数码管的显示,很多运算符号都不能够正常的表示出来,在这里说明一下。
当按下“+”号的时候,会显示“H”;当按下“-”号的时候,会显示“-”;当按下“*”号的时候,会显示“.”;当按下“/”号的时候,会显示“三”。
另外负数的负号也是用“.”来表示。
(5)结论
经过长时间的程序编写和电路图搭建,然后在不断地进行系统调试后,终于算是完成了一个小型简易的计算机。
该计算机虽然可以进行四则运算,但是在一些细节问题上还需改进,例如二次运算的显示问题以及如何进行连续运算的问题。
总的来说这一次课程设计是比较成功的,虽然从功能实现上还未能达到预期目标,但是它已经能实现基本功能,而且程序是自己经过各种方法敲出来的,感觉挺有成就感的。
三、心得体会
为期一周的单片机课程设计终于结束了,在一周的实习过程中心情的变化可以说像是过山车一样起伏。
这次设计我选择的课题是“小型计算器”,一开始我自己觉得这个题目是比较简单的,毕竟只需要实现四则运算就可以了。
但是在真正做起来的时候发现,其实没有那么简单。
这个设计最难的地方在于程序编写,幸好最终我还是在同学的帮助和网络的帮助下写了出来。
在开始做这个题目的时候可以说是一头雾水,硬件电路这一部分只想到了所需要的元件,没想到如何连接起来,所以就更别谈写程序这一部分了。
因为平时学的比较多的是单片机的理论知识,所以自己在实践这一方面还是比较少。
即使多难的问题也是能够解决的,于是我开始在网上查阅相关的资料,然后再问问同学,经过长时间的努力之后最终还是将电路图和程序给做出来了。
程序出来之后就是载入电路图进行运行,一开始数码管什么也没显示,同学告诉我是数码管的管脚接错了。
果然,我重新接了之后数码管就正常工作了。
然后在系统调试的过程中我发现只能够进行一次运算,无法进行连续运算。
之后有惊讶地发现可以将第一次运算的结果用于第二次运算中,这也算是连续运算吧。
然后还有一个问题至今也还没有解决,就是计算器的数值清零问题。
在完成一次计算之后按下清零键后,屏幕确实清零了,但是再进行计算却不能显示,而最后运算结果却出得来,这个问题我后面继续完善。
在完成单片机课程设计后,我发现我无论是在理论层面还是实践层面还有很多不足的地方。
通过这一次实践,我感觉自己的动手能力得到了提高,同时也巩固了单片机的理论知识。
四、附录
(1)系统总硬件电路原理图
(2)系统源程序代码
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
uchary,x,temp,fu=0;
uinta=50,flag=0,key,dyh,bru,cru,i,fuhao=0;//fuhao为数的正负符号,flag是运算符号
//bru表示b是否输入有效,cru表示c是否输入有效
longc=0,d=0,b=0;
uintcodebitT[]={0x10,0x20,0x40,0x80};//显示在第几位
uintcodeDSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x8e};//数模
voiddelay(uintx)//延时程序
{
uchart;
while(x--)
{
for(t=120;t>0;t--);
}
}
uintkeyscan()//线反转法——检测键位
{
uintcod;
P1=0xf0;//低4位为列,列为0进行扫描
y=P1;
P1=0x0f;//高4位为行,行为0进行扫描
x=P1;
temp=y|x;
while(P1!
=0x0f);
if(temp==0x77)cod=0;
if(temp==0x7e)cod=1;
if(temp==0x7d)cod=2;
if(temp==0x7b)cod=3;
if(temp==0xbe)cod=4;
if(temp==0xbd)cod=5;
if(temp==0xbb)cod=6;
if(temp==0xde)cod=7;
if(temp==0xdd)cod=8;
if(temp==0xdb)cod=9;
if(temp==0xb7)cod=10;//加
if(temp==0xd7)cod=11;//减
if(temp==0xe7)cod=12;//乘
if(temp==0xeb)cod=13;//除
if(temp==0xee)cod=14;//C
if(temp==0xed)cod=15;//=
return(cod);
}
voidcaculate(uinto)//显示运算符号
{
if(o==10)//加
{
P2=~(0x76);
P3=0x80;//数码管显示第一位
}
if(o==11)//减
{
P2=~(0x40);//低电平触发,需取反
P3=0x80;
}
if(o==12)//乘
{
P2=~(0x80);
P3=0x80;
}
if(o==13)//除
{
P2=~(0x49);
P3=0x80;
}
}
voiddis(uintn)//整数除法运算显示
{
if(n/10000)
{
for(i=0;i<4;i++)
{
if(fu==0)//正数
P2=DSY_CODE[10];
P3=bitT[3-i];
n=n/10;
delay(4);
P3=0x00;
}
}
elseif(n/1000)//商是四位数的除法运算
{
for(i=0;i<4;i++)
{
if(fu==1)//负数
P2=(DSY_CODE[n%10]&0x7f);//显示一个点
if(fu==0)//正数
P2=DSY_CODE[n%10];//输出最后一位数
P3=bitT[3-i];//显示最后一位数
n=n/10;
delay(4);
P3=0x00;
}
}
elseif(n/100)//三位数
{
for(i=0;i<3;i++)
{
if(fu==1)
P2=(DSY_CODE[n%10]&0x7f);
if(fu==0)
P2=DSY_CODE[n%10];
P3=bitT[3-i];
n=n/10;
delay(4);
P3=0x00;
}
}
elseif(n/10)//两位数
{
for(i=0;i<2;i++)
{
if(fu==1)
P2=(DSY_CODE[n%10]&0x7f);
if(fu==0)
P2=DSY_CODE[n%10];
P3=bitT[3-i];
n=n/10;
delay(4);
P3=0x00;
}
}
elseif(n%10)//个位数
{
if(fu==1)
P2=(DSY_CODE[n]&0x7f);
if(fu==0)
P2=DSY_CODE[n];
P3=0x80;//从个位开始显示
delay(4);
}
}
voiddiv(void)//小数除法运算显示
{d=b/c;
if(d/1000)//千位带小数
{
for(i=0;i<4;i++)
{
P2=DSY_CODE[10];
P3=bitT[3-i];
delay(4);
P3=0x00;
}
}
elseif(d/100)//百位带小数
{
d=10*b/c;
for(i=0;i<4;i++)
{
if(i==1)
P2=(DSY_CODE[d%10]&0x7f);//小数点亮起来
if(i!
=1)
P2=DSY_CODE[d%10];
P3=bitT[3-i];
d=d/10;
delay(4);
P3=0x00;
}
}
elseif(d/10)//十位带小数
{
d=100*b/c;
for(i=0;i<4;i++)
{
if(i==2)
P2=(DSY_CODE[d%10]&0x7f);
if(i!
=2)
P2=DSY_CODE[d%10];
P3=bitT[3-i];
d=d/10;
delay(4);
P3=0x00;
}
}
elseif(d%10)//个位带小数
{
d=1000*b/c;
for(i=0;i<4;i++)
{
if(i==3)
P2=(DSY_CODE[d%10]&0x7f);
if(i!
=3)
P2=DSY_CODE[d%10];
P3=bitT[3-i];
d=d/10;
delay(4);
P3=0x00;
}
}
else//小数位
{
d=(1000*b)/c;
for(i=0;i<4;i++)
{
if(i==3)
P2=(DSY_CODE[0]&0x7f);
if(i!
=3)
P2=DSY_CODE[d%10];
P3=bitT[3-i];
d=d/10;
delay(4);
P3=0x00;
}
}
}
voidmain()
{
flag=0;cru=0;bru=0;dyh=0;//没按下运算符号,输入的c无效,输入的b无效等号未按下
while
(1)
{
P1=0xf0;
if(P1!
=0xf0)
{
delay(30);
a=keyscan();//获取键位编号
}
if(a>9&&a<14)//判断符号是否按下,并显示
{
flag=1;
key=a;
fuhao=1;
caculate(key);//显示计算符号
}
if(a>=0&a<10)//判断按键是否有效
{
if(flag==1)
{
c=10*c+a;
if(c/10000)//判断是否超量程
c=0;//超出量程
cru=1;bru=1;//cru表示c是否输入有效
}
if(flag==0)//运算符号未按下
{
b=10*b+a;
if(b/10000)//bru表示b是否输入有效
b=0;bru=1;
}
}
if(a==14)//消除
{
if(flag==0)
b=b/10;
if(flag==1)
c=c/10;
}
if(a==15)//等号运算(加减乘除)
{
dyh=1;//等号按下
if(flag==1&&bru==1&&cru==1)
{
switch(key)
{
case10:
d=b+c;break;
case11:
if(b>=c)d=b-c;
if(b case12: d=b*c;break; case13: d=b/c;break; } } } if(bru==1) { P1=0x0f; while(P1==0x0f) { P1=0x0f; if(cru! =1&&dyh! =1&&fuhao==0) { if(b==0)//显示除数b { P2=DSY_CODE[0]; P3=0x80; } if(b! =0) dis(b); } if(cru! =1&&dyh! =1&&fuhao==1) caculate(key); if(cru==1&&dyh! =1&&fuhao==1) { if(c==0)//显示被除数c { P2=DSY_CODE[0]; P3=0x80; } if(c! =0) dis(c); } if(cru==1&&dyh==1&&key! =13&&fuhao==1)//如果除号没有按下则显示d dis(d); if(cru==1&&dyh==1&&key==13&&fuhao==1)//除号按下运算后,出现小数位 { if(b==b/c*c) dis(d);//整数除法 if(b! =b/c*c) div();//小数除法 d=b/c; } } if(flag==1&&cru==1&&bru==1&&dyh==1) { flag=0;cru=0;bru=0;b=d;c=0;dyh=0;fu=0;//多次运算符号置零 } } } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 课程设计 报告