51单片机的跑马灯

51单片机的led部分原理图如上,由p2端口引脚控制,原理不多加赘述。

跑马灯即51单片机上的8个led灯依次亮起。

假设已掌握基础的知识,能点亮一个led灯,再使用一个延时函数即可实现跑马灯。

#include<reg52.h>

#define LED_PORT P2	//宏定义
sbit LED1=P2^0;         //定义一个引脚
typedef unsigned char ucahr;
typedef unsigned int uint;

void delay_ms(uint n)	//延时函数
{
	uint i,j;
	for(i=1;i<=n;i++)
	{
		for(j=200;j>0;j--);
	}
}

void display_pmd()		   //跑马灯函数
{
	uint i;
	for(i=0;i<=8;i++)
	{
		LED_PORT=~(0x01<<i);	   // <<即宏定义的LED_PORT二进制数依次左移,~为取反
		delay_ms(50);
	}	
}
	
void main()				   //主函数
{
	while(1)
	{
	 	display_pmd();
	}
}

其中的跑马灯函数diplay_pmd中,LED_PORT=~(0x01<<i);意为

  • 位移操作0x01 << i是位移操作。在 C 语言(这里假设是 51 单片机的 C 编程环境)中,<<是左移运算符。0x01是十六进制表示的数字,它的二进制形式为00000001。当i = 0时,0x01 << 0仍然是0x01(二进制00000001);当i = 1时,0x01 << 1就是0x02(二进制00000010);当i = 2时,0x01 << 20x04(二进制00000100),以此类推。随着i的增加,这个二进制数字中的1会逐位向左移动。
  • 取反操作~是按位取反运算符。它会将操作数的每一位进行取反。例如,对于二进制数00000001,取反后得到11111110。所以,~(0x01 << i)就是对0x01左移i位后的结果进行取反。
  • 赋值操作:整个表达式LED_PORT=~(0x01 << i);是将取反后的结果赋值给LED_PORT。假设LED_PORT是一个与硬件端口相关的定义(比如通过#define LED_PORT P2定义了一个单片机的 P2 端口),这个操作就会改变端口的输出值。

或使用左移函数_crol_()

#include<reg52.h>
#include<intrins.h>  //头文件 定义了左移函数_crol_

#define LED_PORT P2	//宏定义
sbit LED1=P2^0;         //定义一个引脚
typedef unsigned char ucahr;
typedef unsigned int uint;

void delay_ms(uint n)	//延时函数
{
	uint i,j;
	for(i=1;i<=n;i++)
	{
		for(j=200;j>0;j--);
	}
}

void display_pmd()		   //跑马灯函数
{
	uint i;
	for(i=0;i<=8;i++)
	{
		LED_PORT=_crol_(0xfe,i);	   // crol循环左移函数
		delay_ms(50);
	}	
}
	
void main()				   //主函数
{
	while(1)
	{
	 	display_pmd();
	}
}

实验视频如下:

51单片机跑马灯

### 使用C51单片机实现跑马灯功能 #### 原理概述 在嵌入式系统开发中,C51 单片机是一种经典的微控制器平台,广泛应用于基础教学和实际项目开发。跑马灯(流水灯)是一个典型的入门级实验,用于展示单片机对 GPIO 的控制能力。其实现的核心在于通过对单片机寄存器的写操作来改变外部 LED 的状态。 以下是基于 C51 单片机实现跑马灯功能的具体方法: --- #### 硬件连接 假设 8 个 LED 连接到单片机的 P1 (P1.0 至 P1.7),阳极接高电平,阴极通过限流电阻接地。当某一位设置为低电平时,对应的 LED 将被点亮;反之则熄灭[^3]。 --- #### 软件实现 以下是一段完整的 C51 单片机跑马灯代码示例: ```c #include <reg52.h> // 包含头文件,定义特殊功能寄存器 void delay(unsigned int time) { unsigned int i, j; for (i = 0; i < time; i++) // 外层循环决定延时长度 for (j = 0; j < 120; j++); // 内层循环消耗时间 } void main() { unsigned char temp = 0x01; // 初始化变量,表示第一个 LED 点亮 while (1) { // 主循环无限执行 P1 = temp; // 将当前状态赋给 P1 delay(500); // 延时函数调用,调整显示间隔 temp <<= 1; // 左移一位,使下一个 LED 点亮 if (!(temp & 0x80)) // 如果最高位未置位,则重置初始状态 temp |= 0x01; } } ``` 上述代码实现了从左至右依次点亮 LED 并返回起点的效果。其中 `delay` 函数提供了必要的视觉延迟,使得灯光移动更加明显[^4]。 --- #### 扩展功能 如果希望增加反向流动或其他动态效果,可以通过修改核心逻辑轻松完成。例如,在原有基础上加入逆序遍历部分即可形成双向运动模式: ```c while (1) { // 正向扫描 for (unsigned char i = 0; i < 8; i++) { P1 = 0xFE << i; // 动态更新掩码值 delay(500); } // 反向扫描 for (unsigned char i = 0; i < 8; i++) { P1 = ~(0xFE << i); // 对原掩码取反得到镜像序列 delay(500); } } ``` 此版本展示了正反两个方向上的连续变换过程[^5]。 --- #### 注意事项 - **初始化配置**:确保所有涉及 I/O 引脚的方向已正确设定为输出。 - **电源管理**:合理分配供电电压以保护外设免受过载损害。 - **程序优化**:适当调节延时参数平衡功耗与用户体验之间的关系。 --- ### 总结 借助简单的硬件搭建配合精心设计的算法结构,利用 C51 单片机能高效达成丰富多彩的视觉呈现目标。这对于培养初学者动手能力和逻辑思维具有重要意义[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值