STM32 WS2812 RGB LED инструкция


Что такое адресные RGB светодиоды WS2812


Адресные светодиоды — светодиоды, которые управляются световым сигналом по 1 линии данных. С контроллера приходит пакет данных на первый адресный RGB LED. Пакет данных содержит в себе все цвета всех светодиодов в цепочке. Первый светодиод забирает себе первые 24Bit из пакета данных и отправляет оставшиеся данные второму светодиоду. И так далее…

Светодиоды бывают в разных корпусах и также продаются распаянные на гибкие ленты.

Адресные RGB светодиоды WS2812

Адресные RGB светодиоды WS2812



Схема подключения WS2812

Адресные RGB светодиоды WS2812

Логический уровень WS2812 5V. Они могут управляться логическим сигналом с уровнем 3,3V только на плате или на коротких (до пары метров) проводах при условии питания RGB LED не более 5V.


Протокол данных WS2812

Адресные RGB светодиоды WS2812

Адресные RGB светодиоды WS2812

Адресные RGB светодиоды WS2812



Настройка частоты таймера и включение DMA


Частота работы адресных RGB светодиодов WS2812 800kHz.

Чтобы рассчитать делители таймера, воспользуйтесь этой формулой
Counter Period = ( Timer Clock / (Prescaler + 1) / 800000 ) — 1
Counter Period = ( 64000000 / (0 + 1) / 800000 ) — 1 = 79

STM32 WS2812

STM32 WS2812

Длину испольсов 0 и 1 для WS2812 нужно подобрать с помощью осциллографа или логического анализатора.
Для 0 Pulse должен быть ~450nS
Для 1 Pulse должен быть ~800nS
Полный период 1250nS (800kHz)

Для STM32G0 Timer DMA (с настройками тактирования таймеров, какие показаны на скриншоте выше)
WS2812 0: Pulse = 30
WS2812 1: Pulse = 53

Количество импульсов для каждого RGB LED WS2812 = 24 + в конце серии импульсов (для всех LED) 50uS задержка (сигнал LOW).

Теперь, чтобы таймер STM32 в режиме PWM Generation отправлял RGB светодиодам импульсы разной длины нужно включить DMA

STM32 Timer PWM Generation DMA

Для STM32G0 в качестве массива с длинами импульсов можно использовать 8Bit массив (Byte). В других сериях STM32 Byte массив может некорректно работать. В таких случаях укажите не Byte, а Half Word и используйте массив uint16_t, а не uint8_t.

1
2
uint8_t pwmData[LEDPWMDataLength];
uint16_t pwmData[LEDPWMDataLength];



Настройка параметров GPIO для Data Pin for WS2812

STM32 WS2812

ВАЖНО: Не рекомендуется оставлять линию данных для RGB LED WS2812 без подтяжки (комментарии по этому моменту в видео).


Программируем RGB LED WS2812 на STM32

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
...
/* USER CODE BEGIN 0 */
#define MAXIMAL_LEDC 23
uint8_t LED_Data[MAXIMAL_LEDC][3];
volatile uint8_t t_RGBLEDDataWasSent = 0;
 
#define LEDPWMDataLength (24 * MAXIMAL_LEDC) + 50
uint8_t pwmData[LEDPWMDataLength];
 
void WS2812_ResetPWM_Array(void)
{
	uint16_t i = 0;
	while (i < LEDPWMDataLength)
	{
		pwmData[i] = 0;
		i++;
	}
}
 
void WS2812_Send(void)
{
	uint32_t indx=0;
	uint32_t color;
 
	for (int i= 0; i<MAXIMAL_LEDC; i++)
	{
		color = ((LED_Data[i][0]<<16) | (LED_Data[i][1]<<8) | (LED_Data[i][2]));
 
		for (int j=23; j>=0; j--)
		{
			if (color&(1<<j))
			{
				pwmData[indx] = 53;  // 2/3 of 90
			}
 
			else pwmData[indx] = 30;  // 1/3 of 90
 
			indx++;
		}
 
	}
 
        t_RGBLEDDataWasSent = 0;	
 
        HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_4, (uint32_t *)pwmData, LEDPWMDataLength);
 
	while (!t_RGBLEDDataWasSent) {};
 
}
 
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM1)
	{
		HAL_TIM_PWM_Stop_DMA(&htim1, TIM_CHANNEL_4);
		t_RGBLEDDataWasSent = 1;
	}
 
}
 
void SETLedS(uint8_t R, uint8_t G, uint8_t B)
{
	uint8_t i = 0;
	while (i < MAXIMAL_LEDC)
	{
		LED_Data[i][0] = G;
		LED_Data[i][1] = R;
		LED_Data[i][2] = B;
		i++;
	}
	WS2812_Send();
}
 
void Set_LED(int LEDnum, int Red, int Green, int Blue)
{
	LED_Data[LEDnum][0] = Green;
	LED_Data[LEDnum][1] = Red;
	LED_Data[LEDnum][2] = Blue;
}
/* USER CODE END 0 */
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  WS2812_ResetPWM_Array();
  while (1)
  {
	SETLedS(0, 2, 0);
	HAL_Delay(1000);
	SETLedS(0, 0, 20);
	HAL_Delay(1000);
	SETLedS(2, 0, 0);
	HAL_Delay(1000);
    /* USER CODE END WHILE */
...

#define MAXIMAL_LEDC 23 — количество используемых RGB LED светодиодов

WS2812_ResetPWM_Array(); — сброс массива с данными для PWM Generation DMA

SETLedS(uint8_t R, uint8_t G, uint8_t B) — установить цвет для ВСЕХ светодиодов

Set_LED(int LEDnum, int Red, int Green, int Blue) — установить цвет для светодиода с индексом LEDnum


В видео подробно пояснено, как пользоваться функциями для WS2812.


1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)

Загрузка...

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Optionally add an image (JPEG only)