嵌入式学习(30)-STM32F103 WS2812驱动

一、概述

        背景:之前在STM32F407的平台是实现了WS2812的驱动,今天移植到STM32F103的平台发现WS2812无法驱动点亮。最终找到了原因:是GPIO模拟时序的原因。

二、过程记录

WS2812的读写时序电平就两种,参考的时序是

 代码实现如下

其中GPIO高低电平的实现是通过hal库实现的

#define WS2812_LED(x)   do{ x ? \
                      HAL_GPIO_WritePin(WS2812_GPIO_PORT, WS2812_GPIO_PIN, GPIO_PIN_SET) : \
                      HAL_GPIO_WritePin(WS2812_GPIO_PORT, WS2812_GPIO_PIN, GPIO_PIN_RESET); \
                  }while(0)       /* LED0 = RED */

测试发现一个电平的反转周期大约就是0.4us,所以如果需要延时0.4us的话就不需要插入延时函数了。

按照上述情况修改了延时控制可以驱动WS2812了,但是程序在加入新功能的时候,灯的显示并不是想要驱动的样子而是全亮。如下图所示框选延时是必须要有的。

查找了一些资料,发现WS2812的时序有多种:

ws2812驱动总结(包括对时序的详细分析,代码基于STC15系列单片机)_ws2812时序-优快云博客

上述的代码就是类似参考的这种。

三、优化改善

STM32F103使用 hal库操作GPIO占用时间大约是0.4us,为了缩短这个时间我们可以考虑直接操作寄存器的方式,先看下Hal关于GPIO的操作代码:

void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  assert_param(IS_GPIO_PIN_ACTION(PinState));

  if (PinState != GPIO_PIN_RESET)
  {
    GPIOx->BSRR = GPIO_Pin;
  }
  else
  {
    GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
  }
}

 更新后的代码如下:

/* LED端口定义 */
//#define WS2812_LED(x)   do{ x ? \
//                      HAL_GPIO_WritePin(WS2812_GPIO_PORT, WS2812_GPIO_PIN, GPIO_PIN_SET) : \
//                      HAL_GPIO_WritePin(WS2812_GPIO_PORT, WS2812_GPIO_PIN, GPIO_PIN_RESET); \
//                  }while(0)       /* LED0 = RED */
/*方式一*/			  
#define WS2812_LED(x) do { \
    if (x) { \
        GPIOB->BSRR = WS2812_GPIO_PIN; \
    } else { \
        GPIOB->BSRR = (uint32_t)WS2812_GPIO_PIN << 16u; \
    } \
} while(0)				  
/*方式二:*/	
//#define WS2812_LED(x) do { GPIOB->BSRR = (x) ? WS2812_GPIO_PIN : (uint32_t)WS2812_GPIO_PIN << 16u; } while(0)

具体寄存器的操作GPIO的延时时间没有测试,用户可根据测试延时时间去设定延时。

其中BSRR对GPIO的操作不会影响到其他IO的电平,参考链接

[STM32]从零开始的STM32 BSRR、BRR、ODR寄存器讲解_bsrr寄存器-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

剑藏锋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值