流水灯效果探索与实现

2024-05-12 02:52
文章标签 实现 效果 探索 流水

本文主要是介绍流水灯效果探索与实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在嵌入式系统或微控制器项目中,LED流水灯是一种常见的实验项目,它不仅能够展示基本的GPIO(通用输入输出)控制,还能通过不同的模式增加趣味性。本文将探讨四种不同的流水灯效果,并通过代码示例展示如何实现它们。

效果1:依次亮(循环)

这种效果是最基本的流水灯效果,LED灯按照顺序依次亮起,当最后一个LED灯亮起后,又从头开始循环。这种效果可以通过一个简单的for循环实现,循环中依次设置每个LED灯为高电平(亮),然后延时一段时间,再设置为低电平(灭)。随后,下一个LED灯被点亮,如此循环。

代码实现:

#include "Config.h"
#include "STC8G_H_GPIO.h"
#include "STC8G_H_Delay.h"// 每个LED灯 所代表的引脚
#define LED1		P27
#define LED2		P26
#define LED3		P15
#define LED4		P14
#define LED5		P23
#define LED6		P22
#define LED7		P21
#define LED8		P20
#define LED_SW	P45// GPIO配置 输入/输出
void GPIO_config(void) {// 总开关 P4 端口下的5号引脚 推挽模式GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义GPIO_InitStructure.Pin  = GPIO_Pin_5;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_OUT_PP;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P4, &GPIO_InitStructure);//初始化// P1端口下的 4、5号引脚  准双向口模式GPIO_InitStructure.Pin  = GPIO_Pin_4 | GPIO_Pin_5;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P1, &GPIO_InitStructure);//初始化// P2端口下的 0 到 7 号引脚  准双向口模式GPIO_InitStructure.Pin  = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P2, &GPIO_InitStructure);//初始化
}int main() {int i; // 定义for循环初始化下标变量// 1. 配置8个灯和总开关SW的引脚工作模式GPIO_config();// 2. 开启总中断EA = 1;// 4. 开启总开关LED_SW = 0;// 5. 开启流水灯while(1) {// 依次亮for(i = 0; i <= 8; i++) {// i:1,2,3,4,5,6,7,8LED1 = i == 0 ? 0 : 1;   // 第一个灯亮,其他灯不亮LED2 = i == 1 ? 0 : 1;	 // 第二个灯亮,其他灯不亮LED3 = i == 2 ? 0 : 1;	 // 以此类推LED4 = i == 3 ? 0 : 1;LED5 = i == 4 ? 0 : 1;LED6 = i == 5 ? 0 : 1;LED7 = i == 6 ? 0 : 1;LED8 = i == 7 ? 0 : 1;delay_ms(100);    // 延迟100ms}}}
效果2:依次亮(顺序+逆序)

在效果1的基础上,这种效果增加了逆序循环的部分。即当LED灯按照顺序依次亮起并熄灭后,会按照逆序再次亮起并熄灭。实现这一效果需要在原有的for循环基础上增加一个逆序的循环。

代码实现:

#define LED3		P15
#define LED4		P14
#define LED5		P23
#define LED6		P22
#define LED7		P21
#define LED8		P20
#define LED_SW	P45// GPIO配置 输入/输出
void GPIO_config(void) {// 总开关 P4 端口下的5号引脚 推挽模式GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义GPIO_InitStructure.Pin  = GPIO_Pin_5;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_OUT_PP;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P4, &GPIO_InitStructure);//初始化// P1端口下的 4、5号引脚  准双向口模式GPIO_InitStructure.Pin  = GPIO_Pin_4 | GPIO_Pin_5;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P1, &GPIO_InitStructure);//初始化// P2端口下的 0 到 7 号引脚  准双向口模式GPIO_InitStructure.Pin  = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P2, &GPIO_InitStructure);//初始化
}int main() {int i; // 定义for循环初始化下标变量// 1. 配置8个灯和总开关SW的引脚工作模式GPIO_config();// 2. 开启总中断EA = 0;// 4. 开启总开关LED_SW = 0;// 5. 开启流水灯while(1) {// 依次亮 顺序for(i = 0; i <= 8; i++) {// i:1,2,3,4,5,6,7,8LED1 = i == 0 ? 0 : 1;   // 第一个灯亮,其他灯不亮LED2 = i == 1 ? 0 : 1;	 // 第二个灯亮,其他灯不亮LED3 = i == 2 ? 0 : 1;	 // 以此类推LED4 = i == 3 ? 0 : 1;LED5 = i == 4 ? 0 : 1;LED6 = i == 5 ? 0 : 1;LED7 = i == 6 ? 0 : 1;LED8 = i == 7 ? 0 : 1;delay_ms(100);    // 延迟100ms}// 逆序for(i = 8; i >= 0; i--) {// i:8,7,6,5,4,3,2,1LED1 = i == 0 ? 0 : 1;   // 第一个灯亮,其他灯不亮LED2 = i == 1 ? 0 : 1;	 // 第二个灯亮,其他灯不亮LED3 = i == 2 ? 0 : 1;	 // 以此类推LED4 = i == 3 ? 0 : 1;LED5 = i == 4 ? 0 : 1;LED6 = i == 5 ? 0 : 1;LED7 = i == 6 ? 0 : 1;LED8 = i == 7 ? 0 : 1;delay_ms(100);    // 延迟100ms}}}
效果3:逐渐亮

这种效果要求LED灯从第一个开始逐个亮起,直到所有LED灯都亮起,然后再逐个熄灭,直到所有LED灯都熄灭。这种效果可以通过两个嵌套的for循环实现,第一个循环控制亮起的LED灯的数量,第二个循环则用于设置对应数量的LED灯为高电平。在第一个循环结束后,再通过一个类似的循环将LED灯逐个熄灭。

代码实现:

#include "Config.h"
#include "STC8G_H_GPIO.h"
#include "STC8G_H_Delay.h"// 每个LED灯 所代表的引脚
#define LED1		P27
#define LED2		P26
#define LED3		P15
#define LED4		P14
#define LED5		P23
#define LED6		P22
#define LED7		P21
#define LED8		P20
#define LED_SW	P45// GPIO配置 输入/输出
void GPIO_config(void) {// 总开关 P4 端口下的5号引脚 推挽模式GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义GPIO_InitStructure.Pin  = GPIO_Pin_5;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_OUT_PP;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P4, &GPIO_InitStructure);//初始化// P1端口下的 4、5号引脚  准双向口模式GPIO_InitStructure.Pin  = GPIO_Pin_4 | GPIO_Pin_5;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P1, &GPIO_InitStructure);//初始化// P2端口下的 0 到 7 号引脚  准双向口模式GPIO_InitStructure.Pin  = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P2, &GPIO_InitStructure);//初始化
}int main() {int i; // 定义for循环初始化下标变量// 1. 配置8个灯和总开关SW的引脚工作模式GPIO_config();// 2. 开启总中断EA = 1;// 4. 开启总开关LED_SW = 0;// 5. 开启逐渐亮流水灯while(1) {// 逐渐亮for(i = 8; i >= 0; i--) {// 依次点亮前i个灯LED1 = i >= 1; // 如果i >= 1,则LED1亮(),否则不亮LED2 = i >= 2; // 如果i >= 2,则LED2亮,否则不亮LED3 = i >= 3; // 以此类推LED4 = i >= 4;LED5 = i >= 5;LED6 = i >= 6;LED7 = i >= 7;LED8 = i >= 8;delay_ms(100);    // 延迟100ms}// 逐渐灭for(i = 0; i <= 8; i++) {// 依次点亮前i个灯LED1 = i >= 1; // 如果i >= 1,则LED1亮,否则不亮LED2 = i >= 2; // 如果i >= 2,则LED2亮,否则不亮LED3 = i >= 3; // 以此类推LED4 = i >= 4;LED5 = i >= 5;LED6 = i >= 6;LED7 = i >= 7;LED8 = i >= 8;delay_ms(100);    // 延迟100ms}}}
效果4:奇偶亮

这种效果要求LED灯按照奇偶顺序亮起。首先,所有奇数编号的LED灯(如1、3、5、7)亮起,然后熄灭;接着,所有偶数编号的LED灯(如2、4、6、8)亮起,然后熄灭。这种效果可以通过两个独立的循环实现,一个用于控制奇数LED灯,另一个用于控制偶数LED灯。

代码实现:

#include "Config.h"
#include "STC8G_H_GPIO.h"
#include "STC8G_H_Delay.h"// 每个LED灯 所代表的引脚
#define LED1		P27
#define LED2		P26
#define LED3		P15
#define LED4		P14
#define LED5		P23
#define LED6		P22
#define LED7		P21
#define LED8		P20
#define LED_SW	P45// GPIO配置 输入/输出
void GPIO_config(void) {// 总开关 P4 端口下的5号引脚 推挽模式GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义GPIO_InitStructure.Pin  = GPIO_Pin_5;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_OUT_PP;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P4, &GPIO_InitStructure);//初始化// P1端口下的 4、5号引脚  准双向口模式GPIO_InitStructure.Pin  = GPIO_Pin_4 | GPIO_Pin_5;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P1, &GPIO_InitStructure);//初始化// P2端口下的 0 到 7 号引脚  准双向口模式GPIO_InitStructure.Pin  = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7;		//指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P2, &GPIO_InitStructure);//初始化
}int main() {int i; // 定义for循环初始化下标变量// 1. 配置8个灯和总开关SW的引脚工作模式GPIO_config();// 2. 开启总中断EA = 1;// 4. 开启总开关LED_SW = 0;// 5. 开启奇偶流水灯  while(1) {  // 奇数LED亮(1, 3, 5, 7)  for(i = 1; i <= 8; i += 2) { // 从1开始,每次增加2  LED1 = (i == 1);  LED3 = (i == 3);  LED5 = (i == 5);  LED7 = (i == 7);  LED2 = LED4 = LED6 = LED8 = 0; // 确保其他LED关闭  delay_ms(100); // 延迟100ms  }  // 偶数LED亮(2, 4, 6, 8)  for(i = 2; i <= 8; i += 2) { // 从2开始,每次增加2  LED2 = (i == 2);  LED4 = (i == 4);  LED6 = (i == 6);  LED8 = (i == 8);  LED1 = LED3 = LED5 = LED7 = 0; // 确保其他LED关闭  delay_ms(100); // 延迟100ms  }  }  
}
总结

通过以上四种流水灯效果的实现,我们可以看到微控制器在控制LED灯方面的强大能力。这些效果不仅展示了基本的GPIO控制技术,还通过不同的模式增加了项目的趣味性和实用性。在实际应用中,我们可以根据具体需求选择合适的流水灯效果,并通过调整参数和添加功能来进一步优化项目。

这篇关于流水灯效果探索与实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/981406

相关文章

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja