zhanxiaozhang

    1. WS2812灯珠的STM32驱动方式(二)——DMA+PWM 74/43174 DIY/开源硬件专区 2019-09-11
      通宵敲代码 发表于 2019-9-11 08:30 排查一下程序,再就是保证供电电流足够, 理论上这种灯珠可以级联1000多颗。
      我的PWM第一个脉冲有问题,周期不对,剩下的都正确,仿真的波形到是正确的。能否帮忙看看? void timer2_pwm_ch2_init (void) {   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;   TIM_OCInitTypeDef TIM_OCInitStructure;   DMA_InitTypeDef DMA_InitStructure;   RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM2, ENABLE);   TIM_DeInit(TIM2);   /* Compute the prescaler value */   //PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;   /* Time base configuration */   TIM_TimeBaseStructure.TIM_Period = 90 - 1; // 800kHz   TIM_TimeBaseStructure.TIM_Prescaler = 0;   TIM_TimeBaseStructure.TIM_ClockDivision = 0;   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   TIM_TimeBaseInit (TIM2, &TIM_TimeBaseStructure);   /* PWM2 Mode configuration: Channel1 */   TIM_OCStructInit(&TIM_OCInitStructure);   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   TIM_OCInitStructure.TIM_Pulse = 0;   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;   TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset;   TIM_ARRPreloadConfig(TIM2, ENABLE);   TIM_OC2Init (TIM2, &TIM_OCInitStructure);   /* configure DMA */   /* DMA clock enable */   RCC_AHBPeriphClockCmd (RCC_AHBPeriph_DMA1, ENABLE);   /* DMA1 Channel7 Config for PWM2 by TIM2_CH2*/   DMA_DeInit (DMA1_Channel2);   DMA_StructInit(&DMA_InitStructure);   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(TIM2->CCR2);    // physical address of Timer 2 CCR2   DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) WS2812B_OUTPUT_LED_PWM2_BUFFER;        // this is the buffer memory   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;            // data shifted from memory to peripheral   DMA_InitStructure.DMA_BufferSize = 42;   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_Channel2, &DMA_InitStructure);   DMA_ClearFlag(DMA1_FLAG_TC2);   /* TIM2 DMA Request enable */   //TIM_DMACmd (TIM2, TIM_DMA_CC2, ENABLE);   TIM_DMACmd (TIM2, TIM_DMA_Update, ENABLE); #if 1 WS2812B_send_led_pwm2(test_array, 1); #endif }   void WS2812B_send_led_pwm2 (uint8_t (*color)[3], uint16_t len) {     uint8_t i;     uint16_t memaddr;     uint16_t buffersize;     buffersize = (len * 24)+1 ; // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes     memaddr = 0;              // reset buffer memory index     uint8_t total=len;           while (len)     {         for (i = 0; i < 8; i++) // GREEN data         {             WS2812B_OUTPUT_LED_PWM2_BUFFER[memaddr] = ((color[0][1] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;             memaddr++;         }         for (i = 0; i < 8; i++) // RED         {             WS2812B_OUTPUT_LED_PWM2_BUFFER[memaddr] = ((color[0][0] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;             memaddr++;         }         for (i = 0; i < 8; i++) // BLUE         {             WS2812B_OUTPUT_LED_PWM2_BUFFER[memaddr] = ((color[0][2] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;             memaddr++;         }         len--;     } //===================================================================// //bug:最后一个周期波形不知道为什么全是高电平,故增加一个波形     WS2812B_OUTPUT_LED_PWM2_BUFFER[memaddr] = ((color[0][2] << 8) & 0x0080) ? TIMING_ONE : TIMING_ZERO; //===================================================================//     memaddr++;     while (memaddr < buffersize)     {         WS2812B_OUTPUT_LED_PWM2_BUFFER[memaddr] = 0;         memaddr++;     }     TIM_ClearFlag(TIM2,TIM_FLAG_Update );     TIM_SetCounter(TIM2, 0);     DMA_SetCurrDataCounter (DMA1_Channel2, buffersize);   // load number of bytes to be transferred     TIM_Cmd (TIM2, ENABLE);      DMA_Cmd (DMA1_Channel2, ENABLE);          // enable DMA channel 6         // enable Timer 3     while (!DMA_GetFlagStatus (DMA1_FLAG_TC2))         ;   // wait until transfer complete     TIM_Cmd (TIM2, DISABLE);  // disable Timer 3     DMA_Cmd (DMA1_Channel2, DISABLE);             // disable DMA channel 6     DMA_ClearFlag (DMA1_FLAG_TC2);                // clear DMA1 Channel 6 transfer complete flag }

最近访客

< 1/1 >

统计信息

已有2人来访过

  • 芯积分:--
  • 好友:--
  • 主题:--
  • 回复:1

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言