[STM32] 硬件太丑,B格不够,只好彩灯来凑--STM32F103 SPI驱动WS2812

本文介绍了如何利用STM32F103微控制器通过SPI DMA控制WS2812全彩灯环,详细阐述了WS2812灯珠的工作原理和时序,并展示了使用Adafruit_NeoPixel库实现的各种炫酷显示效果。通过精确的SPI通信设置,确保了数据传输的及时性和准确性,实现了华丽的灯光效果。
摘要由CSDN通过智能技术生成

之前发了一个基于涂鸦平台的宠物自动喂食器已经有小夜灯功能了但是躁动的心岂能因此平静,功能以及花里胡哨,那就让他华丽起来,除了画手们的涂装风格,作为电子工程师,得用我们自己的方式美化。正好手里有个ws2812的灯环,全彩模式开始。
WS2812特点:
1.WS2812灯珠内置控制电路与RGB芯片,集成在一个5050封装的元器件中,构成一个完整的外控像素点。
2.每个像素点的三基色可实现256级亮度显示,完成16777216种颜色的全真色彩显示,扫描频率不低于400Hz/s。
3.串行级联接口,能通过一根信号线完成数据的接收与解码。
4.当刷新速率30帧/秒时,低速模式级联数不小于512点,高速模式不小于1024点。
5.数据发送速度可达800Kbps。
数据传输:
ws2812的每颗灯珠的控制需要24位数据,分为8位绿色+8位红色+8位蓝色,每个像素点的三基色颜色可实现256级亮度显示,完成16777216种颜色的全真色彩显示。灯珠之间采用串行级联,在上电复位以后,控制器可向灯带发送一串24bit的数据,比如需要点亮10颗灯,我们发送10个24bit的数据到第一个灯,第一个灯的DIN端接受控制器发过来的24bit数据,第一个灯珠会提取第一个24bit数据后会将该数据送进数据锁存器,剩余的数据经过内部整形电路向下传送,直到所有的灯都获取一个24bit数据。这10个24bit数据的发送间隔不能超过50us,否则会导致下一次的颜色数据被第一个重新锁存,就无法完成完整的点亮。
这里需要着重点一下时序相关的知识,先看时序波形图和数据传输时间表:

 
根据上面两个图可以看到ws2812的电平反转是纳秒级别的,所以在使用单片机外设时我们需要对单片机的外设的传输速度进行控制,速度慢了根本无法点亮。
操作开始:
在驱动ws2812的时候一般采用PWM或者SPI的方式,这两个速度较快,比直接使用IO口进行电平反转要方便,且控制效果更好。这里我们采用SPI的方式,因为在点灯是的数据发送间隔时间的约束,如果我们使用SPI发送的数据较多,中途遇到中断可能会打断我们的点灯,所以我这里使用SPI的DMA进行控制,不怕被其他影响。

通过硬件SPI我们模拟WS2812的通信时序。单片机选用STM32F103,主频72M,SPI1分频设置为8,这样SPI1的通信频率为9M。时间很充足,如果使用SPI2,则需要减小分频系数,否则无法点亮。我这里采用的便是SPI2,4分频,因为SPI1被我的屏幕占用了。
.h文件只要定义了灯珠的个数和0码1码。不同的灯珠数量只需修改PIXEL_NUM 的值。

复制

const char s[5];

int8_t i;



int main(void)

{

//  usart1_init(115200);

  delay_init();



  ws281x_init();

 

  while(1)

  {

     // Some example procedures showing how to display to the pixels:

  ws281x_colorWipe(ws281x_color(255, 0, 0), 50); // Red

  ws281x_colorWipe(ws281x_color(0, 255, 0), 50); // Green

  ws281x_colorWipe(ws281x_color(0, 0, 255), 50); // Blue

//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW

  // Send a theater pixel chase in...

  ws281x_theaterChase(ws281x_color(127, 127, 127), 50); // White

  ws281x_theaterChase(ws281x_color(127, 0, 0), 50); // Red

  ws281x_theaterChase(ws281x_color(0, 0, 127), 50); // Blue



  //ws281x_rainbow(20);

  ws281x_rainbowCycle(20);

  ws281x_theaterChaseRainbow(200);

    

    for(i = 0; i < PIXEL_NUM; ++i)

  {

    ws281x_setPixelColor(i, ws281x_color(0,250,0));

    ws281x_show();

    delay_ms(500);

  }

  }

}

在ws2812.c移植了Adafruit_NeoPixel库的部分函数,用以实现炫酷的显示效果。
都是基础的SPI,不说废话,移植就能用。展示一下效果吧!

---------------------
作者:呐咯密密
链接:https://bbs.21ic.com/icview-3122082-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值