1.流水灯的本质分析
(1)流水灯的本质其实就是不同的亮的状态相应间隔一定的时间。
(2)流水灯
第一个状态等于0x80(10000000)
第一个状态等于0x40(01000000)
第一个状态等于0x20(00100000)
第一个状态等于0x10(00010000)
第一个状态等于0x08(00001000)
第一个状态等于0x04(00000100)
第一个状态等于0x02(00000010)
第一个状态等于0x01(00000001)
(3)延长时间越长,流水灯就流的越慢,越短就流水越快
(4)8个状态一次执行,完成后从头开始,其实就是一个循环
#include <reg51.h>
void delay(void)
{
unsigned char i = 100;
unsigned char i = 100;
while (i--)
{
while (j--);
}
}
void main(void)
{
while (1)
{
p0 = 0x80;
delay();
p0 = 0x40;
delay();
p0 = 0x20;
delay();
p0 = 0x10;
delay();
p0 = 0x08;
delay();
p0 = 0x04;
delay();
p0 = 0x02;
delay();
p0 = 0x01;
delay();
}
}
2.上一节程序的缺陷分析
(1)功能实现了,但是写的太笨了,如果状态变多程序就更长。
(2)改进思路:通过变量运算来得到合适的端口输出值
①首先定义变量unsigned char a;
,初值等于0x80(10000000)
②8个状态,其实就是a依次右移0-7位
③我们这样就相当于是用C语言让单片机去运算得到每个状态的端口值,而不用自己事先去计算好。这样程序就简化了。
(3)C语言移位运算介绍
C语言中有移位运算符, >> 可以右移,<< 可以左移。(无符号所属移位:移出去的位丢掉了,空出来的位用0补)。
写法一:d本身没有发生改变,一直是0x80
#include <reg51.h>
void delay(void)
{
unsigned char i, j;
for (i=0; i<200; i--)
{
for (j=0; j<200; j--);
}
}
void main(void)
{
unsigned char i =0;
unsigned char d = 0x80;
while (1)
{
for (i=0; i<8; i++)
{
p0 = (d >> i);
delay();
}
}
}
写法二:d本身发生改变,0x80~0x0变化中
#include <reg51.h>
void delay(void)
{
unsigned char i, j;
for (i=0; i<200; i--)
{
for (j=0; j<200; j--);
}
}
void main(void)
{
unsigned char i =0;
while (1)
{
unsigned char d = 0x80;
for (i=0; i<8; i++)
{
d = d >> 1;
p0 = d;
delay();
}
}
}
3.跑马灯效果实现
3.1、什么是跑马灯
跑马灯和流水灯很像,不同的是:流水灯是8颗LED其中7灭1亮,亮的在移动;跑马灯是8颗LED7亮1灭,灭的在移动。
3.2、实现思路分析:
(1)一个个计算,01111111——0x7f
(2)左移(右移)+ 按位取反,10000000——~——01111111
#include <reg51.h>
void delay(void)
{
unsigned char i, j;
for (i=0; i<200; i++)
for (j=0; j<200; j++);
}
void main(void)
{
unsigned char i = 0;
while (1)
{
unsigned char d = 0x80;
for (i=0; i<8; i++)
{
p0 = ~d;
d >>= 1;
delay();
}
}
}