l441867854 发表于 2019-7-12 11:16:09

STM32f030f4p6 DMA驱动2811 为什么PWM频率达不到800KHZ

#define TIM_PERIOD                59                                        // Number of CPU cycles that will constitute 1 period
#define PWM_HIGH_WIDTH                45                                // Duty cycle of pwm signal for a logical 1 to be read by the ws2812 chip.                                                                                                                                                //Duty cycle = PWM_HIGH_WIDTH/TIM_PERIOD*100
#define PWM_LOW_WIDTH                10               
uint8_t ledBuff={0};               

void TIM3_PWM_Init(void){                 GPIO_InitTypeDefGPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef       TIM_OCInitStructure;        DMA_InitTypeDef DMA_InitStructure;          /* 配置相应引脚PB1*/    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_DMA1, ENABLE);    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;    GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_UP;    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;          GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_1);    GPIO_Init(GPIOB, &GPIO_InitStructure);                 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟    TIM_TimeBaseStructure.TIM_Period      = TIM_PERIOD;// 设置自动重装周期值    TIM_TimeBaseStructure.TIM_Prescaler   = 0;//设置预分频值    TIM_TimeBaseStructure.TIM_ClockDivision = 0;//设置时钟分割    TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;//向上计数    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);    //初始化定时器3      TIM_OCInitStructure.TIM_OCMode      = TIM_OCMode_PWM1;// PWM2模式    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能                TIM_OCInitStructure.TIM_Pulse = 0;    TIM_OCInitStructure.TIM_OCPolarity= TIM_OCPolarity_High;//输出高    TIM_OC4Init(TIM3, &TIM_OCInitStructure);    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能预装载寄存器          DMA_DeInit(DMA1_Channel3);               DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(TIM3->CCR4);        // physical address of Timer 3 CCR4        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledBuff;                // this is the buffer memory         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                                                // data shifted from memory to peripheral        DMA_InitStructure.DMA_BufferSize = sizeof(ledBuff);        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        // automatically increase buffer index        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                                        // stop DMA feed after buffer size is reached        DMA_InitStructure.DMA_Priority = DMA_Priority_High;        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                DMA_Init(DMA1_Channel3, &DMA_InitStructure);                        TIM_DMACmd(TIM3, TIM_DMA_CC4, ENABLE);                }

void Ws2812_reflash(void){        DMA_SetCurrDataCounter(DMA1_Channel3, sizeof(ledBuff));        DMA_Cmd(DMA1_Channel3,ENABLE);        TIM_Cmd(TIM3, ENABLE);        while(!DMA_GetFlagStatus(DMA1_FLAG_TC3));        TIM_Cmd(TIM3, DISABLE);        DMA_Cmd(DMA1_Channel3,DISABLE);        DMA_ClearFlag(DMA1_FLAG_TC3);        }void Set2812RGB(uint8_t redcolor,uint8_t greencolor,uint8_t bluecolor){        uint8_t i=0;        uint32_t rgb_value=redcolor<<16|greencolor<<8|bluecolor;                        for(i=0;i<69;i++)        {                if((rgb_value<<i)&0x800000)                {                        ledBuff=PWM_HIGH_WIDTH;                }                else                 {                        ledBuff=PWM_LOW_WIDTH;                }                                }        }

int main(void){         //delay_init();        TIM3_PWM_Init();        while(1)        {        //TIM_SetCompare2(TIM1, 10);//ws2812_senddata(color,LED_COUNT);        Set2812RGB(0,57,0);        Ws2812_reflash();//delay_ms(10);        }                }        

butterflyspring 发表于 2019-7-15 21:57:31

你的系统时钟要设置到48MHZ哦,否则达不到,检查一下先:)
页: [1]
查看完整版本: STM32f030f4p6 DMA驱动2811 为什么PWM频率达不到800KHZ