1、如何才能让LED 闪烁
闪烁的本质:亮----延时----灭----延时。
1.1:单片机如何实现延时
(1)单片机执行每条指令需要一定时间
(2)单片机开机后不能休息
(3)单片机可以"空转"来"浪费时间"
1.2:c语言实现延时
(1)笨办法:放多条指令实现延时
(2)正确方法:使用c语言循环语句实现延时
#include <reg51.h>
void main(void)
{
P0 = 0xff;//全亮
//延时
P0 = 0x00;//全灭
//延时
}
通过c语言循环语句实现延时代码:
#include <reg51.h>
void delay(void)
{
unsigned char i = 200;//定义无符号整数i,i的值越小闪的越快。
unsigned char j = 200;
while(i--)//循环
{
while(j--);
}
}
void main(void)
{
P0 = 0xff;
delay();//调用delay函数,函数中执行的代码和灯的亮灭无关。
P0 = 0x00;
delay();//调用delay函数 ,函数中执行的代码和灯的亮灭无关。
}
2、LED流水灯实现
2.1:流水灯本质分析
(1)流水灯的本质其实就是不同的亮的状态相互间隔一定时间。
(2)流水灯的状态
第1个状态等于0x80(1000 0000)
第2个状态等于0x40(0100 0000)
第3个状态等于0x20(0010 0000)
第4个状态等于0x10(0001 0000)
第5个状态等于0x08(0000 1000)
第6个状态等于0x04(0000 0100)
第7个状态等于0x02(0000 0010)
第8个状态等于0x01(0000 0001)
(3)延时时间越长流水灯就流的越慢,越短就流水越快。
(4)8个状态一次执行,完成后从头开始,其实就是一个循环
#include <reg51.h>
void delay(void)
{
unsigned char i = 100;
unsigned char j = 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.2:程序改进
功能实现了,但是写的太笨了,如果状态变多程序就会更长。
改进思路:通过变量运算来得到合适的端口输出值。
(1)首先定义变量unsigned char a,初值等于0x80(10000000)。
(2)8个状态,其实就是a依次右移0-7位。
(3)我们这样就相当于是用c语言让单片机自己去运算得到每个状态的端口值而不用自己事先去计算好。这样程序就简化了。
c语言移位运算介绍
(1)c语言中有移位运算符,>>可以右移,<<可以左移。(移出去的位丢掉了,空出来的位用0补)
#include <REGX51.H>
void delay(void)
{
unsigned char m;
unsigned char n;
for(m=0 ;m<200 ;++m)
{
for(n=0 ;n<200 ;++n)
;
}
}
void main(void)
{
while(1)
{
unsigned char i;
unsigned char j = 0x80;
for(i=0 ;i<=7 ;++i)
{
P0 = (j >> i);
delay();
}
}
}
3、跑马灯的实现
(1)跑马灯和流水灯非常像,不同的是:流水灯是8颗ED其中7灭1亮,亮的在移动;跑马灯是8颗LED7亮1灭,灭的在移动。
(2)跑马灯的状态:
第1个状态等于0xFE(1111 1110)
第2个状态等于0xFD(1111 1101)
第3个状态等于0xFB(1111 1011)
第4个状态等于0xF7(1111 0111)
第5个状态等于0xEF(1110 1111)
第6个状态等于0xDF(1101 1111)
第7个状态等于0xBF(1011 1111)
第8个状态等于0x7F(0111 1111)
(3)实践编程
编程实现跑马灯,必须用到c语言的2种技巧:左移(右移)、按位取反
C语言中~这个符号表示对一个数字按位取反,譬如一个数01111111按位取反后变成了10000000。而11011111按位取反后变成了00100000
#include <REGX51.H>
void delay(void)
{
unsigned char m;
unsigned char n;
for(m=0 ;m<225 ;++m)
{
for(n=0 ;n<225 ;++n)
;
}
}
void main(void)
{
while(1)
{
unsigned char i;
unsigned char j = 0x80;
for(i=0 ;i<=7 ;++i)
{
P0 = ~(j >> i);//按位取反赋给端口p0
delay();
}
}
}