打印
[单片机芯片]

如何配置CH32V103的TIM PWM DMA 模式驱动WS2812B

[复制链接]
1061|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lilijin1995|  楼主 | 2022-3-22 14:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下代码是我们在STM32F103下驱动的代码,定时器是72M,分频系数为0,周期系数为89;代码如下
/**
  ******************************************************************************
  * [url=home.php?mod=space&uid=288409]@file[/url]           : ws281x.c
  * [url=home.php?mod=space&uid=247401]@brief[/url]          : ws281x LED Driver
  ******************************************************************************
  * @attention
  *
  * <h2><center>© Copyright (c) 2020 SYEtronix Inc.
  * 未经作者许可,不得用于其它任何用途
  * 创建日期:2020/2/18
  * 版本:V1.0
  * 版权所有,盗版必究。
  * Copyright(C) 广州市胜意游乐设备有限公司 SYEtronix Inc.
  * All rights reserved               
  *
  ******************************************************************************
  */

#include "ws281x.h"
#include "IR_Switch.h"
#include <string.h>
#include "tim.h"
#include "delay.h"

extern TIM_HandleTypeDef htim3;








uint16_t send_Buf[NUM];

#define PROCESS_DELAY 5
#define SECTION_DELAY 100

void WS_Load(void) { HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, (uint32_t*)send_Buf, NUM); }
void WS_CloseAll(void)
{
        uint16_t i;
        for (i = 0; i < PIXEL_NUM * 24; i++)
                send_Buf[i] = WS0;    // 写入逻辑0的占空比
        for (i = PIXEL_NUM * 24; i < NUM; i++)
                send_Buf[i] = 0;    // 占空比比为0,全为低电平
        WS_Load();
}

void WS_WriteAll_RGB(uint8_t n_R, uint8_t n_G, uint8_t n_B)
{
        uint16_t i, j;
        uint8_t dat[24];
        // 将RGB数据进行转换
        for (i = 0; i < 8; i++)
        {
                dat[i] = ((n_G & 0x80) ? WS1 : WS0);
                n_G <<= 1;
        }
        for (i = 0; i < 8; i++)
        {
                dat[i + 8] = ((n_R & 0x80) ? WS1 : WS0);
                n_R <<= 1;
        }
        for (i = 0; i < 8; i++)
        {
                dat[i + 16] = ((n_B & 0x80) ? WS1 : WS0);
                n_B <<= 1;
        }
        for (i = 0; i < PIXEL_NUM; i++)
        {
                for (j = 0; j < 24; j++)
                {
                        send_Buf[i * 24 + j] = dat[j];
                }
        }
        for (i = PIXEL_NUM * 24; i < NUM; i++)
                send_Buf[i] = 0;    // 占空比比为0,全为低电平
        WS_Load();
}

uint32_t WS281x_Color(uint8_t red, uint8_t green, uint8_t blue) { return green << 16 | red << 8 | blue; }

void WS281x_SetPixelColor(uint16_t n, uint32_t GRBColor)
{
        uint8_t i;
        if (n < PIXEL_NUM)
        {
                for (i = 0; i < 24; ++i)
                        send_Buf[24 * n + i] = (((GRBColor << i) & 0X800000) ? WS1 : WS0);
        }
}

void WS281x_SetPixelRGB(uint16_t n, uint8_t red, uint8_t green, uint8_t blue)
{
        uint8_t i;

        if (n < PIXEL_NUM)
        {
                for (i = 0; i < 24; ++i)
                        send_Buf[24 * n + i] = (((WS281x_Color(red, green, blue) << i) & 0X800000) ? WS1 : WS0);
        }
}

uint32_t Wheel(uint8_t WheelPos)
{
        WheelPos = 255 - WheelPos;
        if (WheelPos < 85)
        {
                return WS281x_Color(255 - WheelPos * 3, 0, WheelPos * 3);
        }
        if (WheelPos < 170)
        {
                WheelPos -= 85;
                return WS281x_Color(0, WheelPos * 3, 255 - WheelPos * 3);
        }
        WheelPos -= 170;
        return WS281x_Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void rainbow(uint8_t wait)
{
        uint32_t timestamp = HAL_GetTick();
        uint16_t i;
        static uint8_t j;
        static uint32_t next_time = 0;

        uint32_t flag = 0;
        if (next_time < wait)
        {
                if ((uint64_t)timestamp + wait - next_time > 0)
                        flag = 1;
        }
        else if (timestamp > next_time)
        {
                flag = 1;
        }
        if (flag)    // && (timestamp - next_time < wait*5))
        {
                j++;
                next_time = timestamp + wait;
                for (i = 0; i < PIXEL_NUM; i++)
                {
                        WS281x_SetPixelColor(i, Wheel((i + j) & 255));
                }
        }
        WS_Load();
}

void rainbowCycle(uint8_t wait)
{
        uint32_t timestamp = HAL_GetTick();
        uint16_t i;
        static uint8_t j;
        static uint32_t next_time = 0;

        static uint8_t loop = 0;
        if (loop == 0)
                next_time = timestamp;
        loop = 1;    //首次调用初始化

        if ((timestamp > next_time))    // && (timestamp - next_time < wait*5))
        {
                j++;
                next_time = timestamp + wait;
                for (i = 0; i < PIXEL_NUM; i++)
                {
                        WS281x_SetPixelColor(i, Wheel(((i * 256 / (PIXEL_NUM)) + j) & 255));
                }
        }
       
        WS_Load();
}












#ifndef _WS281X_H
#define _WS281X_H

#include "sys.h"







#define PIXEL_NUM                18
#define NUM                                (24*PIXEL_NUM + 300)        // Reset 280us / 1.25us = 224
#define WS1                                61
#define WS0                                28

extern uint16_t send_Buf[NUM];

void WS_Load(void);
void WS_WriteAll_RGB(uint8_t n_R, uint8_t n_G, uint8_t n_B);
void WS_CloseAll(void);

uint32_t WS281x_Color(uint8_t red, uint8_t green, uint8_t blue);
void WS281x_SetPixelColor(uint16_t n, uint32_t GRBColor);
void WS281x_SetPixelRGB(uint16_t n ,uint8_t red, uint8_t green, uint8_t blue);

uint32_t Wheel(uint8_t WheelPos);
void rainbow(uint8_t wait);
void rainbowCycle(uint8_t wait);



#endif



想请教大佬如何移植到ch32v103

59、TIM-DMA.rar

476.54 KB

使用特权

评论回复
沙发
WCHTech2| | 2022-3-22 15:07 | 只看该作者
您好,下面链接为F103到V103的移植说明,可参考一下:
https://bbs.21ic.com/icview-3129028-1-1.html

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

162

帖子

7

粉丝