使用STM32CubeIDE软件写个stm32G030F6P6驱动ws2812灯的程序,简单易懂,中文详细注释
时间: 2023-12-12 16:04:53 浏览: 133
使用RT-Thread RTOS 基于STM32G030F6 最小系统板的 ws2812 驱动工程
好的,下面是一个简单的例程,使用STM32CubeIDE软件,驱动WS2812灯。
1. 创建STM32CubeIDE工程
首先创建一个STM32CubeIDE工程,选择对应的开发板和芯片型号(本例中选择的是STM32G030F6P6)。在项目配置中,选择HAL库作为底层驱动。
2. 配置时钟
配置时钟,使得时钟频率为72MHz。
```c
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
uint32_t pFLatency = 0;
/* Configure the main internal regulator output voltage */
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Initializes the CPU, AHB and APB busses clocks */
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_MUL6;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Initializes the CPU, AHB and APB busses clocks */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
pFLatency = FLASH_LATENCY_1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK)
{
Error_Handler();
}
```
3. 配置GPIO
配置GPIO口,使得可以控制WS2812灯的数据引脚。本例中使用PA2口作为数据引脚。
```c
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
/*Configure GPIO pin : PA2 */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
```
4. 驱动WS2812灯
驱动WS2812灯的原理是通过发送一定的时间序列来控制灯的颜色。在本例中,我们使用的是PWM协议。具体的时间序列如下表所示:
| 逻辑0 | 逻辑1 |
|-------|-------|
| 0.35us | 0.8us |
| 0.8us | 0.35us |
根据这个时间序列,我们可以编写一个函数来驱动WS2812灯。
```c
void setLed(uint8_t r, uint8_t g, uint8_t b)
{
uint8_t i;
//将RGB值转换为PWM时间序列
uint32_t pwm_buf[24];//24个bit
for(i=0;i<8;i++)
{
if(r & (1<<i))
{
pwm_buf[i] = 0.8*72000000/1000000;
}
else
{
pwm_buf[i] = 0.35*72000000/1000000;
}
}
for(i=0;i<8;i++)
{
if(g & (1<<i))
{
pwm_buf[i+8] = 0.8*72000000/1000000;
}
else
{
pwm_buf[i+8] = 0.35*72000000/1000000;
}
}
for(i=0;i<8;i++)
{
if(b & (1<<i))
{
pwm_buf[i+16] = 0.8*72000000/1000000;
}
else
{
pwm_buf[i+16] = 0.35*72000000/1000000;
}
}
//发送PWM信号
for(i=0;i<24;i++)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
//延时
for(uint32_t j=0;j<pwm_buf[i];j++);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
//延时
for(uint32_t j=0;j<pwm_buf[i];j++);
}
}
```
在主函数中,我们可以使用这个函数来控制WS2812灯的颜色。
```c
int main(void)
{
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* Infinite loop */
while (1)
{
setLed(255, 0, 0); //红色
HAL_Delay(1000);
setLed(0, 255, 0); //绿色
HAL_Delay(1000);
setLed(0, 0, 255); //蓝色
HAL_Delay(1000);
}
}
```
这样,就可以通过控制WS2812灯的数据引脚,来实现灯的颜色控制了。
阅读全文