【WS2812】使用STM32G0的LL库通过GPIO方式控制WS2812

需求--控制一个WS2812灯的功能。

一、0和1码的时序

二、原理

通过控制GPIO口的电平变化,可以实现对WS2812的亮度和颜色的控制。

WS2812的控制原理如下:

  1. WS2812的数据传输采用单线传输方式,即数据线同时传输控制信号和数据信号。
  2. 控制信号是由特定的时间序列组成的,用来标识数据信号的开始和结束。
  3. 数据信号是由一系列的高电平和低电平脉冲组成的,每个脉冲的宽度表示一个bit的数值。
  4. 一个bit的数值由高电平和低电平脉冲的宽度比例来表示,通常高电平表示逻辑1,低电平表示逻辑0。
  5. 通过连续发送一系列的bit数据,可以实现对WS2812的亮度和颜色的控制。

具体控制WS2812的步骤如下:

  1. 将控制信号和数据信号发送到WS2812的数据线上。
  2. 发送控制信号,标识数据信号的开始。
  3. 依次发送每个LED的RGB颜色数据,通常是以GRB的顺序发送。
  4. 发送控制信号,标识数据信号的结束。

通过控制GPIO口的电平变化,可以实现对WS2812的亮度和颜色的控制。具体的电平变化方式和时间序列需要根据WS2812的规格来确定。

三、编写控制函数

void WS2812_Init(void)
{
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);

  /**/
  LL_GPIO_ResetOutputPin(DOUT_GPIO_Port, DOUT_Pin);

  /**/
  GPIO_InitStruct.Pin = DOUT_Pin;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  LL_GPIO_Init(DOUT_GPIO_Port, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}




/**
  * @brief 设置单个颜色
  * @retval None
  */
void ws2812SetRGB(uint32_t value)
{
	uint8_t cnt = 0;
	LL_GPIO_ResetOutputPin(DOUT_GPIO_Port, DOUT_Pin);
	LL_mDelay(1);
	
	for(cnt = 0; cnt < 24; cnt++)
	{
		if(((value>>cnt)&0x000001) == 1)
			ws2812WriteOne();
		else
			ws2812WriteZero();
	}
	
	LL_GPIO_ResetOutputPin(DOUT_GPIO_Port, DOUT_Pin);
	LL_mDelay(1);
}




/**
  * @brief 48MHz的周期为1/48MHz,即20.83 ns。高电平0.25us 低电平1us
	*        一个nop 20ns;两个nop100ns;三个nop120ns;四个nop170ns;六个nop210ns
	*         十二个nop420ns;二十四个nop720ns;三十六个nop1.04us
  * @retval None
  */
void ws2812WriteZero(void)
{
	LL_GPIO_SetOutputPin(DOUT_GPIO_Port, DOUT_Pin);
	__NOP();__NOP();__NOP();

	LL_GPIO_ResetOutputPin(DOUT_GPIO_Port, DOUT_Pin);
	__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();
	__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();
	__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();
}


/**
  * @brief 48MHz的周期为1/48MHz,即20.83 ns。高电平0.85us 低电平0.4us
	*        一个nop 20ns;两个nop100ns;三个nop120ns;四个nop170ns;六个nop210ns;十一个nop为400ns;
	*         十二个nop420ns;二十四个nop720ns;三十个nop为840ns;三十六个nop1.04us
  * @retval None
  */
void ws2812WriteOne(void)
{
	LL_GPIO_SetOutputPin(DOUT_GPIO_Port, DOUT_Pin);
	__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();
	__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();
	__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();
	
	LL_GPIO_ResetOutputPin(DOUT_GPIO_Port, DOUT_Pin);
	__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值