1234下一页
返回列表 发新帖我要提问本帖赏金: 20.00元(功能说明)

[蓝牙芯片] 【WS2812驱动ch582版】基于CH582使用IO模拟时序驱动WS2812

[复制链接]
7805|69
 楼主| lilijin1995 发表于 2022-9-7 11:48 | 显示全部楼层 |阅读模式
本帖最后由 lilijin1995 于 2022-9-17 17:54 编辑

#申请原创#  @21小跑堂
---------------------
【WS2812驱动ch582板】基于CH582使用IO模拟时序驱动WS2812,实现红绿蓝切换

1.背景

选择IO口驱动WS2812实属无奈,事情是这样的,本来想使用TIM PWM+DMA的方式,但是画板子的时候选择了CH582的第14pin,即PB7 PWM9模式,按理说PWM模式没有DMA问题也不大嘛,但是事情不是这样的,因为这个PWM模式,他的周期只能选择如下几种;

  1. typedef enum
  2. {
  3.      PWMX_Cycle_256 = 0, // 256 个PWMX周期
  4.      PWMX_Cycle_255,     // 255 个PWMX周期
  5.      PWMX_Cycle_128,     // 128 个PWMX周期
  6.      PWMX_Cycle_127,     // 127 个PWMX周期
  7.      PWMX_Cycle_64,      // 64 个PWMX周期
  8.      PWMX_Cycle_63,      // 63 个PWMX周期
  9.      PWMX_Cycle_32,      // 32 个PWMX周期
  10.      PWMX_Cycle_31,      // 31 个PWMX周期
  11. } PWMX_CycleTypeDef;



并且我们的主频是60M,选择分频系数为1不分频,最后算出来1码没有达到800K,尝试了好几种配置,能点亮红色,绿色,蓝色不亮;

2. WS2812B驱动原理

通过阅读规格书,如下图所示,可以知道WS2812B的数据刷新率为800K,

image-20220907112750039.png

再有时序定义如下:0码由T0H和T0L组成,1码也差不多,RESET码是断帧码,断帧就是第几个灯珠停止,点亮几颗灯的意思;

image-20220907113106546.png

最后是数据结构,如下,一个灯珠的数据由24bit的GRB组成,N个24bit的GRB点亮N个灯珠,最后Reset断帧,其中1个bit如果是二进制的1,那么时序对应的是1码,反之是0码;

image-20220907113435604.png

3. 代码实现:

这里我们直接上代码,其中Set0Code和Set1Code是基于1码和0码的时序用示波器调出来的,这里就介绍方法不介绍过程了;方法是直接调用SendOneFrame(0xFF);全发1码驱动1码,确定0码是发SendOneFrame(0x00),看高低电平即可;

  1. /********************************** (C) COPYRIGHT *******************************
  2.   * File Name          : Main.c
  3.   * Author             : Li
  4.   * Version            : V1.0
  5.   * Date               : 2022/09/07
  6.   * Description         : IO驱动WS281X彩灯功能演示
  7.   * Copyright (c) 2022 Guangzhou Liandun Electronic Technology Co., LTD.
  8.   * SPDX-License-Identifier: Apache-2.0
  9.   *******************************************************************************/

  10. #include "CH58x_common.h"

  11. #define SNUM       1//灯珠数量

  12. //缓存区
  13. unsigned char buf[SNUM][3]={
  14. 0
  15. };
  16. //发0码
  17. void Set0Code(void) {
  18.      GPIOB_SetBits(GPIO_Pin_7);
  19.      __nop();
  20.      __nop();
  21.      GPIOB_ResetBits(GPIO_Pin_7);
  22.      //       NOP();
  23. }
  24. //发1码
  25. void Set1Code(void) {
  26.      GPIOB_SetBits(GPIO_Pin_7);
  27.      __nop();
  28.      __nop();
  29.      __nop();
  30.      __nop();
  31.      __nop();
  32.      __nop();
  33.      __nop();
  34.      __nop();
  35.      GPIOB_ResetBits(GPIO_Pin_7);
  36. }
  37. //发一个像素
  38. void SendOnePix(unsigned char *ptr) {
  39.      unsigned char i, j;
  40.      unsigned char temp;

  41.      for (j = 0; j < 3; j++) {
  42.          temp = ptr[j];
  43.          for (i = 0; i < 8; i++) {
  44.              if (temp & 0x80)        //从高位开始发送
  45.                      {
  46.                  Set1Code();
  47.              } else                //发送“0”码
  48.              {
  49.                  Set0Code();
  50.              }
  51.              temp = (temp << 1);      //左移位
  52.          }
  53.      }
  54. }
  55. //发一帧数据
  56. void SendOneFrame(unsigned char *ptr) {
  57.      uint16_t k;

  58.      //  PWM_RGB=0;//发送帧复位信号
  59.      //  DelayMs(1);

  60.      for (k = 0; k < SNUM; k++)              //发送一帧数据,SNUM是板子LED的个数
  61.              {
  62.          SendOnePix(&ptr[(3 * k)]);
  63.      }

  64.      GPIOB_ResetBits(GPIO_Pin_7);              //发送帧复位信号

  65. }

  66. /*********************************************************************
  67.   * @fn      main
  68.   *
  69.   * [url=home.php?mod=space&uid=247401]@brief[/url]   主函数
  70.   *
  71.   * [url=home.php?mod=space&uid=266161]@return[/url]  none
  72.   */
  73. int main() {
  74.      SetSysClock(CLK_SOURCE_PLL_60MHz);

  75.      /* 配置GPIO */
  76.      GPIOB_ModeCfg(GPIO_Pin_7, GPIO_ModeOut_PP_20mA);  // PB7 - PWM9


  77.      while(1)
  78.      {
  79.          //Red
  80.          buf[0][0]=0xFF;
  81.          buf[0][1]=0x00;
  82.          buf[0][2]=0x00;
  83.          SendOneFrame(buf);
  84.          DelayMs(1000);
  85.          //Green
  86.          buf[0][0]=0x00;
  87.          buf[0][1]=0xFF;
  88.          buf[0][2]=0x00;
  89.          SendOneFrame(buf);
  90.          DelayMs(1000);
  91.          //Blue
  92.          buf[0][0]=0x00;
  93.          buf[0][1]=0x00;
  94.          buf[0][2]=0xFF;
  95.          SendOneFrame(buf);
  96.          DelayMs(1000);
  97.      }
  98. }

