|
|
//PA2-TIMER4-CH2 DMA0 -CH0
#include "bsp_pwm.h"
//#include "ws2812.h"
#include "gd32f4xx.h"
//// 定义RGB_LOGICAL值(根据实际PWM周期计算)
#define RGB_LOGICAL_H 96 // 0.8μs (对应逻辑1)
#define RGB_LOGICAL_L 48 // 0.4μs (对应逻辑0)
// 全局缓冲区(最大支持 个灯珠)
#define MAX_LED_COUNT 4
#define RGB_LEN (MAX_LED_COUNT * 24 + 42)
uint16_t LED_Buff[RGB_LEN];
void Tim4CH2_init_DMA(uint32_t number);
#define TIMER4_CH2CV (TIMER4+0x3C) /* 通道2 */
void Timer4_init(void)
{
rcu_periph_clock_enable(RCU_TIMER4);
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_DMA0);
dma_single_data_parameter_struct dma_data_parameter;
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
gpio_af_set(GPIOA, GPIO_AF_2, GPIO_PIN_2);
/* TIMER4 configuration */
timer_initpara.prescaler = 0; //时钟预分频数 (200)M/10/25 = 0.8mHz = 800KHz
timer_initpara.alignedmode = TIMER_COUNTER_EDGE; //向上&向下都是边沿对齐
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 149; /* 自动重装载寄存器周期的值(计数值) */
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER4, &timer_initpara);
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER4, TIMER_CH_2, &timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER4, TIMER_CH_2, 50); //占空比 = TIMERx_CHxCV / TIMERx_CAR
timer_channel_output_mode_config(TIMER4, TIMER_CH_2, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER4, TIMER_CH_2, TIMER_OC_SHADOW_DISABLE);//TIMER_OC_SHADOW_ENABLE
timer_primary_output_config(TIMER4,ENABLE);
timer_auto_reload_shadow_enable(TIMER4);
// ////RGB0--(Timer4_Ch0)--(DMA0_ch2_stream6)-pa0
dma_deinit(DMA0,DMA_CH0);
/* initialize DMA single data mode */
dma_data_parameter.periph_addr = (uint32_t)(uint32_t)&TIMER_CH2CV(TIMER4); ;
dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_data_parameter.memory0_addr = (uint32_t)LED_Buff;
dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_32BIT;
dma_data_parameter.direction = DMA_MEMORY_TO_PERIPH;
dma_data_parameter.number = 42;
dma_data_parameter.priority = DMA_PRIORITY_HIGH;
dma_single_data_mode_init(DMA0, DMA_CH0, &dma_data_parameter);
dma_channel_subperipheral_select(DMA0, DMA_CH0, DMA_SUBPERI6);
dma_circulation_disable(DMA0, DMA_CH0);
timer_dma_enable(TIMER4,TIMER_DMA_UPD);
dma_channel_disable(DMA0, DMA_CH0);
timer_disable(TIMER4);
}
static void WS2812_send_internal(uint8_t (*color)[3], uint16_t len)
{
uint16_t buffersize = (len * 24) + 42;
if(buffersize >= RGB_LEN) {
return;
}
// 准备数据
uint16_t memaddr = 0;
for(uint16_t led = 0; led < len; led++) {
// 准备RGB数据
for(uint8_t j = 0; j < 8; j++) {
LED_Buff[memaddr++] = ((color[led][1]<<j) & 0x80) ? RGB_LOGICAL_H : RGB_LOGICAL_L;
}
for(uint8_t j = 0; j < 8; j++) {
LED_Buff[memaddr++] = ((color[led][0]<<j) & 0x80) ? RGB_LOGICAL_H : RGB_LOGICAL_L;
}
for(uint8_t j = 0; j < 8; j++) {
LED_Buff[memaddr++] = ((color[led][2]<<j) & 0x80) ? RGB_LOGICAL_H : RGB_LOGICAL_L;
}
}
// 填充剩余缓冲区
while(memaddr < buffersize) {
LED_Buff[memaddr++] = 0;
}
Tim4CH2_init_DMA(buffersize);
dma_channel_enable(DMA0, DMA_CH0);
timer_enable(TIMER4);
}
void WS2812_send(uint8_t (*color)[3], uint16_t len)
{
WS2812_send_internal(color, len);
}
// DMA中断处理函数
void DMA0_Channel0_IRQHandler(void)
{
if(dma_flag_get(DMA0, DMA_CH0, DMA_INTF_FTFIF)) {
dma_flag_clear(DMA0, DMA_CH0, DMA_INTF_FTFIF);
dma_channel_disable(DMA0, DMA_CH0);
timer_disable(TIMER4);
}
}
void Tim4CH2_init_DMA(uint32_t number)
{
dma_single_data_parameter_struct dma_data_parameter;
////RGB2-Timer4_Ch2--DMA0_ch0_stream6
dma_deinit(DMA0,DMA_CH0);
/* initialize DMA single data mode */
dma_data_parameter.periph_addr = (uint32_t)&TIMER_CH2CV(TIMER4); //DMA 目标地址:TIM4通道2的输出比较
dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE; //一个周期内地址是否自增
dma_data_parameter.memory0_addr = (uint32_t)LED_Buff; //DMA 源地址
dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE; //一个周期内地址是否自增
dma_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_32BIT; //设置DMA传输的位数
dma_data_parameter.direction = DMA_MEMORY_TO_PERIPH; //DMA由内存向外设写入数据
dma_data_parameter.number = number; //DMA每次传输的数据长度
dma_data_parameter.priority = DMA_PRIORITY_HIGH; //设置DMA的优先级
dma_single_data_mode_init(DMA0, DMA_CH0, &dma_data_parameter); //初始化DMA0的通道2
dma_channel_subperipheral_select(DMA0, DMA_CH0, DMA_SUBPERI6); //选择subperipheral
dma_circulation_disable(DMA0, DMA_CH0);
timer_dma_enable(TIMER4,TIMER_DMA_UPD);
dma_channel_disable(DMA0, DMA_CH0);
dma_interrupt_enable(DMA0, DMA_CH0, DMA_CHXCTL_FTFIE);
nvic_irq_enable(DMA0_Channel0_IRQn, 2, 0);
}
int demo_test(void)
{
Timer4_init();
// 定义8个灯珠的RGB颜色(GRB顺序)
uint8_t led_colors[3][3] = {
{0xFF, 0xFF, 0x00}, //
{0xFF, 0x00, 0x00}, //
{0xFF, 0x00, 0xFF}, //
};
while (1) {
// 发送数据(3个灯珠,使用Timer4_CH2通道)
// WS2812_send(led_colors, 3);
WS2812_send(led_colors, 3);
delay_1ms(1000);
}
}
|
-
|