cancel
Showing results for 
Search instead for 
Did you mean: 

pwm ws2812 not workin

jdo
Associate II

Hi! i am doing example pwm ws2812 with dma, configure the time 1 with ARR=60, using clock= 48 mhz, my pwm not working full buffer i don´t know why not work full buffer, the pwm have 12 pulse, i am sending for one led ws2812 is 24 pulse.

/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "MATH.h"
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define MAX_LED 8
#define USE_BRIGHTNESS 0
 
 
uint8_t LED_Data[MAX_LED][4];
uint8_t LED_Mod[MAX_LED][4];  // for brightness
 
volatile int datasentflag;
//uint16_t pwmData[(24*MAX_LED)+50];
 
uint32_t indx=0;
uint32_t color;
uint32_t cont=0;
uint32_t data1=0;
 
//uint16_t pwmData[74];
 
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim1;
DMA_HandleTypeDef hdma_tim1_ch2;
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_TIM1_Init(void);
/* USER CODE BEGIN PFP */
 
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
 
	//HAL_TIM_PWM_Stop_DMA(&htim1, TIM_CHANNEL_2);
	//datasentflag=1;
}
 
 
 
uint16_t pwmData[74];
 
 void send(int Green, int Red, int Blue)
 {
	 uint32_t data = (Green<<16)|(Red<<8)|Blue;
 
 
	 for(int i=23;i>=0;i--)
	 {
 
		 if(data&(1<<i)) pwmData[i] =40;
 
		 else pwmData[i] = 20;
 
		indx=i;
		cont++;
	 }
	indx++;
 
	 for (int i=24; i<50; i++)
	 	{
	 		pwmData[i] = 0;
	 		indx++;
	 		cont++;
	 	}
	 indx=0;
 
 
	 HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_2,(uint32_t *)pwmData,74);
 
 }
 
 
 
/*--------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------*/
 
 
 
void WS2812_Send (void)
{
	indx=0;
 
 
	for (int i= 0; i<3; 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] = 38;  // 2/3 of 90
			}
 
			else pwmData[indx] = 19;  // 1/3 of 90
 
			indx++;
		}
 
	}
 
	for (int i=0; i<50; i++)
	{
		pwmData[indx] = 0;
		indx++;
	}
 
	HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_2, (uint32_t *)pwmData,indx);
	while (!datasentflag){};
	datasentflag = 0;
}
 
/*-------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------------------*/
 
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
 
}
 
 
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */
 
  // TIM1->CCR3=60;
 //   HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
 
 
  send (0,255,0);
/*
   Set_LED(0, 255, 0, 0);
   Set_LED(1, 0, 255, 0);
   Set_LED(2, 0, 0, 255);
 
   Set_LED(3, 46, 89, 128);
 
   Set_LED(4, 156, 233, 100);
   Set_LED(5, 102, 0, 235);
   Set_LED(6, 47, 38, 77);
 
   Set_LED(7, 255, 200, 0);
 
*/
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
	  send (5,255,18);
	  HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_SET);
	  HAL_Delay(200);
	  HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_RESET);
	  HAL_Delay(200);
  }
  /* USER CODE END 3 */
}
 
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}
 
/**
  * @brief TIM1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM1_Init(void)
{
 
  /* USER CODE BEGIN TIM1_Init 0 */
 
  /* USER CODE END TIM1_Init 0 */
 
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
 
  /* USER CODE BEGIN TIM1_Init 1 */
 
  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 0;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 60-1;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */
 
  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);
 
}
 

0693W00000WKvAGQA1.png

1 ACCEPTED SOLUTION
8 REPLIES 8
jdo
Associate II

0693W00000WKvCSQA1.png0693W00000WKvCqQAL.png0693W00000WKvCvQAL.png

AScha.3
Chief III

why not use spi for this ?

If you feel a post has answered your question, please click "Accept as Solution".
jdo
Associate II

HI! THANKS! I GOING TO USE YOUR TUTORIAL, I HAVE A QUESTION, I HAVE A CUSTOM PCB WITH STM32F030K6T6, BUT I NOT HAVE CRYSTAL EXTERN, I AM USING INTERNAL 48 MHZ, THIS INFLUENCY IN THE PWM? MY BLUEPILL IS FALSE IN THE ALIEXPRESS, I BUY BLUEPILL AND NOT WORK.

I AM GOING TO ANSWER IN UPPERCASE ALSO, AS IF WE WERE SHOUTING INSIDE A HAIL STORM.

0693W00000WL0sNQAT.gif>>I AM USING INTERNAL 48 MHZ, THIS INFLUENCY IN THE PWM?

YES, IT WILL MAKE YOUR SYSTEM CLOCK LESS ACCURATE AND PRONE TO DRIFT WITH TEMPERATURE, BUT NEOPIXELS TOLERATE A BIT OF PWM DRIFT, CHECK IT OUT YOURSELF.

>> MY BLUEPILL IS FALSE IN THE ALIEXPRESS, I BUY BLUEPILL AND NOT WORK.

GOOD LUCK WITH THAT

we dont need to firmware by ourselves, lets talk
jdo
Associate II

"I AM GOING TO ANSWER IN UPPERCASE ALSO, AS IF WE WERE SHOUTING INSIDE A HAIL STORM."

Ah ah ah ah ah! thanks! i don´t know why my pwm stop, not work one moment and work other moment.

thanks, i make your tutorial and this funcional. my bluepill is funcinal too. i know your is using timer 1, this is in APB2 bus, and i am using timer3 this is in APB1, the clock is different.

nimaltd
Senior

also you can use my pack.

https://github.com/nimaltd/ws28xx