4.下载验证:

可以看到RGB大约1ms切换;


附件是源码


EXAM.rar

309.39 KB, 下载次数: 15

打赏榜单

21小跑堂 打赏了 20.00 元 2022-09-08
理由:恭喜通过原创文章审核!请多多加油哦!

评论

硬件随意,软件哭泣,虽说你错过了硬件驱动,但是软件模拟却可以任意移植,也是一个不错的选择哦  发表于 2022-9-8 16:43
kiwis66 发表于 2022-9-12 10:14 | 显示全部楼层
硬件随意,软件哭泣
这是神总结啊
guijial511 发表于 2022-9-12 14:14 来自手机 | 显示全部楼层
哈哈,总结到位。
abotomson 发表于 2022-10-5 16:37 | 显示全部楼层
这个真的可以吗              
dzfansman 发表于 2022-10-5 16:58 | 显示全部楼层
怎么操作WS2812B彩灯模块  
wengh2016 发表于 2022-10-5 17:28 | 显示全部楼层
ws2812和ws2812b能混用吗  
htmlme 发表于 2022-10-5 17:56 | 显示全部楼层
CH582能不能使用定时器实现延时呢
typeof 发表于 2022-10-5 18:31 | 显示全部楼层
延时的代码是怎么调整的      
iamaiqiyi 发表于 2022-10-5 19:21 | 显示全部楼层
之前使用stm32模拟过,不是很稳定,数据显示有问题
alvpeg 发表于 2022-10-5 20:12 | 显示全部楼层
看的出来WS2812对时序还是要求比较严格的  
 楼主| lilijin1995 发表于 2022-10-7 09:44 | 显示全部楼层

我是蓝牙模式指示,只试过1颗灯珠
 楼主| lilijin1995 发表于 2022-10-7 09:45 | 显示全部楼层
dzfansman 发表于 2022-10-5 16:58
怎么操作WS2812B彩灯模块

IO模拟2812时序
 楼主| lilijin1995 发表于 2022-10-7 09:46 | 显示全部楼层
wengh2016 发表于 2022-10-5 17:28
ws2812和ws2812b能混用吗

可以先看一下规格书中的时序,有些不一样,大部分一样
 楼主| lilijin1995 发表于 2022-10-7 09:47 | 显示全部楼层
htmlme 发表于 2022-10-5 17:56
CH582能不能使用定时器实现延时呢

定时器可以直接PWM控制,有DMA会更好
 楼主| lilijin1995 发表于 2022-10-7 09:48 | 显示全部楼层
htmlme 发表于 2022-10-5 17:56
CH582能不能使用定时器实现延时呢

看错了,可以的,控制寄存器实现即可
 楼主| lilijin1995 发表于 2022-10-7 09:49 | 显示全部楼层
typeof 发表于 2022-10-5 18:31
延时的代码是怎么调整的

IO口调整时序,我是加NOP
 楼主| lilijin1995 发表于 2022-10-7 09:51 | 显示全部楼层
iamaiqiyi 发表于 2022-10-5 19:21
之前使用stm32模拟过,不是很稳定,数据显示有问题

我在HK32F030M试过也是不稳定,在辉芒微内存较低的型号也会,一般1K以上的SRAM会好很多,我驱动灯带可以,但饱和度不够
 楼主| lilijin1995 发表于 2022-10-7 09:52 | 显示全部楼层
alvpeg 发表于 2022-10-5 20:12
看的出来WS2812对时序还是要求比较严格的

是啊,最好频率高点MCU
chenqianqian 发表于 2022-10-8 20:53 来自手机 | 显示全部楼层
用PWM效率最高,最方便。
tpgf 发表于 2022-10-9 12:01 | 显示全部楼层
一般情况下可以使用什么驱动WS2812呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

56

主题

165

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部