51单片机控制LED流水灯的常见方法

本文介绍了使用P2寄存器控制LED灯的亮灭,通过改变P2寄存器值实现流水灯效果。通过延时函数调整LED闪烁速度,以及两种方法实现LED状态的循环控制,包括位移操作和crol函数的应用。

原理型点亮

使用 P2 寄存器控制连接 LED 的端口,通过改变 P2 寄存器的值来控制不同的 LED 灯的亮灭状态。
在一个无限循环中,依次点亮 P2 寄存器的不同位,实现流水灯的效果。每次点亮一个 LED 后,调用 Delay() 函数进行一定的延时,从而控制 LED 的闪烁速度。

#include <REGX52.H>
void Delay(unsigned int time)
{
	unsigned int i, j;
	for (i = 0; i < time; i++)
	{
		for (j = 0; j < 120; j++);
	}
}
void main()
{
	while (1)
	{
		P2 = 0xFE;  // 亮第一个 LED,其他 LED 熄灭
		Delay(500);  // 延时 500ms
		P2 = 0xFD;  // 亮第二个 LED,其他 LED 熄灭
		Delay(500);  // 延时 500ms
		P2 = 0xFB;  // 亮第三个 LED,其他 LED 熄灭
		Delay(500);  // 延时 500ms
		P2 = 0xF7;  // 亮第四个 LED,其他 LED 熄灭
		Delay(500);  // 延时 500ms
		P2 = 0xEF;  // 亮第五个 LED,其他 LED 熄灭
		Delay(500);  // 延时 500ms
		P2 = 0xDF;  // 亮第六个 LED,其他 LED 熄灭
		Delay(500);  // 延时 500ms
		P2 = 0xBF;  // 亮第七个 LED,其他 LED 熄灭
		Delay(500);  // 延时 500ms
		P2 = 0x7F;  // 亮第八个 LED,其他 LED 熄灭
		Delay(500);  // 延时 500ms
	}
}

循环位移控制

特性原理:

  1. 延时函数

    • void Delay(unsigned int xms):定义了一个延时函数,参数为需要延时的毫秒数。该函数通过嵌套的三层循环实现延时,每次循环减少一毫秒。
    • 外层循环 xms-- 控制延时的总时间。
    • 中层循环 i-- 和内层循环 j-- 用于实现精确的延时。
  2. 流水灯控制逻辑

    • 使用变量 led 来表示LED的状态,初始化为 0x01,即只有LED1亮。
    • 在一个无限循环中,依次点亮不同的LED,并通过左移操作 led <<= 1 将亮灯位置移至下一个LED。
    • 每次点亮一个LED后,调用 Delay() 函数进行500ms的延时,实现流水灯的效果。
    • led 等于 0x00,即LED8亮完后回到LED1时,将 led 重置为 0x01,重新从LED1开始。

从而通过不断移位和延时的操作,实现了LED灯在P2端口上的流水灯效果。

#include <REGX52.H> 
void Delay(unsigned int xms)  // 定义延时函数,参数为需要延时的毫秒数
{
	unsigned char i, j;  // 定义循环计数变量
	for(; xms > 0; xms--)  // 循环 xms 次,每次减少 1
	{
		for(i = 2; i > 0; i--)  // 嵌套的 for 循环,用于实现延时
		{
			for(j = 239; j > 0; j--);  // 嵌套的 for 循环,用于实现延时
		}
	}
}

void main()  
{
	unsigned char led = 0x01;  // 初始化LED变量为0x01
	while(1)  
	{
		P2 = ~led;  // 将P2端口的值设置为led的按位取反,即只有LED1亮
		led <<= 1;  // 左移一位,将亮灯位置移至下一个LED
		Delay(500);  // 延时500ms
		if (led == 0x00)  // 如果led等于0x0,即LED8亮完后回到LED1
		{
			led = 0x01;  // 将led重置为0x01,重新从LED1开始
		}
	}
}

采用库函数实现流水灯的控制

特性原理

具体来说,程序中通过 crol 函数实现了循环左移操作,将一个初始值 0x01 在二进制表示下循环左移 8 次,并按照左移后的结果将 led 灯逐个点亮。然后通过延时函数 Delay 实现了每个 led 灯的点亮时间,从而形成了连续不断地循环轮流点亮的效果。

_crol_ 是 Keil C51 提供的内置函数,用于实现循环左移操作。它的语法是:

unsigned char _crol_ (unsigned char val, unsigned char shift);

其中,val 表示需要进行循环左移的值,shift 表示左移的位数。

该函数会将 val 左移 shift 位,并将最高位移至最低位,返回左移后的结果。例如,如果 val 的二进制表示为 01101001,shift 的值为 1,则左移后的结果为 11010010。

在上面的代码中,i 的初始值为 0x01,每次通过 _crol_ 函数将 i 左移一位,即实现了 i 的循环左移操作。具体来说,代码中的循环控制变量 i 从二进制的 00000001,经过 8 次循环左移操作,变成了 10000000,然后再次循环回到 00000001,实现了 led 灯的循环轮流点亮。

#include <REG52.H>
#include <intrins.h>

void Delay(unsigned int xms)  // 定义延时函数,参数为需要延时的毫秒数
{
	unsigned char i, j;  // 定义循环计数变量
	for(; xms > 0; xms--)  // 循环 xms 次,每次减少 1
	{
		for(i = 2; i > 0; i--)  // 嵌套的 for 循环,用于实现精确的延时
		{
			for(j = 239; j > 0; j--);  // 嵌套的 for 循环,用于实现精确的延时
		}
	}
}

void main()
{
    unsigned int i;
    while(1)
    {
        for(i = 0x01; i <= 0x80; i = _crol_(i, 1))  // 使用 _crol_ 函数实现循环左移操作
        {
            P2 = ~i;  // 通过取反操作将led灯的状态设置为i的状态
            Delay(500);  // 延时500ms
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值