Step1 :【C51】LED灯闪烁、跑马灯、流水灯、实现每次亮两个灯的流水灯
S t e p 1 Step1 Step1 :【C51】LED灯闪烁、跑马灯、流水灯、实现每次亮两个灯的流水灯
在我所使用的开发板中,LED采用共阳极接法,即所有LED阳极管脚接电源VCC,其阴极管脚接到P2口上。因此,LED发光时,其对应的阴极管脚应为低电平;LED熄灭时,其对应的阴极管脚应为高电平。
LED模块( L E D 0 − 7 LED_{0-7} LED0−7,8个LED灯):
LED0 | LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 |
---|
LED灯闪烁
要求:点亮LED0并让其闪烁。
实现方法:循环让LED灯亮一段时间、熄灭一段时间。(需要用到延时函数)
实现代码:
#include<reg52.h>
sbit LED0=P2^0;
void delay(int n);//延时函数
void main()
{
while(1)//一个死循环,循环执行LED1亮、灭灯操作
{
LED0=0;//亮灯
delay(1000);//延时约1s
LED0=1;//灭灯
delay(1000);
}
}
void delay(int n)
{
int i,j;
for(i=1;i<=n;i++)
for(j=0;j<100;j++);
}
LED跑马灯
要求:实现LED跑马灯,需要循环让LED0-LED7逐个点亮。
实现方法:移位方法实现跑马灯。(方法不唯一)
LED灯具体亮灭情况如下表:
P2端口值 | LED0 | LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 |
---|---|---|---|---|---|---|---|---|
0xFE | 亮 | 灭 | 灭 | 灭 | 灭 | 灭 | 灭 | 灭 |
0xFD | 灭 | 亮 | 灭 | 灭 | 灭 | 灭 | 灭 | 灭 |
0xFB | 灭 | 灭 | 亮 | 灭 | 灭 | 灭 | 灭 | 灭 |
0xF7 | 灭 | 灭 | 灭 | 亮 | 灭 | 灭 | 灭 | 灭 |
0xEF | 灭 | 灭 | 灭 | 灭 | 亮 | 灭 | 灭 | 灭 |
0xDF | 灭 | 灭 | 灭 | 灭 | 灭 | 亮 | 灭 | 灭 |
0xBF | 灭 | 灭 | 灭 | 灭 | 灭 | 灭 | 亮 | 灭 |
0x7F | 灭 | 灭 | 灭 | 灭 | 灭 | 灭 | 灭 | 亮 |
实现代码:
#include<reg52.h>
#include<intrins.h>//进行移位操作的头文件
void delay(int times);
void main()
{
int i;
while(1)
{
P2=0xFE;//P2口的8个引脚被赋值成1111,1110,代表只有P2^0口是低电平,其余都是高电平。
//即只有LED0亮,其余LED灯处于熄灭状态。
//8个引脚与0xFE的2进制分别对应!
for(i=0;i<8;i++)
{
P2=_crol_(P2,1);//每次循环左移一位。
delay(1000);
}
}
}
void delay(int times)
{
times=times*10000;
while(times--);
}
LED流水灯
要求:实现LED流水灯,需要循环让LED0-LED7依次点亮。
实现方法:移位方法实现流水灯。(方法不唯一)
LED灯具体亮灭情况如下表:
P2端口值 | LED0 | LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 |
---|---|---|---|---|---|---|---|---|
0xFE | 亮 | 灭 | 灭 | 灭 | 灭 | 灭 | 灭 | 灭 |
0xFD | 亮 | 亮 | 灭 | 灭 | 灭 | 灭 | 灭 | 灭 |
0xFB | 亮 | 亮 | 亮 | 灭 | 灭 | 灭 | 灭 | 灭 |
0xF7 | 亮 | 亮 | 亮 | 亮 | 灭 | 灭 | 灭 | 灭 |
0xEF | 亮 | 亮 | 亮 | 亮 | 亮 | 灭 | 灭 | 灭 |
0xDF | 亮 | 亮 | 亮 | 亮 | 亮 | 亮 | 灭 | 灭 |
0xBF | 亮 | 亮 | 亮 | 亮 | 亮 | 亮 | 亮 | 灭 |
0x7F | 亮 | 亮 | 亮 | 亮 | 亮 | 亮 | 亮 | 亮 |
实现代码:
#include<reg52.h>
void delay(int times);
void main()
{
int i;
while(1)
{
for(i=0;i<8;i++)
{
P2=0xFE<<i;//每次逻辑左移i位
//注意逻辑移位和循环移位的区别(本文末有提及)
delay(1000);
}
}
}
void delay(int times)
{
times=times*10000;
while(times--);
}
实现每次亮两个灯的流水灯
要求:每次亮起相邻两个灯,闪烁三次后,移动一位。
实现方法:结合LED灯闪烁和流水灯实验所用的方法,稍加改动即可。
实现代码:
#include<reg52.h>
#include<intrins.h>
void delay(int times);
void main()
{
int i,temp,times;
while(1)
{
P2=0xFC;//11111100->LED0、LED1亮
for(i=0;i<8;i++)
{
temp=_crol_(P2,1);
times=3;
while(times--!=0)//闪烁三次
{
P2=temp;
delay(1000);
P2=0xFF;//11111111->所有LED灯熄灭
delay(1000);
P2=temp;//因为进行熄灭操作时将P2赋值为了0xFF,即11111111
//若不引入temp变量暂存当前P2的值,之后的移位操作将毫无意义
//你会发现LED灯一直不会亮(因为P2的8个引脚全为1了,咋移都亮不了)
}
}
}
}
void delay(int times)
{
times=times*10000;
while(times--);
}
补充知识
①bit 和 sbit 型
它们在内存中都只占一个二进制位,其值可以是“1”或“0”。其中:用 bit 定义的位变量在C51编译器编译时,在不同的时候位地址是可以变化的,而用 sbit 定义的位变量必须与51单片机的一个可以寻址位单元或可位寻址的字节单元中的某一位联系在一起,在C51编译器编译时,其对应的位地址是不可变化的。
bit— 位变量声明,当定义一个位变量时可使用此符号。
sbit— 特殊功能位声明, 也就是声明某一个特殊功能寄存器中的某一位。
sfr-对单字节的特殊功能寄存器的数据声明,声明一个8位的寄存器。
sfr16—对双字节的特殊功能寄存器的数据声明。
②C51的移位操作
循环移位:
_crol_:字符循环左移。将char型变量循环向左移动指定位数后返回(将高位补低位)
_cror_:字符循环右移。将char型变量循环向左移动指定位数后返回(将高位补低位)
_irol_:整数循环左移。将int型变量循环向左移动指定位数后返回(将高位补低位)
_iror_:整数循环右移。将int型变量循环向右移动指定位数后返回(将低位补高位)
逻辑移位:
<<:逻辑左移。左移时,低位补0;高位移出的部分舍弃。
>>:逻辑右移。右移时,高位补0;低位移出的部分舍弃。
更多推荐
所有评论(0)