2.1程序功能与实现
硬件电路描述如下:89S52 单片机的P1 口接有8 个LED,当某一端口输出为“0”时,
相应的LED 点亮,P3.2、P3.3、P3.4、P3.5 分别接有四个按钮K1~K4,按下按钮时,相应
引脚被接地。现要求编写可键控的流水灯程序,当K1 按下时,开始流动,K2 按下时停止
流动,全部灯灭,K3 使灯由上往下流动,K4 使灯由下往上流动。
下面首先给出程序,然后再进行分析。
例 2-1:键控流水灯的程序
#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
void mDelay(unsigned int DelayTime)
{ unsigned int j=0;
for(;DelayTime>0;DelayTime--)
{ for(j=0;j<125;j++)
{;} }}
uchar Key()
{ uchar KeyV;
uchar tmp;
P3=P3|0x3c; //四个按键所接位置
KeyV=P3;
if((KeyV|0xc3)==0xff) //无键按下
return(0);
mDelay(10); //延时,去键抖
KeyV=P3;
if((KeyV|0xc3)==0xff)
return(0);
else
{ for(;;){ tmp=P3;
if((tmp|0xc3)==0xff)
break;}
return(KeyV);}}
void main()
{ unsigned char OutData=0xfe;
bit UpDown=0;
bit Start=0;
uchar KValue;
for(;;)
{ KValue=Key();
switch (KValue)
{ case 0xfb: //P3.2=0,Start
{ Start=1;
break; }
case 0xf7: //P3.3=0,Stop
{ Start=0;
break; }
case 0xef: //P3.4=0 Up
{ UpDown=1;
break; }
case 0xdf: //P3.5=0 Down
{ UpDown=0;
break; }
}
if(Start)
{ if(UpDown)
OutData=_crol_(OutData,1);
else
OutData=_cror_(OutData,1); P1=OutData;
}
else
P1=0xff; //否则灯全灭
mDelay(1000);
}
}
输入源程序,保存为exam21.c,建立名为exam21 的工程文件,选择的CPU 型号为
AT89S52,在Debug 页加入-ddpj6,以便使用单片机实验仿真板,其他按默认设置。正确编
译、链接后进入调试模式,点击Peripherals51 实验仿真板,打开实验仿真板,选择Run
(全速运行),此时实验仿真板没有变化,用鼠标点击上方的K1 按钮,松开后即可看到Led
“流动”起来,初始状态是由下往上流动,点击K3 按钮,可改变LED 的流动方向,改为
由上往下流动,点击K4 按钮,又可将流动方向变换回来。点击K2 按钮,可使流动停止,
所有LED“熄灭”。
2.1.1 程序分析
本程序中运用到了两种选择结构的程序:if 和switch,if 语句最常用的形式是:
if(关系表达式)语句1 else 语句2
2.1.2 关系运算符和关系表达式
所谓“关系运算”实际上是两个值作一个比较,判断其比较的结果是否符合给定的条件。
关系运算的结果只有2 种可能,即“真”和“假”。例:3>2 的结果为真,而3<2 的结果为
假。
C 语言一共提供了6 种关系运算符:“<”(小于)、“<=”(小于等于)、“>”(大于)、
“>=(大于等于)”、“==”(等于)和“!=”(不等于)。
用关系运算符将两个表达式连接起来的式子,称为关系表达式。例:
a>b,a+b>b+c,(a=3)>=(b=5)等都是合法的关系表达式。关系表达式的值只有两种
可能,即“真”和“假”。在C 语言中,没有专门的逻辑型变量,如果运算的结果是“真”,
用数值“1”表示,而运算的结果是“假”则用数值“0”表示。
如式子:x1=3>2 的结果是x1 等于1,原因是3>2 的结果是“真”,即其结果为1,该结
果被“=”号赋给了x1,这里须注意,“=”不是等于之意(C 语言中等于用“==”表示),
而是赋值号,即将该号后面的值赋给该号前面的变量,所以最终结果是x1 等于1。
式子:x2=3<=2 的结果是x2=0,请自行分析。
相应的LED 点亮,P3.2、P3.3、P3.4、P3.5 分别接有四个按钮K1~K4,按下按钮时,相应
引脚被接地。现要求编写可键控的流水灯程序,当K1 按下时,开始流动,K2 按下时停止
流动,全部灯灭,K3 使灯由上往下流动,K4 使灯由下往上流动。
下面首先给出程序,然后再进行分析。
例 2-1:键控流水灯的程序
#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
void mDelay(unsigned int DelayTime)
{ unsigned int j=0;
for(;DelayTime>0;DelayTime--)
{ for(j=0;j<125;j++)
{;} }}
uchar Key()
{ uchar KeyV;
uchar tmp;
P3=P3|0x3c; //四个按键所接位置
KeyV=P3;
if((KeyV|0xc3)==0xff) //无键按下
return(0);
mDelay(10); //延时,去键抖
KeyV=P3;
if((KeyV|0xc3)==0xff)
return(0);
else
{ for(;;){ tmp=P3;
if((tmp|0xc3)==0xff)
break;}
return(KeyV);}}
void main()
{ unsigned char OutData=0xfe;
bit UpDown=0;
bit Start=0;
uchar KValue;
for(;;)
{ KValue=Key();
switch (KValue)
{ case 0xfb: //P3.2=0,Start
{ Start=1;
break; }
case 0xf7: //P3.3=0,Stop
{ Start=0;
break; }
case 0xef: //P3.4=0 Up
{ UpDown=1;
break; }
case 0xdf: //P3.5=0 Down
{ UpDown=0;
break; }
}
if(Start)
{ if(UpDown)
OutData=_crol_(OutData,1);
else
OutData=_cror_(OutData,1); P1=OutData;
}
else
P1=0xff; //否则灯全灭
mDelay(1000);
}
}
输入源程序,保存为exam21.c,建立名为exam21 的工程文件,选择的CPU 型号为
AT89S52,在Debug 页加入-ddpj6,以便使用单片机实验仿真板,其他按默认设置。正确编
译、链接后进入调试模式,点击Peripherals51 实验仿真板,打开实验仿真板,选择Run
(全速运行),此时实验仿真板没有变化,用鼠标点击上方的K1 按钮,松开后即可看到Led
“流动”起来,初始状态是由下往上流动,点击K3 按钮,可改变LED 的流动方向,改为
由上往下流动,点击K4 按钮,又可将流动方向变换回来。点击K2 按钮,可使流动停止,
所有LED“熄灭”。
2.1.1 程序分析
本程序中运用到了两种选择结构的程序:if 和switch,if 语句最常用的形式是:
if(关系表达式)语句1 else 语句2
2.1.2 关系运算符和关系表达式
所谓“关系运算”实际上是两个值作一个比较,判断其比较的结果是否符合给定的条件。
关系运算的结果只有2 种可能,即“真”和“假”。例:3>2 的结果为真,而3<2 的结果为
假。
C 语言一共提供了6 种关系运算符:“<”(小于)、“<=”(小于等于)、“>”(大于)、
“>=(大于等于)”、“==”(等于)和“!=”(不等于)。
用关系运算符将两个表达式连接起来的式子,称为关系表达式。例:
a>b,a+b>b+c,(a=3)>=(b=5)等都是合法的关系表达式。关系表达式的值只有两种
可能,即“真”和“假”。在C 语言中,没有专门的逻辑型变量,如果运算的结果是“真”,
用数值“1”表示,而运算的结果是“假”则用数值“0”表示。
如式子:x1=3>2 的结果是x1 等于1,原因是3>2 的结果是“真”,即其结果为1,该结
果被“=”号赋给了x1,这里须注意,“=”不是等于之意(C 语言中等于用“==”表示),
而是赋值号,即将该号后面的值赋给该号前面的变量,所以最终结果是x1 等于1。
式子:x2=3<=2 的结果是x2=0,请自行分析。