keil软件的使用方法.docx
《keil软件的使用方法.docx》由会员分享,可在线阅读,更多相关《keil软件的使用方法.docx(62页珍藏版)》请在冰点文库上搜索。
keil软件的使用方法
Keil软件的使用
随着单片机开发技术的不断发展,目前已有越来越多的人从普遍使用汇编语言到逐渐使用高级语言开发,其中主要是以C语言为主,市场上几种常见的单片机均有其C语言开发环境。
这里以最为流行的80C51单片机为例来学习单片机的C语言编程技术。
大家都有C语言基础,但是编单片机程序,大家还得找专门的书来学习一下。
这里我们只介绍Keil这种工具软件的用法。
学习一种编程语言,最重要的是建立一个练习环境,边学边练才能学好。
Keil软件是目最流行开发80C51系列单片机的软件,Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(µVision)将这些部份组合在一起。
下面我以一个实验举一个例子,一步一步学习Keil软件的使用。
首先我们看硬件原理图:
很明显,要点亮使发光二极管,必须使单片机的I/O口P1.0输出低电平。
于是我们的任务就是编程序使P1.0输出地电平。
1.使用Keil前必须先安装。
安装过程简单,这里不在叙述。
2.安装好了Keil软件以后,我们打开它。
打开以后界面如下:
3.我们先新建一个工程文件,点击“Project->New Project…”菜单,如下图,:
3.选择工程文件要存放的路径,输入工程文件名LED,最后单击保存.
4.在弹出的对话框中选择CPU厂商及型号
5.选择好Atmel公司的AT89S52后,单击确定
1.在接着出现的对话框中选择“是”。
5.新建一个C51文件,单击左上角的NewFile如下图所示:
6.保存新建的文件,单击SAVE如下图:
2.在出现的对话框中输入保存文件名MAIN.C(注意后缀名必须为.C),再单击“保存”,如下图;
7.保存好后把此文件加入到工程中方法如下:
用鼠标在SourceGroup1上单击右键,然后再单击AddFilestoGroup‘SourceGroup1'如下图:
8.选择要加入的文件,找到MAIN.C后,单击Add,然后单击Close
9.在编辑框里输入如下代码:
10.到此我们完成了工程项目的建立以及文件加入工程,现在我们开始编译工程如下图所示:
我们先单击编译,如果在错误与警告处看到0Error(s)表示编译通过;
11.生成.hex烧写文件,先单击OptionsforTarget,如图;
12.在下图中,我们单击Output,选中CreateHEXF。
再单击“确定”。
13.打开文件夹‘实验1’,查看是否生成了HEX文件。
如果没有生成,在执行一遍步骤10到步骤12,直到生成。
以上是Keil软件的基本应用,更多的高级应用请大家去查找资料.
以下将介绍的是如何将HEX文件下载到单片机里面。
我们用的下载软件是
Easy51Pro
Easy51Prov2.0软件的使用
Easy51Prov2.0是单片机下载工具:
在我们的QQ群里有这个软件,大家可以下载来直接用,而不用安装。
下面我给大家简单的说一下用法:
1.硬件连接;必须满足下面的每一个条件才能下载。
如图
2.打开软件;
3.检测器件,注意右边的信息提示。
如果没有检测到器件,检查硬件连接。
3.打开HEX文件。
先单击“(自动)打开文件”。
在“实验1”的文件夹里找到文件LED.hex文件.
4.最后单击“自动完成”,OK大功告成。
5.大功既然告成,就要看到效果。
现在我们在实验板的左下角找到JK7,用导线连到P1.0上,LED2被点亮了把。
是不是很有成就感。
如果以上的实验你觉得是小儿科,太简单了。
那么请关注以下的内容。
一.闪烁灯
[实验任务]
在P1.0端口上接一个发光二极管L1,使L1在不停地一亮一灭,一亮一灭的时间间隔为0.2秒。
[硬件电路]
与上面点亮小灯的连接完全相同。
[C语言源程序]
#include
/*************************************************************************************
第一行是一个"文件包含"处理。
所谓"文件包含"是指一个文件将另外一个文件的内容全部包含进来,所以这里的程序虽然只有4行,但C编译器在处理的时候却要处理几十或几百行。
这里程序中包含REG51.h文件的目的是为了要使用P1这个符号,即通知C编译器,程序中所写的P1是指80C51单片机的P1端口而不是其它变量。
*****************************************************************************/
voiddelay02s(void)//延时0.2秒子程序
{
unsignedchari,j,k;//定义3个无符号字符型数据。
for(i=20;i>0;i--)//作循环延时
for(j=20;j>0;j--)
for(k=248;k>0;k--);
}
voidmain(void)//每一个C语言程序有且只有一个主函数,
{
while
(1)//循环条件永远为真,以下程序一直执行下去。
{
P1_0=0;//I/O口P1.0输出低电平,小灯被点亮。
delay02s();//延时经过0.2秒。
P1_0=1;//I/O口P1.0输出高电平,小灯熄灭。
delay02s();//延时经过0.2秒。
}
}
二.广告灯的左移右移
[实验任务]
做广告灯的左移右移,八个发光二极管分别接在单片机的P3.0-P3.7接口上,输出“0”时,发光二极管亮,开始时P3.0→P3.1→P3.2→P3.3→┅→P3.7→P3.6→┅→P3.0亮,重复循环。
[硬件电路]
[DPY-1实验板连接]
用8芯排线把JP-LSH连接到JP12上。
[C语言源程序]
#include
unsignedchari;
unsignedchartemp;
unsignedchara,b;
voiddelay(void)//延时子程序
{
unsignedcharm,n,s;
for(m=20;m>0;m--)
for(n=20;n>0;n--)
for(s=248;s>0;s--);
}
voidmain(void)//主程序
{
while
(1)//循环条件永远为真,以下程序一直执行下去。
{
temp=0xfe;
P3=temp;//直接对I/O口P3赋值,使.P3.0输出低点平。
delay();//延时
for(i=1;i<8;i++)//实现广告灯的从右到左移动(以原理图为准)
{
a=temp<
b=temp>>(8-i);
P3=a|b;
delay();
}
for(i=1;i<8;i++)//实现广告灯的从左到右移动
{
a=temp>>i;
b=temp<<(8-i);
P3=a|b;
delay();
}
}
}
三.按键识别
[实验任务]
通过按下一次按键,使广告灯向左移动一位,直到最后一位,在向右移动。
[硬件电路]
(大家注意到这一个电路图与上一个实验的电路图只多了一个按键和一个5.1K的电阻。
)
[DPY-1实验板连接]
用8芯排线把JP-LSH连接到JP12上。
用一根导线把JK5接到P2.1上。
[实验原理]
从图中可以看出P2.1在按键没有按下时接的是高电平,按键按下时接的就是低电平了。
所以我们只要判断P2.1的电平就可以知道按键是否被按下了。
而在按键按下的过程中,由于抖动,将产生干扰,在按下的过程中,一旦有干扰过来,可能造成误触发过程,这并不是我们所想要的。
因此在按键按下的时候,要把我们手上的干扰信号以及按键的机械接触等干扰信号给滤除掉,一般情况下,我们可以采用软件滤波的方法去除这些干扰信号,一般情况下,一个按键按下的时候,总是在按下的时刻存在着一定的干扰信号,按下之后就基本上进入了稳定的状态。
我们在程序设计时,从按键被识别按下之后,延时5ms以上,从而避开了干扰信号区域,我们再来检测一次,看按键是否真得已经按下,若真得已经按下,这时肯定输出为低电平,若这时检测到的是高电平,证明刚才是由于干扰信号引起的误触发,CPU就认为是误触发信号而舍弃这次的按键识别过程。
[C语言源程序]
#include
sbitBY1=P2^1;//定义按键的输入端
unsignedcharcount;//按键计数,每按一下,count加1
unsignedchartemp;
unsignedchara,b;
voiddelay10ms(void)//延时程序
{
unsignedchari,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
key()//按键判断程序
{
if(BY1==0)//判断是否按下键盘
{
delay10ms();//延时,软件去干扰
if(BY1==0)//确认按键按下
{
count++;//按键计数加1
if(count==8)//计8次重新计数
{count=0;}//将count清零
}
while(BY1==0);//按键锁定,每按一次count只加1.
}
}
move()//广告灯向左移动移动函数
{
a=temp<b=temp>>(8-count);
P3=a|b;
}
main()
{
count=0;//初始华参数设置
temp=0xfe;
P3=0xff;
P3=temp;
while
(1)//永远循环,扫描判断按键是否按下
{
key();//调用按键识别函数
move();//调用广告灯移动函数
}
}
四.数码管动态显示
[实验任务]
P0端口接动态数码管的字形码笔段,P2端口接动态数码管的数位选择端,动态显示“1234”字样;
[硬件电路]
注意:
在P0口还有1K的排阻作为上拉电阻,在以后的电路原理图中都是如此,请大家不要忽略了
[DPY-1实验板连接]
用排线把JP-CODE连到JP8是,注意:
a接P0.0;b接P0.1;c接P0.3……
把JP-CS连到JP14上,注意:
4H接P2.4;3H接P2.5;2H接P2.6;1H接P2.7;
[实验原理]
七段LED显示器内部由七个条形发光二极管和一个小圆点发光二极管组成,根据各管的极管的接线形式,可分成共阴极型和共阳极型。
LED数码管的a-dp七个发光二极管因以不同亮暗的组合就能形成不同的字形,这种组合称之为字形码,下面给出共阴极的字形码
“0”3FH“1”06H“2”5BH“3”4FH
“4”66H“5”6DH“6”7DH“7”07H
“8”7FH“9”6FH“A”77H“b”7CH
“C”39H“d”5EH“E”79H“F”71H
由于显示的数字0-9的字形码没有规律可循,只能采用查表的方式来完成我们所需的要求了。
这样我们按着数字0-9的顺序,把每个数字的笔段代码按顺序排好!
建立的表格如下所示:
TABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
动态接口采用各数码管循环轮流显示的方法,当循环显示频率较高时,利用人眼的暂留特性,看不出闪烁显示现象,这种显示需要一个接口完成字形码的输出(字形选择),另一接口完成各数码管的轮流点亮(数位选择)。
[C语言源程序]
#include
codeunsignedcharseg7code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f};//显示段码
voidDelay(unsignedinttc)//延时程序
{
while(tc!
=0)//如果tc为0则终止延时
{
unsignedinti;//局部正整数变量i
for(i=0;i<100;i++);//执行400次将耗时1毫秒
tc--;//tc计数减一
}
}
voidLed(intdate)//显示函数
{
P2=P2&0x7f;//P2.7输出低电平,选通千位数
P0=seg7code[date/1000];//取出千位数,查表,输出。
Delay(8);//延时
P2=P2|0xf0;//销隐
P2=P2&0xbf;//P2.6输出低电平,选通百位数
P0=seg7code[date%1000/100];//取出百位数,查表,输出。
Delay(8);//延时
P2=P2|0xf0;//销隐
P2=P2&0xdf;//P2.5输出低电平,选通十位数
P0=seg7code[date%100/10];//取出十位数,查表,输出。
Delay(8);//延时
P2=P2|0xf0;//销隐
P2=P2&0xef;
P0=seg7code[date%10];//取出个位数,查表,输出。
Delay(8);
P2=P2|0xf0;
}
main()
{
intdisplay_date=1234;//定义并赋值要显示的数据
while
(1)
{
Led(display_date);//调用显示函数显示数据display_date
}
}
五.4×4矩阵式键盘识别
[实验任务]
用AT89S51的并行口P3接4×4矩阵键盘,以P3.0-P3.3作输入线,以P3.4-P3.7作输出线;在每一个数码管上显示每个按键的“0-F”序号。
[硬件电路]
[DPY-1实验板连接]
用排线把JP-CODE连到JP8是,注意:
a接P0.0;b接P0.1;c接P0.3……
把JP-CS连到JP14上,注意:
4H接P2.4;3H接P2.5;2H接P2.6;1H接P2.7;用排线把JP-KEY连到JP12上,注意1,2,3,4,5,6,7,8,分别对应P3.0,P3.1,P3.3,P3.4……
[实验原理]
每个按键有它的行值和列值 ,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线分别通过两并行接口和CPU通信。
键盘处理程序的任务是:
确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。
两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
[C语言源程序]
#include
unsignedcharcodeseg7code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsignedchark;
voiddelay10ms(void)//延时程序
{
unsignedchari,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
voidGetch()
{unsignedcharX,Y,Z;
P3=0xff;
P3=0x0f;//先对P3置数行扫描
if(P3!
=0x0f)//判断是否有键按下
{delay10ms();//延时,软件去干扰
if(P3!
=0x0f)//确认按键按下X=P3;
{
X=P3;//保存行扫描时有键按下时状态
P3=0xf0;//列扫描
Y=P3;//保存列扫描时有键按下时状态
Z=X|Y;//取出键值
switch(Z)//判断键值(那一个键按下)
{
case0xee:
k=0;break;//对键值赋值
case0xde:
k=1;break;
case0xbe:
k=2;break;
case0x7e:
k=3;break;
case0xed:
k=4;break;
case0xdd:
k=5;break;
case0xbd:
k=6;break;
case0x7d:
k=7;break;
case0xeb:
k=8;break;
case0xdb:
k=9;break;
case0xbb:
k=10;break;
case0x7b:
k=11;break;
case0xe7:
k=12;break;
case0xd7:
k=13;break;
case0xb7:
k=14;break;
case0x77:
k=15;break;
}}}}//请注意写程序时的格式规范,此处是为了节省纸张
voidmain(void)
{
while
(1)
{P3=0xff;
Getch();
P0=seg7code[k];//查表LED输出
P2=0x0f;//输出相同的四位数据。
}
}
六.按键中断识别
[实验任务]
采用中断技术,每按一下按键,计数器加1,并用LED显示出来。
[硬件电路]
注意:
我们只用了4位数码管中的两位。
[DPY-1实验板连接]
用排线把JP-CODE连到JP8上,注意:
a接P0.0;b接P0.1;c接P0.3……
把JP-CS连到JP14上,注意:
2H接P2.0;1H接P2.1;中断按键已经接好。
[实验原理]
以上的两个关于按键识别的实验的程序都是采用扫描的方式来实现的,CPU的利用率比较低,在实时性要求高比较高,要求快速响应的场合不太实用。
中断方式可以满足快速响应的要求。
关于中断技术的具体内容,请大家参照教材。
[C语言源程序]
#include
unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsignedchardispcount=0;//计数
sbitgewei=P2^0;//个位选通定义
sbitshiwei=P2^1;//十位选通定义
voidDelay(unsignedinttc)//延时程序
{while(tc!
=0)
{
unsignedinti;
for(i=0;i<100;i++);
tc--;
}
}
voidExtInt0()interrupt0//中断服务程序
{
dispcount++;//每按一次中断按键,计数加一
if(dispcount==100)//计数范围0-99
{dispcount=0;}
}
voidLED()//LED显示函数
{
if(dispcount>=10)//显示两位数
{
shiwei=0;
P0=table[dispcount/10];
Delay(8);
shiwei=1;
gewei=0;
P0=table[dispcount%10];
Delay(5);
gewei=1;
}
else//显示一位数
{
shiwei=1;
gewei=0;
P0=table[dispcount];
Delay(8);
}
}
voidmain()
{TCON=0x01;//中断设置
IE=0x81;
while
(1)//循环执行
{
LED();//只须调用显示函数
}
}
七.定时器T0的应用---9.9秒计时设计
[实验任务]
开始时,显示“00”,第1次按下BY1后就开始计时。
第2次按BY1后,计时停止。
第3次按BY1后,计时归零。
[硬件电路]
注意这一个电路图与上一个的接法只是按键接的I/O口不一样。
所以只要用导线把JK5接到P3.0上就可以了。
[DPY-1实验板连接]
用排线把JP-CODE连到JP8上,注意:
a接P0.0;b接P0.1;c接P0.3……把JP-CS连到JP14,注意:
2H接P2.0;1H接P2.1;用导线把JK5接到P3.0上。
[C语言源程序]
#include
unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,};
unsignedcharsec;//定义计数值,每过1/10秒,sec加一
unsignedcharkeycnt=0;
unsignedinttcnt;//键值判断
sbitgewei=P2^0;//个位选通定义
sbitshiwei=P2^1;//十位选通定义
voidDelay(unsignedinttc)//延时程序
{
while(tc!
=0)
{
unsignedinti;
for(i=0;i<100;i++);
tc--;
}
}
voidLED()//LED显示函数
{
shiwei=0;
P0=table[sec/10];
Delay(8);
shiwei=1;
gewei=0;
P0=table[sec%10];
Delay(5);
gewei=1;
}
voidKEY()//按键扫描程序
{
unsignedchari,j;
if(P3_0==0)
{
for(i=20;i>0;i--)//延时去干扰
for(j=248;j>0;j--);
if(P3_0==0)
{
keycnt++;
switch(keycnt)//按下次数判断
{
case1:
//第一次按下
TH0=0x06;//对TH0TL0赋值
TL0=0x06;
TR0=1;//开始定时
break;
case2:
//第二次按下
TR0=0;//定时结束
break;
case3:
//第三