/WS2812-L073-CubeMX

STM32使用SPI驱动WS2812灯珠

Primary LanguageC

WS2812-L073-CubeMX

软件环境

  • CubeMX生成基础框架

    • 对应文件为 ./WS2812-L073-CubeMX.ioc
  • VSCode作为编辑器

    • 对应文件为 ./.vscode/*
  • Keil MDK工具链编译

    • 对应文件为 ./MDK-ARM/*

灯环

开发板

  • 开发板型号Nucleo-L073RZ,对应的MCU为STM32L073RZ,32MHz主频

  • 可能输出接口:IO、SPI、PWM、UART、I2C等。当前使用SPI。

方案设计

  • 主频使用最高的32Mhz,则时钟周期T0为31.25ns。考虑灯珠信号,合适的分频数为8(外设ABP1预分频*SPI预分频),即则SPI每一位为250ns。

  • 此时定义灯珠信号每一位bit分别为

    bit_1=0b1110, T1H=750ns, T1L=250ns
    bit_0=0b1000, T0H=250ns, T0L=750ns

  • 考虑到使用SPI, 其MOSI对应的位默认为高,可能导致传输第一位时没有电平拉高的过程,因此修改定义为

    bit_1=0b0111
    bit_0=0b0100

  • 同时在整个发送串末尾增加至少一个低电平数据,以补完整个信号串的完整性

    • 也可以在不修改bit_0和bit_1的情况下,在最前面增加低电平数据
  • 若选用其他MCU或灯珠信号定义,计算方法同理:最终分频出的SPI频率,可组合出对应的T0和T1信号.

方案实现

程序框架

  • CubeMX配置,主频32MHz,SPI对应的外设分频倍数APB1为4

  • 启用SPI1,必须为Master且必须要开启输出,此处选择Transmit Only Master. 预分频为2, 其他不要修改,使用默认.

    • 以上两处分频倍数根据需要设定,只需保证"外设分频倍数*SPI预分频倍数=8"即可).
  • 启用定时器TIM2,Clock Source选择Internal Clock,并自行配置预分频值和自动重载值,以产生一个固定触发的定时中断.

  • 生成代码.于是一个基于HAL库的程序框架便搭建起来了.

WS2812库

  • 自行构建代码以生成对应的字节流,最终可以通过HAL库函数向SPI端口发送即可.本例中的WS2812.h和WS2812.c只是一种方式.

  • 本例中使用的自行构建函数包括全色显示/渐变色显示/色环显示/亮度调整等.

  • 主函数示例为:

    • 使用WS2812_Init()生成一个控制对象
    • 启用定时器中断, 每次中断时使用WS2812_HueCircle()对对象染色,并通过SPI发送给灯珠.
    • 由于每次染色的位置都偏差一个LED,最终形成旋转的Hue色环.

其他

  • 本工程为纯功能测试,未对代码做任何优化, 全部代码仅做参考