暗中观察
默默关注
流水灯可以有一个花样,也可以有多个花样,所以可称为花样流水灯。
1、RROTEUS仿真电路图如下(共阳极接法、P2口八路流水灯)
2、写出程序并创建*.hex文件(按不同花样分解依次设计程序)。
花样1:自左至右依次流水,每次只亮一个灯。程序如下:
先来补充三个知识点。
(1)“宏”定义
#define是一个宏定义命令,它常用来指定常数、字符串或者宏函数的代用标识符。其指令格式如下。
#define 代名词 常数(字符串或者宏函数)
例如:
#define outputs P0 //定义使用outputs代替P0。
定义后,当程序中用P0口输出时,如P0=0xFF就可以用outputs=0xFF代替。
程序中 #define uchar unsigned char定义使用uchar代替unsigned char,#define uint unsigned int定义使用uint代替unsigned int。
(2)移位(〉〉和〈〈)和循环移位函数(_crol_ ,_cror_)
A、标准C语言中的移位操作符">>"右移一次,超过8位的就被舍去了,最高位补0。
应用举例:
一,问:计算表达式14
答:表达式14
二,问: 计算表达式8 >> 2的值。
具体还需要自己多调试调试。
B、循环移位函数(_crol_, _cror_)
在51头文件reg51.h中没有循环移位函数的定义,而在intrins.h中有说明,所以需要调用intrins.h头文件。
_crol_( m1 , m2 )循环左移位函数
_cror_( m1 , m2 )循环右移位函数
其中m1为需要移位的变量,m2为需要移动的位数。移出去的码循环移动的另一端。
例如程序中i=0xfe(1111 1110); i=_crol_(i,1)意思为将变量i循环左移一位,i=0xfd(1111 1101);
循环移位函数在执行效率上,肯定比标准C的移位效率高,因为不用管移出的超过8位的位。
(3)延时子程序delay(uint t)
子函数是一种具有相对独立功能的程序,其结构与主程序相似。函数格式如下:
返回数据类型 函数名(传入数据类型)
函数可将要处理的数据传入该函数,也可将函数处理完成的数据返回到调用它的程序中。如将一个字符型数据(char)传入函数,处理完成后返回一个整型数据(int),假定其函数名为“SUB_name”,则函数可以这样定义:int SUB_name(char x)
如果不需要传入函数,则可在小括号内用"void"代替,函数可以这样定义:int SUB_name(void)
如果不要返回数据,则可以在函数名左侧用"void"代替,函数可以这样定义:void SUB_name(char x)。
如本设计中的1ms延时子函数:
void delay(uint t) //无返回值的带有传入数据的子函数
{
uchar j;
while(t--)
for(j=0;j
}
因此,如果想要一个500ms的延时,可以直接调用此函数delay(500),使用起来非常方便,而且理论延时时间很接近实际时间。
此外,需要掌握几个时间转换公式。
1ms=1000us, 1s=1000ms, 1s=106us
现将程序附于下:
#include //调用51单片机头文件,include调用
#include //调用头文件,intrins.h中含有循环移位函数
#define uchar unsigned char //宏定义使用uchar代替unsigned char
#define uint unsigned int //宏定义使用uint代替unsigned int
void delay(uint t) //1ms延时子函数
{
uchar j;
while(t--)
for(j=0;j
}
void main()
{
uchar i;
i=0xfe; //设定左边第一个灯亮的初始码
while(1) //死循环
{
P2=i; //将代码编入外接八路流水灯的P2口
delay(500); //延时500ms,如果是delay(1000)则延时1s
i=_crol_(i,1); //将代码循环左移一位数
}
}
花样2:自右至左依次流水,每次只亮一个灯。程序如下:
只改动了主程序中注释的两处,在此不再详述。
花样3:自右至左依次流水,每次亮两个灯。程序如下:
花样4:自左至右依次流水,每次亮两个灯。程序如何改动呢?
花样5:每次只亮一个灯,流水时间隔一个灯再亮?
花样6:八路灯同时闪烁?
... ...
各种花样太多了,就不一一罗列了。
最后将你需要的花样组合到一个程序之中,就可以实现你想要的效果,是不是感觉很有意思呢?
快,关注这个公众号,一起涨姿势~
领取专属 10元无门槛券
私享最新 技术干货