控制/MCU
前言
前面的几个教程我们实现了点亮LED灯并实现了闪烁,而本教程我们要进一利用开发板的LED&交通灯模块实现LED的流水灯设计,将采用位移循环和库函数的调用实现该功能。
一、使用移位和循环实现
如果要实现LED 流水灯,只需循环让D1-D8 指示灯逐个点亮。同样本实验也需要延时,这个在前面已介绍,这里就不多说。要实现循环点亮,可以使用最容易理解的方法:点亮D1 且把D2-D8 熄灭,延时一段时间后再点亮D2 且把D1、D3-D8 熄灭,延时一段时间后再点亮D3 且把D1-D2、D4-D8 熄灭,如此循环,这样就可以很简单的实现LED 流水灯实验,当然我们不推荐此种方法。在前面我们学习了C 语言相关的基础知识,里面有移位以及循环语句操作,根据流水灯实现原理,即IO 口由低往高或者由高往低逐个输出低电平特点,那么我们可以将移位操作以及循环结合进来。实现代码如下:
#include< reg52.h >
typedef unsigned int u16;
typedef unsigned char u8;
#define LED_PORT P2//使用宏定义 直接定义p2全部PI端口
void delay_10us(u16 time_us)
{
while(time_us--);
}
void main()
{
u8 i=0;
while(1)
{
for(i=0;i< 8;i++)
{
LED_PORT=~(0x01<
进入main 函数后首先定义一个变量i,然后进入while 循环,由于要实现8个LED 从D1->D8 循环点亮,因此可以使用for 循环语句循环8 次,每循环一次,点亮的小灯向右移动一个,而D1-D8 是连接到P2.0-P2.7 的,因此输出的电平要左移一位,因此可以使用LED_PORT=~(0x01<
二、使用左移_crol_、右移_cror_函数
除了使用for 循环语句实现移位,KEIL C51 软件内还有对应的移位库函数,左移函数是_crol_(),右移函数是_cror_(),要使用这两个函数在我们的程序中必须包含**intrins.h **头文件。这两个移位函数,大家可以百度了解下,其内部实现过程是看不到的,该移位函数实现的移位功能就相当于一个队列内循环移动,如果是左移,那么最高位就被移到最低位了,次高位变为最高位,依次类推。使用左移、右移函数实现的流水灯操作代码如下:
#include< reg52.h >
#include< intrins.h >
#define LED_PORT P2
typedef unsigned int u16;
typedef unsigned char u8;
void delay_10us(u16 time_us)
{
while(time_us--);
}
void main()
{
u8 i=0;
LED_PORT=~0x01 ;
while(1)
{
for(i=0;i< 7;i++)
{
LED_PORT =_crol_(LED_PORT,1);
delay_10us(50000);
}
for(i=0;i< 7;i++)
{
LED_PORT =_cror_(LED_PORT,1);
delay_10us(50000);
}
}
}
进入main 函数后首先定义一个变量i,LED_PORT=~0x01,因为LED 是低电平点亮,所以0X01 取反后的结果是0XFE,对应二进制数为1111 1110,即最低位为0,因此最开始的D1 指示灯会点亮,然后进入while 循环,使用for 循环、_crol_和_cror_移位函数实现LED 左右流水显示。
细心的朋友可能会发现此处每个for 循环只有7 次,为什么不是8 次呢,这是因为在进入whlie循环时,就已经将LED_PORT 端口设置了一次状态,即让D1 点亮,并且我们是想让LED 从左至右依次点亮,然后继续又从右至左依次点亮,这样形成左右流水效果。假如将循环次数改为8 次,我们列举下第一个for 循环的LED_PORT 端口状态值,如下所示:
初始状态:LED_PORT=1111 1110
i=0:LED_PORT=1111 1101
i=1:LED_PORT=1111 1011
i=2:LED_PORT=1111 0111
i=3:LED_PORT=1110 1111
i=4:LED_PORT=1101 1111
i=5:LED_PORT=1011 1111
i=6:LED_PORT=0111 1111
i=7:LED_PORT=1111 1110
通过上述列举,可以非常清楚的了解端口LED 状态,所以此处应该将循环次数设置为7 次,即i 最大等于6。这样到下一个循环右移时就可以从最高位开始往低位移动,从而实现左右流水灯效果。
全部0条评论
快来发表一下你的评论吧 !