这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » AT-START-M412测评】TIM+DMA方式驱动WS2812色环

共1条 1/1 1 跳转至

AT-START-M412测评】TIM+DMA方式驱动WS2812色环

菜鸟
2025-07-02 15:27:46     打赏

TIM3+DMA方式驱动WS2812色环


WS2812介绍
WS2812智能LED通过单线NRZ(Non-Return-to-Zero)通信协议传输数据,每个LED需要接收24位(3字节)数据,分别对应G(绿色)、R(红色)、B(蓝色)三种颜色的亮度值(每种颜色8位)


2.WS2812通信时序详解

典型时序参数:逻辑"1": 高电平约800ns,低电平约450ns逻辑"0": 高电平约400ns,低电平约850ns每个bit周期固定为1.25μs (±150n)
3.通信思路
定时器+PWM实现
使用PWM占空比区分逻辑1和逻辑0设置PWM周期为1.25μs逻辑1:占空比64%(800ns高电平)逻辑0:占空比32%(400ns高电平)

4.AT32_Work_Bench工程配置
配置TIM3通道一,设置定时器周期


DMA设置


开启DMA传输中断


5.生成工程
定义WS2812.h文件
复制

#ifndef __WS2812_H
#define __WS2812_H

#include "at32m412_416.h"   // 使用AT32 MCU的硬件驱动头文件

// ====================
// 硬件相关配置定义
// ====================

/* WS2812数据位时序定义 */
#define RGB_led_bit_1       121  // 逻辑"1"的PWM比较值
#define RGB_led_bit_0       61   // 逻辑"0"的PWM比较值

/* LED灯带配置 */
#define led_data_length     24   // 每个LED需要24位数据(GRB各8位)
#define RGB_PIXEL_NUM       24   // 最大支持LED数量

// ====================
// 数据结构定义
// ====================

/**
* [url=home.php?mod=space&uid=247401]@brief[/url] WS2812数据缓冲区的联合体定义
*
* 使用二维数组存储所有LED的24位数据:
* - 第一维: LED索引(0~RGB_PIXEL_NUM-1)
* - 第二维: 24位数据(8位G + 8位R + 8位B)
*/
typedef union _rgbPixelBuffer {
    uint16_t All_Buffer[RGB_PIXEL_NUM][led_data_length];
} RGB_PixelBuffer, *PRGB_PixelBuffer;

// ====================
// 全局变量声明
// ====================

extern RGB_PixelBuffer RGB_Buffer;  // 全局数据缓冲区

// ====================
// 函数声明
// ====================

void WS2812_Update(void);
void RGB_Write_Led_Bit(uint32_t RGB, uint16_t Index);
void RGB_Write_Led_Bit_AllLedSame(uint32_t RGB, uint16_t numLeds);

#endif /* __WS2812_H */

定义WS2812.c文件
复制

#include "ws2812.h"

RGB_PixelBuffer RGB_Buffer={0};

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  设置特定LED的RGB颜色。
  * @param  RGB: 组合后的RGB颜色值,格式为0x00RRGGBB。
  * @param  Index: 要写入的LED索引。
  * @retval None.
  */
void RGB_Write_Led_Bit(uint32_t RGB, uint16_t Index) {
    uint16_t led_index = Index;
    uint8_t  green= (RGB >> 16);  
    uint8_t  red= (RGB >> 8);  
    uint8_t blue = RGB;        
    for (uint8_t n = 0; n < 8; n++) {
        RGB_Buffer.All_Buffer[led_index][0 * 8 + n] = (red & (0x80 >> n)) ? RGB_led_bit_1 : RGB_led_bit_0;
        RGB_Buffer.All_Buffer[led_index][1 * 8 + n] = (green & (0x80 >> n)) ? RGB_led_bit_1 : RGB_led_bit_0;
        RGB_Buffer.All_Buffer[led_index][2 * 8 + n] = (blue & (0x80 >> n)) ? RGB_led_bit_1 : RGB_led_bit_0;
    }
}


/**
  * @brief  同时点亮所有LED为相同的RGB颜色。
  * @param  RGB: 组合后的RGB颜色值,格式为0x00RRGGBB。
  * @param  numLeds: LED的数量。
  * @retval None.
  */
void RGB_Write_Led_Bit_AllLedSame(uint32_t RGB, uint16_t numLeds) {
    for (uint16_t i = 0; i < numLeds; i++) {
        RGB_Write_Led_Bit(RGB, i);
    }
}

// 启动DMA传输
void WS2812_Update(void) {
            if((dma_data_number_get(DMA1_CHANNEL1) != 0))
                {
                        return;
                }else
                {
                         tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_1, 0);               
             tmr_counter_enable(TMR3, FALSE);
             dma_channel_enable(DMA1_CHANNEL1, FALSE);
             dma_data_number_set(DMA1_CHANNEL1, (RGB_PIXEL_NUM * 24));
                         dma_interrupt_enable(DMA1_CHANNEL1, DMA_FDT_INT, TRUE);                        
                         tmr_dma_request_enable(TMR3, TMR_C1_DMA_REQUEST, TRUE);        
             dma_channel_enable(DMA1_CHANNEL1, TRUE);
       tmr_counter_enable(TMR3, TRUE);
                }                        
}

DMA中断处理
复制

void DMA1_Channel1_IRQHandler(void)
{
  /* add user code begin DMA1_Channel1_IRQ 0 */
    if (dma_flag_get(DMA1_FDT1_FLAG) != RESET)
    {
                          tmr_dma_request_enable(TMR3, TMR_C1_DMA_REQUEST, FALSE);
                                tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_1, 0);
        dma_channel_enable(DMA1_CHANNEL1, FALSE);
                          dma_flag_clear(DMA1_FDT1_FLAG);
    }  
  /* add user code end DMA1_Channel1_IRQ 0 */
  /* add user code begin DMA1_Channel1_IRQ 1 */

  /* add user code end DMA1_Channel1_IRQ 1 */
}

6.波形检查(符合时序要求)

7.点亮效果
  



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]