当前位置: 首页 > news >正文

开源一个可以调RGB三色的小灯棒子

 开源一个可以调灯的小灯棒子。

主控用的STC8G1K08A-SOP8,RGB三色灯是WS2812B。

开源到立创开源广场了,可以直接进入下方链接,那边可以直接查看原理图和PCB。

一个可调RGB三色的小灯棒子 - 立创开源硬件平台一个可调RGB三色的小灯棒子https://oshwhub.com/zctnb/diao-guang-deng

通过观察板子下面三个灯来调整板子上两排的灯的颜色,下面三个灯分别表示RGB,并且也只亮对应的颜色,比如说最左边的灯只有红色的亮度,蓝和绿的亮度都是0。

这边可以稍微讲解一下WS2812B是通过调整RGB三色的亮度来完成任意颜色的表示的。

关于WS2812B如何控制的可以看看我之前的文章,不过里面的代码恐怕没法直接使用,因为我最近发现了时钟频率好像当时没调对,不过理论部分都是正确的,严格说起来代码也是没问题的,只不过烧录程序的时候频率要选成11.0592。

今天我们不点LED,我们点WS2812B_为什么用点灯blinker调ws2812第一灯闪-CSDN博客文章浏览阅读1.1k次,点赞10次,收藏22次。这也难不倒我,经过我一顿操作和计算,STC8G1K08A的主频为24MHz,一个_nop_()大概耗时是63+ns,其实我计算的结果应该是44ns,因为1/24 000 000 约等于是40ns,但是我拿着40一个_nop_()的结果去写代码,发现好像不对劲,最后定位在了一个_nop_()大概耗时是60+ns。1码和0码差不多,高低电平是顺序一样,都是先高电平后低电平,不一样的是持续时间,持续时间其实也差不多,就是高低电平的时间反过来,所以我们1码的高电平时间定为0.6us,低电平时间定为0.3us。_为什么用点灯blinker调ws2812第一灯闪 https://blog.csdn.net/m0_63235356/article/details/144155464?spm=1001.2014.3001.5501

一共有三个按钮,从左到右按照顺序,我姑且叫做A、B、C。

当按下A之后会切换模式,模式一共是五种,按照切换顺序是灯全灭(初始模式),调节红灯,调节绿灯,调节蓝灯,灭调节灯。

调节红灯的时候上面两排主灯亮,下面三个灯只亮最左边一个灯,并且只亮红光,这时候按下B可以增加红光的值,按下C可以减少红光的值,如果是双击的话,那么就是增加(减少)10,满数值是255。调节的结果会实时反应在两排主灯上。

调节绿灯蓝灯也是一样的道理,灭调节灯模式就是三个调节灯灭,两排主灯亮,此时按下B和C没有效果。

原理图画了两版,咱就聊聊第二版吧,因为第一版确实没设计好,三个按钮光加上拉电阻没加电容,然后烧录留的接触点第一版原理图里也没有(我记得放了,但是没有,不过PCB是没问题的)

主控用的STC8G1K08A-SOP8,外围电路仅需在VCC和GND之间接俩电容就行。

按键我接了P32、P33、P55,分别是外部中断0、1、3。

P54接WS2812B,并且是可以串联多个的。

充电管理芯片用的TP4056,买的国产高端平替,一个一毛多,一下子屯多了,大家可以自行更换成自己手上有的芯片。

Type-C只是用来充电的,所以也是可以自己换成别的型号的。

代码如下,注释都已经写好了,也不难,应该是可以看的懂的。

