基于msc51单片机实现的四位4乘4矩阵键盘计算器的C语言程序和PROTUES电路和仿真课程设计报告.docx
《基于msc51单片机实现的四位4乘4矩阵键盘计算器的C语言程序和PROTUES电路和仿真课程设计报告.docx》由会员分享,可在线阅读,更多相关《基于msc51单片机实现的四位4乘4矩阵键盘计算器的C语言程序和PROTUES电路和仿真课程设计报告.docx(25页珍藏版)》请在冰豆网上搜索。
基于msc51单片机实现的四位4乘4矩阵键盘计算器的C语言程序和PROTUES电路和仿真课程设计报告
单片机原理及接口技术
课程设计报告
设计题目:
计算器设计
信息与电气工程学院
二零一三年七月
计算器设计
单片机体积小,功耗小,价格低,用途灵活,无处不在,属专用计算机。
是一种特殊器件,需经过专门学习方能掌握应用,应用中要设计专用的硬件和软件。
近年来,单片机以其体积小、价格廉、面向控制等独特优点,在各种工业控制、仪器仪表、设备、产品的自动化、智能化方面获得了广泛的应用。
与此同时,单片机应用系统的可靠性成为人们越来越关注的重要课题。
影响可靠性的因素是多方面的,如构成系统的元器件本身的可靠性、系统本身各部分之间的相互耦合因素等。
其中系统的抗干扰性能是系统可靠性的重要指标。
数学是科技进步的重要工具,数据的运算也随着科技的进步越发变得繁琐复杂,计算器的出现可以大大解放人在设计计算过程中的工作量,使计算的精度、速度得到改善,通过msc51单片机,矩阵键盘和LED数码管可以实现简单的四位数的四则运算和显示,并当运算结果超出范围时予以报错。
注:
这一部分主要描述题目的背景和意义,对设计所采取的主要方法做一下简要描述。
字数不要太多,300-500字。
另注:
本文要当做模板使用,不要随意更改字体、字号、行间距等,学会使用格式刷。
文中给出的各项内容都要在大家的报告中体现,可采用填空的方式使用本模板。
1.设计任务
结合实际情况,基于AT89C51单片机设计一个计算器。
该系统应满足的功能要求为:
(1)实现简单的四位十进制数字的四则运算;
(2)按键输入数字,运算法则;
(3)LED数码管移位显示每次输入的数据和运算结果;
(4)当运算结果超出范围时实现报错。
主要硬件设备:
AT89C51单片机、LED数码管、矩阵键盘。
注:
这一部分需要写明系统功能需求,用到的主要硬件(参考实验箱的说明书)。
2.整体方案设计
计算器以AT89C51单片机作为整个系统的控制核心,应用其强大的I/O功能和计算速度,构成整个计算器。
通过矩阵键盘输入运算数据和符号,送入单片机进行数据处理。
经单片机运算后判断是否超出要求的运算范围,控制LED数码管的输出原理图如图2-1所示。
图2-1基于单片机的变频调速恒压供水系统原理图
本系统硬件主要由矩阵键盘、I/O输入输出、显示系统……等几部分组成。
各模块的主要功能如下:
(1)矩阵键盘将十六进制编码的数字传入单片机。
(2)单片机扫描键盘信号并接收,对输入的键盘信号进行处理
(3)LED以动态扫描的方式移位显示每次输入的数据和最后的运算结果。
系统的整体设计方案设计图如图2-2所示。
图2-2系统的整体方案设计图
注:
文中出现的所有框图、流程图都要用VISIO画,不允许从文档中裁剪然后粘贴。
要注意图的格式,图中的文字大小不要大于正文,图题用五号宋体,居中。
3.系统硬件电路设计
3.1时钟电路
本设计采用外部时钟方式,使用外部振荡器产生脉冲信号,采用12MHz的石英晶体振荡器,结构如图3-1。
图3-1时钟电路和复位电路
3.2复位电路
本设计采用按键手动电平复位电路,通过RST端经电阻与电源Vcc接通而实现,结构如图3-1。
3.3数码管显示电路
本设计所用数码管显示电路采用4位红色共阴极数码管接上拉电阻实现,其结构如图3-2。
图3-2数码管显示电路
3.4键盘输入电路
本设计采用4*4矩阵键盘实现数据和运算法则的输入。
按键设置在行、列线的交点上,行列线分别连接的按键开关的两端,并通过上来电阻街道+5V上。
无按键按下时,行、列线均处于高电平,当有按键按下是,相对应的行和列电平为低电平。
此特点也用于单片机I/O口对矩阵键盘的扫描。
矩阵键盘和单片机的连接如图3-2所示。
图3-2矩阵键盘与单片机的连接图
注:
以上各部分按照电路功能模块化介绍器件选型、器件特性、电路设计思路、电路功能等,要注意与第2小节中的整体方案设计图相对应。
文中出现的电路原理图同样不能从资料中裁剪,可从自己设计的Proteus图中拷贝。
4.系统程序设计
4.1主程序流程图
单片机控制I/O口循环扫描键盘状态,当检测到有按键按下时,将按键信号输入单片机,处理并输出显示,若无按键按下,则保持前一个数据的显示状态。
系统主程序流程图如图4-1所示。
图4-1主程序流程图
4.2键盘扫描子程序流程图
先检测是否有按键按下,当有按键按下时,逐行检测每一行的列状态,将准确的键盘信号输入单片机。
……
键盘扫描流程图如图4-2所示。
图4-2键盘扫描流程图
4.3按键处理输出显示子程序流程图
输出的子程序包括运算数的输出和结果输出,当有数字键按下,之前的数字左移一位,最新按下的数字显示在第一位,当有符号键按下,屏幕清零,当有等号键按下,判断运算结果是否符合要求,若符合要求,输出结果,不符合要求,输出报错提示。
输出显示子程序流程图如图4-3所示。
图4-3按键处理显示输出子程序流程图
5.系统调试
这一部分分为Proteus软件仿真调试和硬件调试两部分,分别给出调试过程、调试时应注意的问题,分析遇到的问题及问题的解决方法,Proteus调试可截屏运行结果图形并加以分析。
5.1Proteus软件仿真调试
……
5.2硬件调试
……
6.程序清单
#include
#include
#include
#include
#include
unsignedcharkey_scan();
voiddelay10ms();
unsignedcharkey_free();
voiddisplay();
voiddisplay1(unsignedintnumber1);
voiddisplay2(unsignedintnumber2);
voiddisplay3(unsignedintnumber3);
voiddisplay4(unsignedintnumber4);
voiddisplay_result();
voiddelay(unsignedinttime);
voidkey_deal();
voiddisplay_error();
voidcaculate();
voidput_offleds();
unsignedcharnumbertable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6d,0x7D,0x07,0x7f,0x6f};//1至9的共阴显示段码
unsignedcharerrortable[]={0x86};//报错时使用的段码
unsignedcharweitable[]={0xfe,0xfd,0xfb,0xf7};//共阴数码管位选
unsignedinttemp,temp1,temp2,number1,number2,number3,number4,a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,way,k,k1,waytest,result_test;
unsignedintResult;result1,result2,result3,result4,E_test;
unsignedcharkey;
voidmain()
{
while
(1)
{
key_scan();
key_free();
key_deal();
}
}
//新的显示函数
voiddisplay()
{
display1(number1);
delay(6);
display2(number2);
delay(6);
display3(number3);
delay(6);
display4(number4);
delay(6);
}
voiddisplay1(unsignedintnumber1)
{
P2=weitable[3];
P1=numbertable[number1];
}
voiddisplay2(unsignedintnumber2)
{
P2=weitable[2];
P1=numbertable[number2];
}
voiddisplay3(unsignedintnumber3)
{
P2=weitable[1];
P1=numbertable[number3];
}
voiddisplay4(unsignedintnumber4)
{
P2=weitable[0];
P1=numbertable[number4];
}
//结果显示程序
voiddisplay_result()
{
display1(result1);
delay(6);
display2(result2);
delay(6);
display3(result3);
delay(6);
display4(result4);
delay(6);
}
//定义延时程序
voiddelay(unsignedinttime)
{
unsignedinti,j;
for(i=time;i>0;i--)
{
for(j=112;j>0;j--);
};
}
//按键扫描子程序
unsignedcharkey_scan()
{
P0=0x0f;//对所有行置高电平,列全为低电平
//P0=0xff;
temp1=P0;
if(temp1!
=0x0f)//如果有按键按下
{
//put_offleds();
//delay(3);
temp1=P0;//延时消抖
if(temp1!
=0x0f)
{
P0=0xf0;//翻转扫描列状态
//P0=0xff;
temp2=P0;
if(temp1==0x0e)//若第一行有按键按下
{k=0;//键盘按下动作标记
switch(temp2)
{
case0xe0:
//第一列有人按下
key=7;break;
case0xd0:
//第二列有人按下
key=8;break;
case0xb0:
//若第三列有人按下
key=9;break;
case0x70:
//若第四列有人按下
key='/';break;
}
}
elseif(temp1==0x0d)
//若第二行有按键按下
{k=0;//键盘按下动作标记
switch(temp2)
{
case0xe0:
//第一列有人按下
key=4;break;
case0xd0:
//第二列有人按下
key=5;break;
case0xb0:
//若第三列有人按下
key=6;break;
case0x70:
//若第四列有人按下
key='*';break;
}
}
elseif(temp1==0x0b)//若第三行有按键按下
{k=0;//键盘按下动作标记
switch(temp2)
{
case0xe0:
//第一列有人按下
key=1;break;
case0xd0:
//第二列有人按下
key=2;break;
case0xb0:
//若第三列有人按下
key=3;break;
case0x70:
//若第四列有人按下
key='-';break;
}
}
elseif(temp1==0x07)//若第4行有按键按下
{k=0;//键盘按下动作标记
switch(temp2)
{
case0xe0:
//第一列有人按下
key='.';break;
case0xd0:
//第二列有人按下
key=0;break;
case0xb0:
//若第三列有人按下
key='=';break;
case0x70:
//若第四列有人按下
key='+';break;
}
}
}
}
k+=1;
returnkey;
}
//延时程序
voiddelay10ms()
{unsignedchari,j;
for(i=0;i<25;i++)
{
for(j=0;j<80;j++)
{
}//延时1ms
}
}
//等待按键释放
unsignedcharkey_free()
{
key=key_scan();
P0=0x0F;//所有行置高电平
//P0=0xff;
temp=P0;
while(temp!
=0x0F)//如果仍有键按下
{
temp=P0;
};
return(key);//返回键值
}
//按键处理程序
voidkey_deal()
{
//对按下次数初始化
if(key=='.')//如果是清零符号
{
number1=0;
number2=0;
number3=0;
number4=0;
//k=0;
display();
waytest=0;
result_test=0;
E_test=0;
//嵌入显示程序
}
if(key!
='+'&&key!
='-'&&key!
='*'&&key!
='/'&&key!
='.'&&key!
='=')//如果key是数字
{
/*if(E_test==1)
{
number1=0;
number2=0;
number3=0;
number4=0;
E_test=0;
}*/
if(k==1)
{
number4=number3;
number3=number2;//移位显示
number2=number1;
//number1=key;
}
//k1=k;
number1=key;
/*if(k==5)
{
display_error();
}*/
display();//嵌入显示程序
}
if(key=='+'||key=='-'||key=='*'||key=='/')//如果key是运算符
{
way=key;
if(waytest!
=1)
{
a1=number1;
a2=number2;
a3=number3;
a4=number4;
}
waytest=1;
number1=0;
number2=0;
number3=0;
number4=0;
display();
//k=0;
//记录运算法则
//合成第一个运算数字赋值给number1并对number清零
}
if(key=='=')
{E_test=1;
//k=0;
if(waytest==1)//对第二个数进行赋值并对number清零
{b1=number1;
b2=number2;
b3=number3;
b4=number4;
}
caculate();//调用运算程序
if(Result!
=0x79)
{
display_result();
}
else
{
display_error();
}
}
}
voiddisplay_error()//定义报错显示程序
{
P2=weitable[1];
P1=0x79;
}
//新的运算子程序
voidcaculate()
{unsignedintNumber1,Number2;
Number1=a1+(a2*10)+(a3*100)+(a4*1000);
Number2=b1+(b2*10)+(b3*100)+(b4*1000);
switch(way)
{
case'+':
//加号运算
Result=Number1+Number2;
if(a4+b4>9)//报错标记
{
Result=0x79;
}
break;
case'-':
//减法运算
Result=Number1-Number2;
if(Number1{
Result=0x79;//报错标记
}
break;//考虑溢出设计
case'*':
//乘法运算
Result=Number1*Number2;
if(a4*b4!
=0||a3*b3!
=0)
{//报错标记
Result=0x79;
}
break;
case'/':
//除法运算
Result=Number1/Number2;
if(Number1{
Result=0x79;//报错标记
}
break;
default:
Result=Number1;
break;
}
result4=Result/1000;
result3=Result%1000/100;
result2=Result%100/10;
result1=Result%10;
}
//定义关闭数码管函数
voidput_offleds()
{
P1=0x00;
P2=0xff;
}
……
注:
以上程序清单的格式不能更改,采用CourierNew字体,5号大小,背景色不能缺,注意排列整齐、注释等。
7.小结
本部分对整个设计过程进行总结说明,对取得的成果进行简单评价,对存在的问题给出以后的展望或解决办法。
其他格式说明
以下主要对文中出现的图、表以及公式格式给出相关示例,请大家按照如下格式编排。
对图的格式要进行设置,首先设置其版式为“嵌入型”,然后将图和图下面的图号及图题居中排列,如图2-1所示。
图2-1水罐液位控制结构图
XXXX。
XXX如表2-1所示。
表2-1XXX
材料
名称
化学成分(%)
力学性能
C
Mn
Cr
其他
抗拉强度
σb
/N/mm2
屈服强度
σs
/N/mm2
弹性模量
E
/N/mm2
伸长率
δ
/%
布氏硬
度
/HBS
…
…
对于文中出现的所有公式,要求必须用公式编辑器进行编辑,并在后面作相应的标号,具体格式如下例所示,右对齐,公式本体依靠在公式号和公式本体之间加入空格实现居中。
(2-1)
(2-2)
报告内容编号说明:
1.节标题(小三黑体,段前段后6磅间距,顶格)
1.1条标题(小四黑体,段前6磅间距,顶格)
(1)一级子项标题(小四号宋体,首行缩进2字,行间距与正文相同,1.25倍行距,英文括号,编号与后面文字之间空一格,可加粗突出显示,也可不加粗)
(2)哈尔滨工业大学本科课程设计报告模板
1)二级子项标题(小四号宋体,首行缩进2字,英文半括号,编号与后面文字之间空一格,不加粗)
2)
①三级子项标题(编号形式有区别,别的同二级子项标题)