amobbs.com 阿莫电子技术论坛

标题: 用gd32f330驱动单极性归零码LED出现波形不对的问题 [打印本页]

作者: tjiefk    时间: 2022-5-12 20:06
标题: 用gd32f330驱动单极性归零码LED出现波形不对的问题
本帖最后由 tjiefk 于 2022-5-12 20:08 编辑

最近有一个项目需要用到RGB LED,选了内置IC的LED灯珠,MCU用GD32F330,PWM+DMA方式,用示波器发现波形不太对,高占空比切到低占空比没有问题,但从低占空比切到高占空比时就出现第一个高占空比波形不对
[attach]586198[/attach]
[attach]586199[/attach]
下面是代码:

#include "rgb_led.h"

const uint8_t g_red[3] = {0x00, 0xff, 0x00};
const uint8_t g_green[3] = {0xff, 0x00, 0x00};
const uint8_t g_blue[3] = {0x00, 0x00, 0xff};

uint16_t g_rgb_led_buf[(24*7+24)]=
{
    // ZERO,ZERO,ZERO,ZERO,ONE,ONE,ONE,ONE,
    // ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,
    // ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,
        ZERO
};

// uint8_t g_rgb_led_buf[48]=
// {
//     ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,
//     ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,ZERO,
//     ZERO,ZERO,ZERO,ZERO,ONE,ONE,ONE,ONE,
//     0,0,0,0,0,0,0,0,
//     0,0,0,0,0,0,0,0,
//     0,0,0,0,0,0,0,0
// };

void rgb_led_gpio_init(void)
{
    rcu_periph_clock_enable(RCU_GPIOB);
    /*Configure PB5(TIMER2_CH1) as alternate function*/
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4);
    gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_4);

}

void timer2_init(void)
{
    /* TIMER2 configuration: generate PWM signals with different duty cycles:
    TIMER2CLK = SystemCoreClock / 1 = 84MHz */
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER2);
    timer_deinit(TIMER2);

    /* TIMER0 configuration */
    timer_initpara.prescaler         = 1-1;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 94-1;            //PWM频率893K
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_init(TIMER2,&timer_initpara);

     /* CH0 configuration in PWM mode */
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
    timer_channel_output_config(TIMER2,TIMER_CH_0,&timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0,0);      //占空比66%
    timer_channel_output_mode_config(TIMER2,TIMER_CH_0,TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(TIMER2,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);

    /* auto-reload preload enable */
    //timer_auto_reload_shadow_enable(TIMER2);

    timer_dma_disable(TIMER2, TIMER_DMA_CH0D);
   
}

void rgb_dma_init(void)
{
    dma_parameter_struct dma_init_struct;

    /* enable DMA clock */
    rcu_periph_clock_enable(RCU_DMA);
   
    /* initialize DMA channel */
    dma_deinit(DMA_CH3);
    /* DMA channel3 initialize */
    dma_struct_para_init(&dma_init_struct);
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
    dma_init_struct.memory_addr = (uint32_t)g_rgb_led_buf;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;   
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.number = 0;
    dma_init_struct.periph_addr = (uint32_t)TIMER2_CH0CV_ADDR;
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA_CH3,&dma_init_struct);
    /* 使能循环模式 */
    //dma_circulation_enable(DMA_CH3);
    /* enable DMA channel3 */
        
}



void rgb_led_init(void)
{
    rgb_led_gpio_init();
    rgb_dma_init();
    timer2_init();
}




void rgb_led_show(const uint8_t color[], uint16_t len)
{
    uint8_t i = 0;
    uint16_t memaddr = 0;
    uint16_t buffersize = 0;

    buffersize = (len * 24)+24;       // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes
//    memaddr = 0;                        // reset buffer memory index

    while (len)
    {
        /*  green data */
        for(i = 0; i < 8; i++)
        {
            g_rgb_led_buf[memaddr] = ((color[0] << i) & 0x80) ? ONE : ZERO;
            memaddr++;
        }

        /*  red data */
        for(i = 0; i < 8; i++)
        {   
            g_rgb_led_buf[memaddr] = ((color[1] << i) & 0x80) ? ONE : ZERO;
            memaddr++;
        }

        /*  blue data */
        for(i = 0; i < 8; i++)
        {
            g_rgb_led_buf[memaddr] = ((color[2] << i) & 0x80) ? ONE : ZERO;
            memaddr++;
        }

        len--;
    }
    timer_counter_value_config(TIMER2, 0);
    dma_transfer_number_config(DMA_CH3, buffersize);   
    timer_dma_enable(TIMER2, TIMER_DMA_CH0D);
    dma_channel_enable(DMA_CH3);
    timer_enable(TIMER2);
    while(!dma_flag_get(DMA_CH3, DMA_FLAG_FTF));
    timer_disable(TIMER2);
    dma_channel_disable(DMA_CH3);
    dma_flag_clear(DMA_CH3, DMA_FLAG_FTF);
}



作者: tjiefk    时间: 2022-5-14 07:38
终于搞定了,但又出现新问题,第一个脉冲丢失,前面加多少0都没用
作者: 1a2b3c    时间: 2022-5-14 07:59
虽然没有去看你的代码。但是可以提醒你一下,因为正好前几天刚用了PiC的pwm,说的是需要的第一次定时器溢出后再开启pwm输出(pic是操作gpio输出模式使能),这样可以避免第一个脉冲宽度不对的问题,因为可能切换或者刚配置后第一个的时间不是满的,希望有用




欢迎光临 amobbs.com 阿莫电子技术论坛 (https://www.amobbs.com/) Powered by Discuz! X3.4