热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

NRF52840学习历程(十一)幻彩RGB灯之WS2812B

时间在2021年2月6日,寒假放假在家好好学一学nRF52840今天还在感冒,休息一波开发板:初雪的100出头那块NRF52840EVALKIT下载工具:JINLK

时间在2021年2月6日,寒假放假在家好好学一学nRF52840

 

今天还在感冒,休息一波

 

开发板:初雪的100出头那块 NRF52840 EVAL KIT

下载工具:JINLK V11(最好是JLINK V9以上 也有人用JLINK OB也行,其他的下载器诸如STLINK,DAP不建议用)

版本号: KEIL5编程环境,CMSIS为5.3.0, NRF52840的CMSIS为8.35.0

参考资料: NRF52840-Eval-Kit-Schematic.pdf(原理图)

nRF5_SDK_17.0.2_d674dde(官方例程)

nRF5_SDK_17.0.0_offline_doc(官方文档)

nRF52840_PS_v1.1.pdf(官方数据手册)

ws2812b数据手册

 


代码太长, 先放效果图

 

 


------------------------------------------------------------------------------

------------------------------------------------------------------------------

 

已用IO

0.96OLED / 1.29彩色OLED

D0(CLK) -> 12

D1(SDA) -> 23

RES     -> 7

DC      -> 21

CS      -> 19

 

按键

KEY0 ->11

KEY1 ->24

KEY2 ->20

KEY3->17

 

LED

LED0 ->13

LED1->14

LED2->32+9=41

LED3->16

 

串口

TX ->6

RX ->8

 

ADC

光敏 -> 5

摇杆X -> 28

摇杆Y -> 29

 

IIC_0.96OLED

SDA -> 32

SCL -> 22

 

还没用到(空闲)

P0.0 1 2 3 9 10 15 26 27 30 31

P1.1 2 3 4 5 6 7 8 10 11 12 13 14 15


 

添加WS2812B 幻彩RGB

WS2812B -> 25

 


-------------------------------------------------------------------------------

------------------------------------------------------------------------------

 

先介绍下WS2812B

时序

可以看出,

1码时需要高电平时间为800ns左右

0码 需要400ns左右

 

传输流程是, 第一个灯吃掉24位数据之后,再把剩下的数据(已经少了24个数据了)原封不动的传到下一个灯

 

24位数据为 G R B 排列 ,其中B是最低8位

传输是高位先行(就是先传最高位,再传次高位)

数据手册推荐电路图

 

工作频率是 800Khz ( 就是它的周期,1.25u 要传输一Bit位,跟上面的0,1码相符合)

 

工作电压是3.3V~5.0V都行,我这边测试过3.3V是正常的, 5V更不用说了, 超过5.3V可能就烧,所以别用超过5.3V电源, 可以用5V电压,建议串一个大功率的(比如3A的)肖特基二极管,确保电压低于5V

------------------------------------------------------------------------------

------------------------------------------------------------------------------

------------------------------------------------------------------------------

 

下面直接代码

全局变量

static nrf_pwm_values_common_t ws2812b[24*64]={0,0,0}; //序列1数组

PWM初始化


