mirror of
https://gitee.com/dlmu-cone/tronone-h7-scaffold
synced 2026-07-25 03:47:46 +08:00
122 lines
3.7 KiB
C
122 lines
3.7 KiB
C
/**
|
|
* @file ws2812.c
|
|
* @brief WS2812 LED driver
|
|
* @author TuxMonkey (nqx2004@gmail.com)
|
|
* @version 1.0
|
|
* @date 2025-07-08
|
|
*
|
|
* @copyright Copyright (c) 2025 DLMU-C.ONE
|
|
*
|
|
* @par 修改日志:
|
|
* <table>
|
|
* <tr><th>Date <th>Version <th>Author <th>Description
|
|
* <tr><td>2025-07-08 <td>1.0 <td>TuxMonkey <td>内容
|
|
* </table>
|
|
*/
|
|
|
|
#include "ws2812.h"
|
|
|
|
#define WS2812_SPI_TIMEOUT 2U
|
|
#define WS2812_RESET_BYTES 100U
|
|
|
|
#define WS2812_LowLevel 0xC0 // 0码
|
|
#define WS2812_HighLevel 0xF0 // 1码
|
|
|
|
static SPI_HandleTypeDef ws2812_spi;
|
|
static uint8_t ws2812_spi_initialized = 0U;
|
|
|
|
static uint8_t WS2812_SPI_Init(void)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
|
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
|
|
|
if (ws2812_spi_initialized != 0U)
|
|
{
|
|
return 1U;
|
|
}
|
|
|
|
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI6;
|
|
PeriphClkInitStruct.Spi6ClockSelection = RCC_SPI6CLKSOURCE_HSE;
|
|
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
|
{
|
|
return 0U;
|
|
}
|
|
|
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
|
__HAL_RCC_SPI6_CLK_ENABLE();
|
|
|
|
GPIO_InitStruct.Pin = GPIO_PIN_7;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
|
GPIO_InitStruct.Alternate = GPIO_AF8_SPI6;
|
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
|
|
|
ws2812_spi.Instance = SPI6;
|
|
ws2812_spi.Init.Mode = SPI_MODE_MASTER;
|
|
ws2812_spi.Init.Direction = SPI_DIRECTION_2LINES_TXONLY;
|
|
ws2812_spi.Init.DataSize = SPI_DATASIZE_8BIT;
|
|
ws2812_spi.Init.CLKPolarity = SPI_POLARITY_LOW;
|
|
ws2812_spi.Init.CLKPhase = SPI_PHASE_2EDGE;
|
|
ws2812_spi.Init.NSS = SPI_NSS_SOFT;
|
|
ws2812_spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
|
|
ws2812_spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
|
ws2812_spi.Init.TIMode = SPI_TIMODE_DISABLE;
|
|
ws2812_spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
|
ws2812_spi.Init.CRCPolynomial = 0x0;
|
|
ws2812_spi.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
|
|
ws2812_spi.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
|
|
ws2812_spi.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
|
|
ws2812_spi.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
|
|
ws2812_spi.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
|
|
ws2812_spi.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
|
|
ws2812_spi.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
|
|
ws2812_spi.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
|
|
ws2812_spi.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
|
|
ws2812_spi.Init.IOSwap = SPI_IO_SWAP_DISABLE;
|
|
|
|
if (HAL_SPI_Init(&ws2812_spi) != HAL_OK)
|
|
{
|
|
return 0U;
|
|
}
|
|
|
|
ws2812_spi_initialized = 1U;
|
|
return 1U;
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* @param [in] r My Param doc
|
|
* @param [in] g My Param doc
|
|
* @param [in] b My Param doc
|
|
*/
|
|
void WS2812_Ctrl(uint8_t r, uint8_t g, uint8_t b)
|
|
{
|
|
uint8_t txbuf[24];
|
|
uint8_t res = 0;
|
|
|
|
if (WS2812_SPI_Init() == 0U)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (uint8_t i = 0; i < 8U; i++)
|
|
{
|
|
txbuf[7 - i] = (((g >> i) & 0x01) ? WS2812_HighLevel : WS2812_LowLevel) >> 1;
|
|
txbuf[15 - i] = (((r >> i) & 0x01) ? WS2812_HighLevel : WS2812_LowLevel) >> 1;
|
|
txbuf[23 - i] = (((b >> i) & 0x01) ? WS2812_HighLevel : WS2812_LowLevel) >> 1;
|
|
}
|
|
if (HAL_SPI_Transmit(&ws2812_spi, txbuf, sizeof(txbuf), WS2812_SPI_TIMEOUT) != HAL_OK)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (uint8_t i = 0; i < WS2812_RESET_BYTES; i++)
|
|
{
|
|
if (HAL_SPI_Transmit(&ws2812_spi, &res, 1U, WS2812_SPI_TIMEOUT) != HAL_OK)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|