#include "STC8G_H_Delay.h"
#include "STC8G_H_Exti.h"
#include "STC8G_H_GPIO.h"
#include "STC8G_H_NVIC.h"
#include "STC8G_H_Timer.h"
// RGB灯和按键的引脚
#define WS2812B_IN  P54
#define KEY1_GPIO   P32
#define KEY2_GPIO   P33
#define KEY3_GPIO   P55// G、R、B
uint16 color[3] = {10, 10, 10};
uint8 timer0_open = 0, timer0_over = 0;     // 定时器0开启 结束标志
uint8 timer1_open = 0, timer1_over = 0;     // 定时器1开始 结束标志
uint8 key1_down = 0, key2_down = 0, key3_down = 0;      // 三个按键是否按下的标志
uint8 key1_count = 0, key2_count = 0, key3_count = 0;   // 三个按键按下次数
// 0全关,1调R,2调G,3调B,4关调色,
uint8 mode = 0;void Timer0_ISR_Handler (void) interrupt TMR0_VECTOR{static uint8 i = 0;if(++i >= 5){           // 定时10秒消除抖动ET0 = 0;            // 关闭定时器0timer0_open = 0;    // 修改标志timer0_over = 1;i = 0;}
}void Timer1_ISR_Handler (void) interrupt TMR1_VECTOR{static count = 0;if(++count >= 250){     // 定时500ms来记录期间按下按键的次数ET1 = 0;            // 关闭定时器1timer1_open = 0;    // 修改标志timer1_over = 1;count = 0;}
}// 复位
void WS2812B_SendReset(void) {unsigned char data i, j;WS2812B_IN = 0;  // 拉低80usi = 2;j = 219;do {while (--j);} while (--i);
}// 发送1码
void WS2812B_SendOne(void) {WS2812B_IN = 1;  // 拉高延时0.6us_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();WS2812B_IN = 0;  // 拉低延时0.3us_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}// 发送0码
void WS2812B_SendZero(void) {WS2812B_IN = 1;  // 拉高延时0.3us_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();WS2812B_IN = 0;  // 拉低延时0.6us_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}// 发送自定义RGB颜色
void WS2812B_SendColor(void) {uint8 i, j;for (i = 0; i < 3; ++i) {for (j = 0; j < 8; ++j) {   if (color[i] & (0x80 >> j))     // 高位在前WS2812B_SendOne();elseWS2812B_SendZero();}}
}// 初始化GPIO
void GPIO_Init(void) {P5_MODE_OUT_PP(GPIO_Pin_4);P3_MODE_IN_HIZ(GPIO_Pin_3);P3_PULL_UP_ENABLE(GPIO_Pin_3);P3_MODE_IN_HIZ(GPIO_Pin_2);P3_PULL_UP_ENABLE(GPIO_Pin_2);P5_MODE_IN_HIZ(GPIO_Pin_5);P5_PULL_UP_ENABLE(GPIO_Pin_5);
}// 中断初始化
void Exti_Init(void) {EXTI_InitTypeDef Exti_InitStructure;Exti_InitStructure.EXTI_Mode = EXT_MODE_Fall;Ext_Inilize(EXT_INT0, &Exti_InitStructure);NVIC_INT0_Init(ENABLE, Priority_1);Exti_InitStructure.EXTI_Mode = EXT_MODE_Fall;Ext_Inilize(EXT_INT1, &Exti_InitStructure);NVIC_INT1_Init(ENABLE, Priority_1);Exti_InitStructure.EXTI_Mode = EXT_MODE_Fall;Ext_Inilize(EXT_INT3, &Exti_InitStructure);NVIC_INT3_Init(ENABLE, Priority_1);
}// 定时器初始化
void Timer_Init(void){TIM_InitTypeDef initer;initer.TIM_Mode = TIM_16BitAutoReload;          // 模式0,16位自动重装载寄存器.initer.TIM_ClkOut = DISABLE;                    // 失能可编程时钟输出initer.TIM_ClkSource = TIM_CLOCK_1T;            // 1T工作模式initer.TIM_Value = 17536;                       // 延时2ms                       initer.TIM_Run = ENABLE;                        Timer_Inilize(Timer0, &initer);Timer_Inilize(Timer1, &initer);NVIC_Timer0_Init(DISABLE, Priority_2);NVIC_Timer1_Init(DISABLE, Priority_2);
}// 当进入外部中断之后的处理逻辑
void when_key_down(uint8 what_key){WakeUpSource = 0;if(timer0_open == 0){   // 如果定时器0没有打开,那么进入处理逻辑;否则判定为抖动,不予理会timer0_open = 1;    ET0 = 1;            // 打开定时器0// 记录按下的按键if(what_key == 1)   key1_down = 1;else if(what_key == 2)   key2_down = 1;else if(what_key == 3)   key3_down = 1;if(timer1_open == 0){   // 如果定时器1没打开,那么打开timer1_open = 1;ET1 = 1;}}
}// 切换模式
void change_mode(void){uint16 i = 0;uint8 j = 0;if(mode == 0){          // 所有灯灭 给所有灯发送0x00 0x00 0x00WS2812B_SendReset();for(i = 0; i < 360; ++i) WS2812B_SendZero();}else if(mode == 1){    // 调R,前三个灯只亮第一个且只亮红灯WS2812B_SendReset();for(j = 0; j < 8; ++j)  WS2812B_SendZero();for(j = 0; j < 8; ++j){if (color[1] & (0x80 >> j)) WS2812B_SendOne();else    WS2812B_SendZero();}for(j = 0; j < 56; ++j) WS2812B_SendZero();}else if(mode == 2){    // 调G,前三个灯只亮第二个且只亮绿灯WS2812B_SendReset();for(j = 0; j < 24; ++j) WS2812B_SendZero();for(j = 0; j < 8; ++j){if (color[0] & (0x80 >> j)) WS2812B_SendOne();else    WS2812B_SendZero();}for(j = 0; j < 40; ++j) WS2812B_SendZero();}else if(mode == 3){    // 调B,前三个灯只亮第三个且只亮蓝灯WS2812B_SendReset();for(j = 0; j < 64; ++j) WS2812B_SendZero();for(j = 0; j < 8; ++j){if (color[2] & (0x80 >> j)) WS2812B_SendOne();else    WS2812B_SendZero();}}else if(mode == 4){    // 前三个灯全灭WS2812B_SendReset();for(i = 0; i < 72; ++i) WS2812B_SendZero();}if(mode != 0){  // 当模式不为全灭时,需要更新后面的RGB灯for(i = 0; i < 12; ++i){WS2812B_SendColor();}}
}void main(void) {EAXSFR();  // 扩展SFR(XFR)访问使能GPIO_Init();Exti_Init();Timer_Init();EA = 1;             // 开启中断while (1) {if(WakeUpSource == 1){when_key_down(1);}else if(WakeUpSource == 2){when_key_down(2);}else if(WakeUpSource == 4){when_key_down(3);}// 当定时器0结束运行if(timer0_over == 1){timer0_over = 0;// 增加按键按下次数if(key1_down == 1){key1_down = 0;if(KEY1_GPIO == 0)  key1_count++;}else if(key2_down == 1){key2_down = 0;if(KEY2_GPIO == 0)  key2_count++;}else if(key3_down == 1){key3_down = 0;if(KEY3_GPIO == 0)  key3_count++;}}// 当定时器1结束运行if(timer1_over == 1){timer1_over = 0;// 根据按键按下的次数分别对RGB的数值进行处理if(key1_count != 0){if(++mode > 4) mode = 0;}else if(key2_count == 1){if(mode == 1) color[1]++;else if(mode == 2) color[0]++;else if(mode == 3) color[2]++;}else if(key3_count == 1){if(mode == 1) color[1]--;else if(mode == 2) color[0]--;else if(mode == 3) color[2]--;}else if(key2_count >= 2){if(mode == 1) color[1] += 10;else if(mode == 2) color[0] += 10;else if(mode == 3) color[2] += 10;}else if(key3_count >= 2){if(mode == 1) color[1] -= 10;else if(mode == 2) color[0] -= 10;else if(mode == 3) color[2] -= 10;}change_mode();key1_count = key2_count = key3_count = 0;   // 清空}}
}

我用的是STC的库函数,不懂使用的小伙伴可以看看我往期的文章,有教学系列文章。

https://blog.csdn.net/m0_63235356/category_12853526.html?spm=1001.2014.3001.5482https://blog.csdn.net/m0_63235356/category_12853526.html?spm=1001.2014.3001.5482

相关文章:

开源一个可以调RGB三色的小灯棒子

开源一个可以调灯的小灯棒子。 主控用的STC8G1K08A-SOP8&#xff0c;RGB三色灯是WS2812B。 开源到立创开源广场了&#xff0c;可以直接进入下方链接&#xff0c;那边可以直接查看原理图和PCB。 一个可调RGB三色的小灯棒子 - 立创开源硬件平台一个可调RGB三色的小灯棒子https…...

在聚类算法的领域特定语言(DSL)中添加一个度量矩阵组件

以下是一个详细的步骤和示例代码&#xff0c;用于在聚类算法的领域特定语言&#xff08;DSL&#xff09;中添加一个度量矩阵组件&#xff0c;同时满足处理数据集能达到完美聚类且改进后查询次数少于改进前的要求。 整体思路 定义DSL和原聚类算法&#xff1a;首先&#xff0c;…...

【C++】list 链表的使用+模拟实现

目录 文章目录 前言 一、list的简介 二、list的使用方法 三、list的模拟实现 1.基本框架&#xff1a; 2.迭代器实现 3.常用接口实现 四、完整代码 总结 前言 本文主要介绍C【STL】容器中的 list&#xff0c;包括接口说明和模拟实现。其中讲解了迭代器功能上的分类&am…...

AI助力小微企业技术开发规范化管理 | 杂谈

AI助力小微企业技术开发规范化管理 在小型技术研发企业中&#xff0c;人员配置紧张&#xff0c;往往一名员工需要承担多项职务和任务。例如&#xff0c;后端程序开发人员可能同时要负责需求调研、数据库设计、后端设计及开发&#xff0c;甚至在某些情况下还需兼任架构师的角色。…...

Android 实现 RTMP 推流:快速集成指南

简介 在 Android 设备上实现 RTMP 推流,可以用于直播、远程监控等应用场景。本文将基于 rtmp-rtsp-stream-client-java 库,介绍如何在 Android 端快速集成 RTMP 推流,包括权限管理、相机预览、推流控制等关键步骤。 步骤 1. 配置 Maven 仓库 在 settings.gradle.kts 中添…...

pipeline 使用git parameter插件实现动态选择分支构造

效果&#xff0c;&#xff0c;点击build with Parameters 就会出现右边的当前仓库的所有的分支&#xff0c;默认最多显示5个&#xff0c;可以修改配置&#xff0c;修改显示的最大分支数量。如果分支太多&#xff0c;可以通过右边的过滤框输入过滤。 安装git params插件 搜索g…...

postcss.config.js 动态配置基准值

在Vue项目中引入PostCSS可以实现不同分辨率的自适应&#xff0c;通常在H5项目中使用 1. 安装插件 npm install --save-dev postcss postcss-loader autoprefixer 2. 新建postcss.config.js文件&#xff0c;添加下列配置项 module.exports {plugins: {postcss-px-to-viewpor…...

DeepSeek 冲击(含本地化部署实践)

DeepSeek无疑是春节档最火爆的话题&#xff0c;上线不足一月&#xff0c;其全球累计下载量已达4000万&#xff0c;反超ChatGPT成为全球增长最快的AI应用&#xff0c;并且完全开源。那么究竟DeepSeek有什么魔力&#xff0c;能够让大家趋之若鹜&#xff0c;他又将怎样改变世界AI格…...

eNSP下载安装(eNsp、WinPcap、Wireshark、VirtualBox下载安装)

一、下载 下载网址&#xff1a;https://cloud.grbj.cn/softlink/eNSP%20V100R003C00SPC100%20Setup.exe 备用临时网址&#xff1a;https://linshi.grbj.cn/abdpana/softlink 二、准备工作 系统要求 关闭防火墙 三、安装 3.1安装WinPcap 基本都是下一步&#xff0c;双击&…...

利用Ai对生成的测试用例进行用例评审

利用AI对生成的测试用例进行用例评审,可以从用例的完整性、有效性、一致性等多个维度展开,借助自然语言处理、机器学习等技术,提高评审效率和准确性。以下为你详细介绍具体方法: 1. 需求匹配度评审 利用自然语言处理(NLP)技术 步骤:首先将软件需求文档和生成的测试用例…...

C#上位机--跳转语句

在 C# 编程中&#xff0c;跳转语句用于改变程序的执行流程。这些语句允许程序从当前位置跳转到其他位置&#xff0c;从而实现特定的逻辑控制。本文将详细介绍 C# 中四种常见的跳转语句&#xff1a;GOTO、Break、Continue 和 Return&#xff0c;并通过具体的示例代码来展示它们的…...

`sh` 与 `bash` 的区别详解

sh 与 bash 的区别详解 1. 历史背景 sh (Bourne Shell)&#xff1a; 由 Stephen Bourne 在 1977 年开发&#xff0c;是 Unix 系统的默认 Shell。语法简洁&#xff0c;但功能有限。 bash (Bourne Again Shell)&#xff1a; 由 Brian Fox 在 1989 年开发&#xff0c;是 sh 的扩…...

*PyCharm 安装教程

PyCharm 安装教程&#xff0c;适用于 Windows、macOS 和 Linux 系统&#xff1a; 1. 下载 PyCharm 官网地址&#xff1a;https://www.jetbrains.com/pycharm/版本选择&#xff1a; Community&#xff08;社区版&#xff09;&#xff1a;免费&#xff0c;适合基础 Python 开发…...

[特殊字符] Elasticsearch 双剑合璧:HTTP API 与 Java API 实战整合指南

&#x1f680; Elasticsearch 双剑合璧&#xff1a;HTTP API 与 Java API 实战整合指南 一、HTTP API 定义与用途 Elasticsearch 的 HTTP API 是基于 RESTful 接口设计的核心交互方式&#xff0c;支持通过 URL 和 JSON 数据直接操作索引、文档、集群等资源。适用于快速调试、…...

网络和操作系统基础篇

网络和操作系统基础篇 TCP三次握手 客户端——发送带有SYN标志的数据包——服务端一次握手Client进入syn_sent状态&#xff1b;服务端——发送带有SYN/ACK标志的数据包——客户端二次握手服务端进入syn_rcvd&#xff1b;客户端——发送带有ACK标志的数据包——服务端三次握手…...

Oracle 连接报错:“ORA-12541:TNS:no listener ”,服务组件中找不到监听服务

一、 报错&#xff1a; navicat连接数据库报错&#xff1a;ORA-12541&#xff1a;TNS:no listener 二、排查问题 三、 解决问题 删除Oracle安装目录下选中的配置&#xff1a;listener.ora 及 listener*.bak相关的 cmd&#xff0c;用管理员打开 执行&#xff1a;netca 命…...

内外网文件传输 安全、可控、便捷的跨网数据传输方案

一、背景与痛点 在内外网隔离的企业网络环境中&#xff0c;员工与外部协作伙伴&#xff08;如钉钉用户&#xff09;的文件传输面临以下挑战&#xff1a; 安全性风险&#xff1a;内外网直连可能导致病毒传播、数据泄露。 操作繁琐&#xff1a;传统方式需频繁切换网络环境&…...

基于Flask的租房信息可视化系统的设计与实现

【Flask】基于Flask的租房信息可视化系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 随着互联网的快速发展&#xff0c;租房市场日益繁荣&#xff0c;信息量急剧增加&#xff…...

《Keras 2 :使用 RetinaNet 进行对象检测》:此文为AI自动翻译

《Keras 2 :使用 RetinaNet 进行对象检测》 作者:Srihari Humbarwadi 创建日期:2020/05/17 最后修改日期:2023/07/10 描述:实施 RetinaNet:用于密集对象检测的焦点损失。 (i) 此示例使用 Keras 2 在 Colab 中查看 • 介绍 目标检测是计算机中非常重要的问题 视觉。在…...

【Erdas实验教程】010:监督分类及后处理、精度评价

文章目录 一、监督分类介绍二、监督分类流程1. 定义分类模板2. 评价分类模板3. 执行监督分类4. 评价分类结果4.1 叠加显示4.2 动态窗口链接4.3 阈值处理4.4 分类精度评价5. 分类后处理5.1 集聚处理5.2 滤网分析5.3 去除分析5.4 重编码一、监督分类介绍 遥感图像计算机分类的依…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...

高效的后台管理系统——可进行二次开发

随着互联网技术的迅猛发展&#xff0c;企业的数字化管理变得愈加重要。后台管理系统作为数据存储与业务管理的核心&#xff0c;成为了现代企业不可或缺的一部分。今天我们要介绍的是一款名为 若依后台管理框架 的系统&#xff0c;它不仅支持跨平台应用&#xff0c;还能提供丰富…...