NRF52840学习历程(十一)幻彩RGB灯之WS2812B |
您所在的位置:网站首页 › RGB3528幻彩原理图 › NRF52840学习历程(十一)幻彩RGB灯之WS2812B |
时间在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基本时钟:8M p_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; //大概812ns p_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>i)) ws2812b[(j*24)+i] = 3; // 800ns高电平 1码(他PWM高低电平是相反的) else ws2812b[(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 使用8M时钟, 因为WS2812B的速率为800Khz, 所以要分出来800K, 拿8M /10就很好的分出来800Khz模式为公用模式,这个是非常容易拿数组序列驱动,其他模式的数组不是一维数组,而是二维数组,因此非常不方便 引脚为25输出, 注意, 没有用 p_config.output_pins[0] = 25 |NRF_DRV_PWM_PIN_INVERTED; 是因为NRF_DRV_PWM_PIN_INVERTED 在停止之后是为高电平的, 所以不需要他 计数最大值为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,操作更方便哦
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |