1)
多个LED灯闪烁或流动—延时函数—流水灯
l
延时子程序段(延时函数)可以产生闪烁效果。下面是带闪烁的字节传送:
#include
#define
uchar unsigned char
//定义了DelayMS等函数名
#define
uint unsigned int
//定义了x,i等变量名
void
DelayMS(uint x) //延时函数 —非主函数,用户定义的函数,可被调用
{ //
DelayMS(uint x)函数的自变量使x,返回值是因变量DelayMS的值
while(x--)
; //条件循环语句,C语言的保留字,x每循环一次,自动减1,直至x为0,终止循环
}//注意while(1) ; 将成为永久循环,因为条件始终为真—非0
//主函数
void main()
{
P1=0x00; //将16进制数00H赋给P1口,字节传送
DelayMS(200); //调延时函数,并传递数值x=200。直接用函数名,则为调用。
P1=0xff; //将16进制数FF赋给P1口,字节传送
DelayMS(200); //调延时函数,并传递数值x=200—参数传递
}
程序说明:
u
数据类型与变量及函数命名、运算符、表达式及其语句问题:
u
程序控制—逻辑运算和判断、循环控制、函数调用等问题
While(条件语句)与for(条件语句)单独使用所表达的循环,是在句首先执行判断,为真(1)循环,为假(0)转下一句执行(顺序执行)。其中语句的括号内为判断条件语句。
Do-while合用,是需要对do的过程再进行一次判断。While(条件语句)为真循环,为假跳转。while(1)表示高电平为真循环do,否则,低电平跳转。由于P1.0 口为高电平结尾,因此,又回到do再循环,无限反复。参见图-2。
2)
多种软控制形成流水灯
l
利用延时函数产生闪烁,可以形成流水灯
位控制流水灯
移位控制流水灯
P1=0x00
DelayMS(200)
P1=_cror_(P1,1); //
右移 / P1=_crol_(P1,1);左移//51-C语言专门定义的函数
字节控制流水灯
P1=0x00;DelayMS(200);P1=0x01;DelayMS(200);P1=0x02;DelayMS(200);
P1=0x04;DelayMS(200); P1=0x08; DelayMS(200);P1=0x10; DelayMS(200);
P1=0x20; DelayMS(200);P1=0x40; DelayMS(200);P1=0x80;DelayMS(200);
数表字节控制流水灯
Uchar code
SHuZi[]={0x7F,0xfb,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x7F,0xfb,0xdf,
0xef,0xf7,0xfb,0xfd,0xfe};
//给数组的所有元素赋初值,可以不指定数组元素的个数
Uchar code
LiuSHui[]={0x01,0x02,0x04,0x08,0x80,0x40,0x20,0x10};
数组的赋值与引用
P3=SHuZi [i];
1.
单个按键控制,单个与多个LED灯(位操作—输入与字节操作—输出)—有简单输入和多种输出方式的最小系统及其输出形式组合—最小系统I/O
a)
单个按键与单个LED灯(位操作—输入与位操作—输出)—判断语句与函数
b)
单个按键与多个LED灯(位操作—输入与字节操作—输出)—判断语句与函数
c)
单个按键与多个LED灯(位操作—输入与混合操作—输出)—判断语句与函数
d)
单个按键与单个电机控制—开环控制(位操作—输入/输出)—判断语句与函数
2.单个按键控制,单个与多个LED灯(位操作—输入与字节操作—输出)
通过按键开关来模拟输入端的信号—数据变化。先用单个按键控制一位的端口状态(0或1)来表示。通过判断端口的位状态来发送必需的指令及其输出端口,可以输出位或字节。这里需要结构化语言的分支结构进行程序设计。
分支结构的基本形式:
If(条件表达式)
语句;
可以用复合语句If(判断表达式)
{语句;……}
If(条件表达式)
语句1;else 语句2; 可以用复合语句
If(条件表达式1) 语句1;else if
(条件表达式2) 语句2;……;else 语句n;
switch(表达式) {case 常量表达式1:语句1;……;case 常量表达式n:语句n;default:语句n+1;}
1)
单个按键与单个LED灯(位操作—输入与输出)—判断语句、循环与函数
l
如果是位传送,受制于开关的控制,则:(参见图-3):无判断语句—单键单位
#include
//预处理指令,将头文件reg51.h转换为与C语言一致的格式
//声明变量
sbit
LED1_0=P1^0; //
#define 头文件中没有定义的I/O,在此由用户定义
sbit
LED2_0=P2^0; //这里是位定义,区别与字节定义
sbit LED3_0=P3^0;
void main() //主函数
{ //函数体开始—顺序执行—顺序结构
LED2_0=P2^0; //语句,函数体内容,将P2.0口状态位赋给LED2_0
LED1_0=LED2_0; //语句,函数体内容;也可以用LED1_0=P2^0
LED3_0=~LED2_0; //语句,函数体内容;也可以用LED3_0= ~LED1_0
} //函数体结束
l
如果是位传送,受制于开关的控制,则:(见图-4)
无判断语句—单键双位、延时函数、循环(硬件显示所见到的循环、结构化软件设计的循环模式)
#include
#define
uchar unsigned char
#define
uint unsigned int
//设置
sbit SW2_0=P2^0; sbit
LED0=P0^0; sbit LED10=P1^0; sbit LED11=P1^1;
sbit LED12=P1^2; sbit
LED13=P1^3; sbit LED14=P1^4; sbit LED15=P1^5;
sbit LED16=P1^6; sbit
LED17=P1^7; sbit LED3=P3^0;
//延时 –函数
void
DelayMS(uint x)
{ uchar i;
while(x--) //循环–函数,x--到0
{
for(i=0;i<120;i++);
//循环
}
}
void
main()//主程序—主函数
{
while(1) //循环无限
{ LED0=SW2_0; DelayMS(100);
LED10=~SW2_0; DelayMS(100);
LED11=~SW2_0; DelayMS(100);
LED12=~SW2_0; DelayMS(100);
LED13=~SW2_0;
DelayMS(100);
LED14=~SW2_0; DelayMS(100);
LED15=SW2_0; DelayMS(100);
LED16=SW2_0; DelayMS(100);
LED17=SW2_0; DelayMS(100); LED3=SW2_0; DelayMS(100); //顺序执行 }
}
l
下面是添加了判断条件的用于耗时—延时:有判断语句和循环
#include
//预处理命令
void main(void)
//主函数名,必须有一个主函数,void为数据类型
{
unsigned int
a; //定义变量,a为int类型,无符号整型。语句必须分号结尾
do
{ //do-while
组成的循环过程,过程的开始
for (a=0;
a<500; a++); //这是一个条件循环,判断a的值是否小于500,真循环-耗时,假转下句
P1_0 =
0;
//位赋值语句,设 P1.0 口为低电平—置0,点亮 LED
for (a=0;
a<500;
a++); //这又是一个判断循环
P1_0 =
1; //设 P1.0 口为高电平,熄灭 LED
}
while(1); //do-while 组成循环过程的末尾,需要对do的过程进行一次判断
}
***********************
#include
//预处理指令,将头文件reg51.h转换为与C语言一致的格式
//声明变量
sbit
LED1_0=P1^0; //
#define 头文件中没有定义的I/O,在此由用户定义
sbit
LED2_0=P2^0; //这里是位定义,区别与字节定义
sbit LED3_0=P3^0;
void main() //主函数
{ //函数体开始
LED2_0=P2^0; //语句,函数体内容,将P2.0口状态位赋给LED2_0
do
{ //do-while
组成的循环过程,过程的开始
for (a=0; a<500;
a++); //这是一个条件循环,判断a的值是否小于500,真循环-耗时,假转下句
LED1_0=LED2_0; //语句,函数体内容;也可以用LED1_0=P2^0
for
(a=0; a<500;
a++); //这又是一个判断循环
LED3_0=~LED2_0; //语句,函数体内容;也可以用LED3_0= ~LED1_0
}
while(1);//do-while 组成循环过程的末尾,需要对do的过程进行一次判断
} //函数体结束
程序说明:
u
程序控制—逻辑运算和判断、循环控制、函数调用等问题
要使得灯受制于开关的控制,位传送或字节传送,则需要添加判别(判断)条件语句,以便区别(转换)位与字节输出。
关于C语言中的循环控制模式:结构化程序设计通常有三种基本控制模式(语言的结构模式),顺序执行(顺序结构)、判断与分支(分支结构、条件控制)、反复执行(循环结构)。
循环结构的基本形式:
goto 语句标号;不得已才使用!loop: if(条件表达式) {
……;goto loop;} 语句;
while (条件表达式) 语句;
或复合语句—while (条件表达式){语句;……;语句; }
do语句; while(条件表达式)—先执行后判断,而while (条件表达式) 语句;先判断后执行。少1循环
for (表达式1;表达式2;表达式3;) 语句;
循环可以嵌套
循环结构的终止—跳出循环 break continue
***********************************************************
2)
单个按键与多个LED灯(位操作—输入与字节操作—输出)—判断语句与函数
对于多个LED灯(LED数 <
8个或>8但不是8的倍数)来说,在硬件连接方面、软件编写方面均没有大的难点。按照单个LED的连接方式增加便可。控制程序编写基本上也是重复性工作—用COPY简单修改即可。
l
对于LED数<
8个需要用位操作指令。需要解决两个方面的问题。一个是硬件的连接方法,一个是控制程序的编写指令—用词方法。硬件方面可以用单个或多个成组的LED多个或总线接口、单个接口扩展等。程序编写则可以使用重复性工作、可以使用字节命令而摒弃位命令,使得程序简洁、可读性好、硬件运行效率高。
l
对于LED数=
8个或是8的倍数的情况,硬件方面可以用单个或多个成组的LED多个或总线接口、单个接口扩展等。程序编写则可以使用重复性工作、可以使用字节操作指令而摒弃位操作指令,使得程序简洁、可读性好、硬件运行效率高。
l
LED数目>8但不是8的倍数,用位传送数据
a)
单输入与单、多输出电子线路—静态特性
参见图3、图4等
b)
单输入与单、多输出电子线路与控制指令—电子线路动态特性—行为及其结果
参见图3、图4等