stm32f103c8t6 配置DMA+PWM ws2812b
时间: 2023-10-01 22:09:06 浏览: 173
stm32f103c8t6_ws281x_spi+dma_spi_stm32_ws2812b_dma_
5星 · 资源好评率100%
要使用STM32F103C8T6控制WS2812B RGB LED,您需要使用DMA控制器和PWM模块来生成信号。以下是配置步骤:
1. 配置TIM模块:
- 设置TIM时钟源和分频系数
- 配置PWM模式和计数器自动重载值
- 配置PWM输出通道和占空比
2. 配置DMA通道:
- 设置DMA通道和流控制器
- 配置DMA数据传输方向和数据大小
- 配置DMA传输地址和传输模式
3. 配置WS2812B LED:
- 设置WS2812B LED的通道数和每个通道的数据位数
- 将PWM数据缓冲区中的数据转换为WS2812B协议的数据格式
4. 启动DMA传输:
- 启动DMA传输和PWM输出
这里还提供一份参考代码,仅供参考:
```c
#include "stm32f1xx_hal.h"
// 定义WS2812B LED的通道数和每个通道的数据位数
#define LED_COUNT 8
#define LED_BIT_COUNT 24
// 定义PWM数据缓冲区
uint16_t pwm_buffer[LED_COUNT * LED_BIT_COUNT * 2];
// 配置TIM模块
void TIM_Config(void)
{
TIM_HandleTypeDef htim;
// 设置TIM时钟源和分频系数
htim.Instance = TIM2;
htim.Init.Prescaler = 71;
htim.Init.CounterMode = TIM_COUNTERMODE_UP;
htim.Init.Period = 29;
htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim.Init.RepetitionCounter = 0;
HAL_TIM_PWM_Init(&htim);
// 配置PWM模式和计数器自动重载值
TIM_OC_InitTypeDef sConfigOC;
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 14;
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;
HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, TIM_CHANNEL_1);
// 配置PWM输出通道和占空比
HAL_TIM_PWM_Start(&htim, TIM_CHANNEL_1);
HAL_TIM_PWM_Start_DMA(&htim, TIM_CHANNEL_1, (uint32_t *)pwm_buffer, LED_COUNT * LED_BIT_COUNT * 2);
}
// 配置DMA通道
void DMA_Config(void)
{
DMA_HandleTypeDef hdma;
// 设置DMA通道和流控制器
hdma.Instance = DMA1_Channel7;
hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma.Init.PeriphInc = DMA_PINC_DISABLE;
hdma.Init.MemInc = DMA_MINC_ENABLE;
hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma.Init.Mode = DMA_CIRCULAR;
hdma.Init.Priority = DMA_PRIORITY_HIGH;
hdma.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma.Init.MemBurst = DMA_MBURST_SINGLE;
hdma.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init(&hdma);
// 配置DMA传输地址和传输模式
HAL_DMA_Start(&hdma, (uint32_t)pwm_buffer, (uint32_t)&TIM2->CCR1, LED_COUNT * LED_BIT_COUNT * 2);
HAL_DMA_PollForTransfer(&hdma, HAL_DMA_FULL_TRANSFER, 1000);
}
// 将PWM数据缓冲区中的数据转换为WS2812B协议的数据格式
void PWM_To_WS2812B(void)
{
uint32_t i, j, k;
uint16_t high, low;
for (i = 0; i < LED_COUNT; i++)
{
for (j = 0; j < LED_BIT_COUNT; j++)
{
k = i * LED_BIT_COUNT + j;
high = (pwm_buffer[k] & 0x8000) ? 40 : 20;
low = (pwm_buffer[k] & 0x8000) ? 20 : 40;
pwm_buffer[k * 2] = high;
pwm_buffer[k * 2 + 1] = low;
}
}
}
int main(void)
{
HAL_Init();
TIM_Config();
DMA_Config();
// 将PWM数据缓冲区中的数据转换为WS2812B协议的数据格式
PWM_To_WS2812B();
while (1)
{
// 启动DMA传输和PWM输出
HAL_DMA_Start(&hdma, (uint32_t)pwm_buffer, (uint32_t)&TIM2->CCR1, LED_COUNT * LED_BIT_COUNT * 2);
HAL_DMA_PollForTransfer(&hdma, HAL_DMA_FULL_TRANSFER, 1000);
}
}
```
阅读全文