发新帖本帖赏金 20.00元(功能说明)我要提问
返回列表
打印
[活动专区]

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

[复制链接]
623|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 阿源玩电子 于 2025-6-22 18:40 编辑

#申请原创#
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.点亮效果






AT32M412CBT7_WS2812.zip

3.09 MB

驱动工程文件

使用特权

评论回复

打赏榜单

ArteryMCU 打赏了 20.00 元 2025-07-04
理由:[M412开发板评测活动]内容优质

发新帖 本帖赏金 20.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

29

帖子

0

粉丝