使用PWM和DMA控制WS2812 LED - STM32F1

时间:2018-03-26 20:04:49

标签: stm32 stm32f1

尝试使用计时器WS2812 LEDsPWM来控制DMA。我几乎成功但现在我遇到了一个我无法解决的问题。正如您在图像上看到的那样,前两个LEDs发出绿光,而另一个LEDs发光。但是所有这些都应该发绿光。

![图片链接:] https://ibb.co/c2XEqS

我使用Nucleo Board和STM32F1微控制器(64MHZ)。

定时器初始化:

void Init_TIM4()
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    GPIO_InitTypeDef gpio;
    GPIO_StructInit(&gpio);

    gpio.GPIO_Mode = GPIO_Mode_AF_PP;
    gpio.GPIO_Pin = GPIO_Pin_8;
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &gpio);

    TIM_TimeBaseInitTypeDef tim;
    TIM_TimeBaseStructInit(&tim);
    tim.TIM_CounterMode = TIM_CounterMode_Up;
    tim.TIM_Period = 80;
    tim.TIM_ClockDivision = 0;
    TIM_TimeBaseInit(TIM4, &tim);

    TIM_OCInitTypeDef channel;
    TIM_OCStructInit(&channel);
    channel.TIM_OCMode = TIM_OCMode_PWM1;
    channel.TIM_OutputState = TIM_OutputState_Enable;
    channel.TIM_Pulse = 0;
    channel.TIM_OCIdleState = TIM_OCIdleState_Set;
    TIM_OC3Init(TIM4, &channel);
    }

DMA和其余代码:

#define BUFFER_SIZE 25

volatile uint16_t src_buffer[BUFFER_SIZE] = {32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,0};

void send_data()
{
    DMA_SetCurrDataCounter(DMA1_Channel1, BUFFER_SIZE);
    DMA_Cmd(DMA1_Channel1, ENABLE);
    TIM_Cmd(TIM4, ENABLE);

    while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
    TIM_Cmd(TIM4, DISABLE);
    DMA_Cmd(DMA1_Channel1, DISABLE);
    DMA_ClearFlag(DMA1_FLAG_TC1);
}

int main(void)
{
   Init_TIM4();

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    DMA_InitTypeDef dma;

    DMA_StructInit(&dma);
    dma.DMA_PeripheralBaseAddr = (uint32_t)&TIM4->CCR3;
    dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    dma.DMA_MemoryBaseAddr = (uint32_t)src_buffer;
    dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
    dma.DMA_BufferSize = BUFFER_SIZE;
    dma.DMA_M2M = DMA_M2M_Disable;
    dma.DMA_DIR = DMA_DIR_PeripheralDST;
    dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    dma.DMA_Mode = DMA_Mode_Normal;
    dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

    DMA_Init(DMA1_Channel1, &dma);
    TIM_DMACmd(TIM4, TIM_DMA_CC1, ENABLE);

    for (int i = 0; i < 8; i++) {
        send_data();
    }
    while(1)
    {

    }
}

0 个答案:

没有答案