Skip to main content
Visitor II
December 13, 2022
Solved

pwm ws2812 not workin

  • December 13, 2022
  • 5 replies
  • 1868 views

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

    This topic has been closed for replies.

    5 replies

    jdoAuthor
    Visitor II
    December 13, 2022

    0693W00000WKvCSQA1.png0693W00000WKvCqQAL.png0693W00000WKvCvQAL.png

    Super User
    December 13, 2022

    why not use spi for this ?

    jdoAuthor
    Visitor II
    December 16, 2022

    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.

    jdoAuthor
    Visitor II
    December 14, 2022

    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.

    Graduate II
    December 14, 2022

    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

    jdoAuthor
    Visitor II
    December 14, 2022

    "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.

    Graduate
    March 21, 2024

    also you can use my pack.

    https://github.com/nimaltd/ws28xx