cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32f103c8t6 Can't Start DMA ws2812b

nder
Associate
 

I want to drive a WS2812 LED strip using PWM and DMA. I've tried everything, but it's not working. I'm running at 72MHz, and I'm using htim2.Init.Prescaler = 0; and htim2.Init.Period = 90-1;. This is how my library works.

/*

* wsled.c

*

* Created on: May 31, 2024

* Author: arge

*/

 

#include "main.h"

#include "math.h"

#define MAX_LED 180

#define USE_BRIGHTNESS 0

 

extern TIM_HandleTypeDef htim2;

extern DMA_HandleTypeDef hdma_tim2_ch1;

uint8_t LED_Data[MAX_LED][4];

uint8_t LED_Mod[MAX_LED][4]; // for brightness

 

int datasentflag=0;

 

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)

{

HAL_TIM_PWM_Stop_DMA(&htim2, TIM_CHANNEL_1);

datasentflag=1;

}

 

void Set_LED (int LEDnum, int Red, int Green, int Blue)

{

LED_Data[LEDnum][0] = LEDnum;

LED_Data[LEDnum][1] = Green;

LED_Data[LEDnum][2] = Red;

LED_Data[LEDnum][3] = Blue;

}

 

#define PI 3.14159265

 

void Set_Brightness (int brightness) // 0-45

{

#if USE_BRIGHTNESS

 

if (brightness > 45) brightness = 45;

for (int i=0; i<MAX_LED; i++)

{

LED_Mod[i][0] = LED_Data[i][0];

for (int j=1; j<4; j++)

{

float angle = 90-brightness; // in degrees

angle = angle*PI / 180; // in rad

LED_Mod[i][j] = (LED_Data[i][j])/(tan(angle));

}

}

 

#endif

 

}

 

uint32_t pwmData[(24*MAX_LED)+50];

 

void WS2812_Send (void)

{

uint32_t indx=0;

uint32_t color;

 

 

for (int i= 0; i<MAX_LED; i++)

{

#if USE_BRIGHTNESS

color = ((LED_Mod[i][1]<<16) | (LED_Mod[i][2]<<8) | (LED_Mod[i][3]));

#else

color = ((LED_Data[i][1]<<16) | (LED_Data[i][2]<<8) | (LED_Data[i][3]));

#endif

 

for (int i=23; i>=0; i--)

{

if (color&(1<<i))

{

pwmData[indx] = 60; // 2/3 of 90

}

 

else pwmData[indx] = 30; // 1/3 of 90

 

indx++;

}

 

}

 

for (int i=0; i<50; i++)

{

pwmData[indx] = 0;

indx++;

}

 

HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_1, pwmData,indx);

while (!datasentflag){};

datasentflag = 0;

}

 

void Reset_LED (void)

{

for (int i=0; i<MAX_LED; i++)

{

LED_Data[i][0] = i;

LED_Data[i][1] = 0;

LED_Data[i][2] = 0;

LED_Data[i][3] = 0;

}

}

 

When I look at the oscilloscope, the frequency is 800kHz, and each period is 1.25 microseconds, which seems correct according to the datasheet. However, the intervals are always constant. When I use SetLed(12.led,255,0,0);, the 12th LED should light up green, but there is no response. If I set all LEDs to 255, not only the 12th LED but all LEDs light up. I've been struggling with this for 3 days. Can you help me?

0 REPLIES 0