void MY_PWM_INIT_04(void)
{nrfx_pwm_config_t p_config; //定义结构体p_config.base_clock = NRF_PWM_CLK_8MHz ; // PWM基本时钟:8Mp_config.count_mode = NRF_PWM_MODE_UP ; //计数模式: 向上计数p_config.irq_priority = _PRIO_APP_HIGH ; //中断优先级p_config.load_mode = NRF_PWM_LOAD_COMMON; // 加载模式: 公用模式p_config.output_pins[0] = 25; //PWM通道0的引脚输出绑定p_config.output_pins[1] = NRF_DRV_PWM_PIN_NOT_USED; p_config.output_pins[2] = NRF_DRV_PWM_PIN_NOT_USED; p_config.output_pins[3] = NRF_DRV_PWM_PIN_NOT_USED; //不使用p_config.step_mode = NRF_PWM_STEP_AUTO ;// 重复计数输出p_config.top_value = 10;//脉冲计数的顶点值 8MHz/10=800Khz // 使用 PWM控制器0, 初始化内容写入寄存器, 事件中断函数nrf_drv_pwm_init(&my_pwm0,&p_config,NULL);// ws2812b = 8; //大概250ns
// ws2812b = 3; //大概812nsp_sequence0.end_delay = 0 ; p_sequence0.length = NRF_PWM_VALUES_LENGTH(ws2812b) ; // 序列长度p_sequence0.repeats = 0 ; p_sequence0.values.p_common = ws2812b;
// p_sequence0.values.p_common = &ws2812b;// // 单序列输出PWM 使用PWM0 ,把序列1内容写入结构体,播放次数,播完继续播
// nrf_drv_pwm_simple_playback(&my_pwm0, &p_sequence0,1,NRF_DRV_PWM_FLAG_LOOP);}

 

主函数


// MY_PWM_INIT();
// MY_PWM_INIT_02();
// MY_PWM_INIT_03();nrf_gpio_cfg_output(25);nrf_gpio_pin_clear(25);MY_PWM_INIT_04();uint32_t ws2812_buf[64]=
//{0};
// B G R
{0xff,0,0xff00,0,0xff0000,0,0,0xffffff,
0,0xffffff,0,0,0,0,0,0,
0,0,0,0xff33,0xff00,0,0,0,
0,0,0,0,0,0,0xffffff,0,
0,0xff0000,0,0,0,0,0,0,
0,0,0,0,0xffffff,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 };int i = 0,j=0;for(j =0; j<64; j++){for(i =0; i<24 ; i++){if(ws2812_buf[j] & (0x800000>>i))ws2812b[(j*24)+i] = 3; // 800ns高电平 1码(他PWM高低电平是相反的)elsews2812b[(j*24)+i] = 7; // 400ns高电平 0码}}// 就播放一次, 播放完收工nrf_drv_pwm_simple_playback(&my_pwm0, &p_sequence0,1,NRF_DRV_PWM_FLAG_STOP);

其他都没怎么动了

------------------------------------------------------------------------------

------------------------------------------------------------------------------

代码讲解

定义RAM数组, 为64个WS2812灯, 又每个灯需要24位数据, 所以有24*64个

后面的{0,0,0}是让数据上电时为0

 


  1. 使用8M时钟, 因为WS2812B的速率为800Khz, 所以要分出来800K, 拿8M /10就很好的分出来800Khz
  2. 模式为公用模式,这个是非常容易拿数组序列驱动,其他模式的数组不是一维数组,而是二维数组,因此非常不方便

 


  1. 引脚为25输出, 注意, 没有用

p_config.output_pins[0] = 25 |NRF_DRV_PWM_PIN_INVERTED;

是因为NRF_DRV_PWM_PIN_INVERTED 在停止之后是为高电平的, 所以不需要他


  1. 计数最大值为10, 这样就可以分出来800K了

 

这三个注释是我抓取数据用的, 只是测试用, 后面修改了具体数值了

其中

ws2812b = 8 他反而输出了大概250ns

ws2812b = 3; //大概812ns

可以得出, PWM输出的极性跟我们日常的是相反的

随便定义了64个灯的颜色


  • 因为WS2812是高位先行的,所以用先传高位, 那么我就用 RGB的数据 按位与 (2^24 >> i)即可
  • 当数据为1时,那么就是1码,输出800ns高电平即可,注意是 纳秒(ns)


  • 同理 数据为0时, 输出0码, 为400ns高电平, 之前是8的,但输出不稳定,改为7变为400ns就稳定了

 

之后就是播放序列即可, 注意是播放1次, 播放完毕之后就停止了

 

------------------------------------------------------------------------------

------------------------------------------------------------------------------

 

 

 

链接:https://pan.baidu.com/s/1aFWzBB1Yp3rxoYn57v7QVg

提取码:chpo

复制这段内容后打开百度网盘手机App,操作更方便哦

 


推荐阅读
  • 解决针织难题:R语言编程技巧与常见错误分析 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 从0到1搭建大数据平台
    从0到1搭建大数据平台 ... [详细]
  • MySQL下载与安装指南:详细记录常见问题及解决方法
    MySQL下载与安装指南:详细记录常见问题及解决方法 ... [详细]
  • 百度飞桨图像分割课程笔记14:全景分割技术详解——PanopticDeepLab(CVPR 2019)
    Panoptic-DeepLab 是一种自底向上的全景分割方法,无需预先进行目标检测。该模型在 CVPR 2019 上提出,以其简洁、强大且快速的特点成为全景分割任务的基准。通过高效地结合实例分割和语义分割,Panoptic-DeepLab 能够准确地识别和区分图像中的每个对象和背景区域,为复杂的场景提供全面的分割结果。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
  • 在Linux系统中,网络配置是至关重要的任务之一。本文详细解析了Firewalld和Netfilter机制,并探讨了iptables的应用。通过使用`ip addr show`命令来查看网卡IP地址(需要安装`iproute`包),当网卡未分配IP地址或处于关闭状态时,可以通过`ip link set`命令进行配置和激活。此外,文章还介绍了如何利用Firewalld和iptables实现网络流量控制和安全策略管理,为系统管理员提供了实用的操作指南。 ... [详细]
  • 在安装 iOS 开发所需的 CocoaPods 时,用户可能会遇到多种问题。其中一个常见问题是,在执行 `pod setup` 命令后,系统无法连接到 GitHub 以更新 CocoaPods/Specs 仓库。这可能是由于网络连接不稳定、GitHub 服务器暂时不可用或本地配置错误等原因导致。为解决此问题,建议检查网络连接、确保 GitHub API 限制未被触发,并验证本地配置文件是否正确。 ... [详细]
  • 今天我开始学习Flutter,并在Android Studio 3.5.3中创建了一个新的Flutter项目。然而,在首次尝试运行时遇到了问题,Gradle任务 `assembleDebug` 执行失败,退出状态码为1。经过初步排查,发现可能是由于依赖项配置不当或Gradle版本不兼容导致的。为了解决这个问题,我计划检查项目的 `build.gradle` 文件,确保所有依赖项和插件版本都符合要求,并尝试更新Gradle版本。此外,还将验证环境变量配置是否正确,以确保开发环境的稳定性。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 掌握这些技巧,轻松获取超过90%的资源信息
    在数字时代,高效获取所需资源是每个人必备的技能。本文将分享一系列实用技巧,帮助读者轻松获取超过90%的网络资源信息,无论是学术资料、技术文档还是最新资讯,都能迅速找到。通过优化搜索引擎使用、利用专业数据库和社群资源等方法,读者将能够在信息海洋中游刃有余。 ... [详细]
  • 【图像分类实战】利用DenseNet在PyTorch中实现秃头识别
    本文详细介绍了如何使用DenseNet模型在PyTorch框架下实现秃头识别。首先,文章概述了项目所需的库和全局参数设置。接着,对图像进行预处理并读取数据集。随后,构建并配置DenseNet模型,设置训练和验证流程。最后,通过测试阶段验证模型性能,并提供了完整的代码实现。本文不仅涵盖了技术细节,还提供了实用的操作指南,适合初学者和有经验的研究人员参考。 ... [详细]
  • JavaScript XML操作实用工具类:XmlUtilsJS技巧与应用 ... [详细]
  • Android Studio 安装指南:详细步骤与常见问题解答
    Android Studio 安装指南:详细步骤与常见问题解答 ... [详细]
author-avatar
峰吹云飞_974
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有