实验环境:

KEIL5、正点原子阿波罗STM32F767开发板

一、灯带介绍

过多介绍我这里不赘述了,想了解详情的可以看看手册,直接开干。

1.1、灯带连接方式

我们只要控制DIN端就好了。

1.2、传输数据方式

简单理解就是单总线发了一串数据,第一个灯拿了第一个字节的数据,第二个灯拿个第二个字节的数据,以此类推。

1.3、控制时序

代码就照这个时序写,因为例程中没有没有纳秒级别的延迟函数,所以我们要根据自己芯片去写。

我用的晶振是216M,一个 __nop() 计算方式为:1 / 216MHz ≈ 0.0046us = 4.6ns 。
根据这个就可以写纳秒(ns)级别的函数了。

二、程序介绍

2.1、WC2812B.c

/************************************************************
@Description: WS2812B全彩LED灯驱动
***********************************************************/
#include "WS2812B.h"
#include "delay.h"Color_TypeDef PixelBuf[PIXEL_NUM]; //像数数据
uint8_t flag;
Color_TypeDef   Color_Prar;
//晶振216M,1/216≈0.004629us=4.6ns
#define delay_4_6ns     __nop()                         //1个nop是4.6ns
#define delay_23ns      delay_4_6ns;delay_4_6ns;delay_4_6ns;delay_4_6ns;delay_4_6ns
#define delay_115ns     delay_23ns;delay_23ns;delay_23ns;delay_23ns;delay_23ns
//T0H
#define delay_391ns     delay_115ns;delay_115ns;delay_115ns;delay_23ns;delay_23ns
//T0L
#define delay_851ns     delay_805ns;delay_23ns;delay_23ns
//T1L
#define delay_460ns     delay_115ns;delay_115ns;delay_115ns;delay_115ns
//T1H
#define delay_805ns     delay_460ns;delay_115ns;delay_115ns;delay_115ns/*---------------------------------------------------------------------------
@Function   :WS2812B_Init
@Description:初始化
----------------------------------------------------------------------------*/
void WS2812B_Init(void)
{GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOB_CLK_ENABLE();           //开启GPIOA时钟GPIO_Initure.Pin=WS2812B_PIN;           //PB1GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输入GPIO_Initure.Pull=GPIO_PULLUP;          //上拉GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速HAL_GPIO_Init(WS2812B_PORT,&GPIO_Initure);HAL_GPIO_WritePin(WS2812B_PORT,WS2812B_PIN,GPIO_PIN_SET);    //PB1置1
}
/*---------------------------------------------------------------------------
@Function   :WS2812B_Reset
@Description:复位
----------------------------------------------------------------------------*/
void WS2812B_Reset(void)          //复位函数
{WS2812B_Low();delay_us(300);
}/*---------------------------------------------------------------------------
@Function   :WS2812B_WriteByte
@Description:写一个字节
----------------------------------------------------------------------------*/
void WS2812B_WriteByte(uint8_t dat)
{u8 i;for (i=0;i<8;i++){//先发送高位if (dat & 0x80) //1{WS2812B_Hi();delay_805ns;  //T1HWS2812B_Low(); delay_460ns; //T1L}else //0{WS2812B_Hi();delay_391ns; //T0HWS2812B_Low();   delay_851ns; //T0L}dat<<=1;}
}/*---------------------------------------------------------------------------
@Function   :RGB_LED_Write_24Bits
@Description:写入1个24bit颜色数据
----------------------------------------------------------------------------*/
void RGB_LED_Write_24Bits(uint8_t green, uint8_t red, uint8_t blue)
{WS2812B_WriteByte(green);WS2812B_WriteByte(red);WS2812B_WriteByte(blue);WS2812B_Reset();
}/*---------------------------------------------------------------------------
@Function   :RGB_LED_Red
@Description:写入1红色数据
@Input      :无
@Retrun     :无
@Others     :
----------------------------------------------------------------------------*/
void RGB_LED_Red(void)
{uint8_t i;for (i = 0; i < 1; i++){RGB_LED_Write_24Bits(0, 0xff, 0);}
}/*---------------------------------------------------------------------------
@Function   :RGB_LED_Green
@Description:写入1绿色数据
----------------------------------------------------------------------------*/
void RGB_LED_Green(void)
{uint8_t i;for (i = 0; i < 1; i++){RGB_LED_Write_24Bits(0xff, 0, 0);}
}/*---------------------------------------------------------------------------
@Function   :RGB_LED_Blue
@Description:写入1蓝色数据
----------------------------------------------------------------------------*/
void RGB_LED_Blue(void)
{uint8_t i;for (i = 0; i < 1; i++){RGB_LED_Write_24Bits(0, 0, 0xff);}
}/*---------------------------------------------------------------------------
@Function   :WS2812B_WriteColor
@Description:写入1个24bit颜色数据
----------------------------------------------------------------------------*/
void WS2812B_WriteColor(Color_TypeDef *pColor)
{WS2812B_WriteByte(pColor->G);WS2812B_WriteByte(pColor->R);WS2812B_WriteByte(pColor->B);
}/*---------------------------------------------------------------------------
@Function   :WS2812B_RefreshPixel
@Description:更新显示
@Input      :无
@Retrun     :无
@Others     :
----------------------------------------------------------------------------*/
void WS2812B_RefreshPixel(void)
{u8 i;for(i=0;i<PIXEL_NUM;i++){WS2812B_WriteColor(&PixelBuf[i]);}
}
//============================================================================
void Copy_Color(Color_TypeDef *pDst,Color_TypeDef *pScr)
{pDst->R = pScr->R;pDst->G = pScr->G;pDst->B = pScr->B;
}/*---------------------------------------------------------------------------
@Function   :WS2812B_FillColor
@Description:填充颜色
@Input      :start:开始位置;end:结束信置;pColor:颜色值
@Retrun     :无
@Others     :
----------------------------------------------------------------------------*/
void WS2812B_FillColor(u16 start,u16 end,Color_TypeDef *pColor)
{if (start > end) //交换位置{u16 temp;temp = start;start = end;end = temp;}if (start >= PIXEL_NUM)return; //超出范围if (end >= PIXEL_NUM)end = PIXEL_NUM-1;//填充颜色值while(start <= end){Copy_Color(&PixelBuf[start],pColor);start++;}
}/*---------------------------------------------------------------------------
@Function   :WS2812B_All_Blue
@Description:点亮全部灯带显示为蓝色
----------------------------------------------------------------------------*/
void WS2812B_All_Blue(u8 num)
{Color_Prar.G = 0x00;Color_Prar.R = 0x00;Color_Prar.B = 0xff;WS2812B_FillColor(0,num,&Color_Prar);
}
void WS2812B_All_Red(u8 num)    //全红
{Color_Prar.G = 0x00;Color_Prar.R = 0xff;Color_Prar.B = 0x00;WS2812B_FillColor(0,num,&Color_Prar);
}
void WS2812B_All_Green(u8 num)  //全绿
{Color_Prar.G = 0xff;Color_Prar.R = 0x00;Color_Prar.B = 0x00;WS2812B_FillColor(0,num,&Color_Prar);
}void WS2812B_All_Yellow(u8 num)    //全黄
{Color_Prar.G = 0xff;Color_Prar.R = 0xff;Color_Prar.B = 0x00;WS2812B_FillColor(0,num,&Color_Prar);
}

2.2、WS2812.h

/************************************************************
@Description: WS2812B全彩LED灯驱动
***********************************************************/
#ifndef __WS2812B_H
#define __WS2812B_H
#include "sys.h"//WS2812B IO 定义  注意初始化APB时钟也要修改
#define WS2812B_PORT        GPIOB
#define WS2812B_PIN         GPIO_PIN_1
#define WS2812B_RCC_AHB     __HAL_RCC_GPIOB_CLK_ENABLE()           //开启GPIOB时钟#define WS2812B_Hi()  HAL_GPIO_WritePin(WS2812B_PORT,WS2812B_PIN,GPIO_PIN_SET)
#define WS2812B_Low()   HAL_GPIO_WritePin(WS2812B_PORT,WS2812B_PIN,GPIO_PIN_RESET)
//颜色
typedef struct color{u8 G;u8 R;u8 B;
}Color_TypeDef;//------------------------
#define PIXEL_NUM   60  //LED灯的个数void WS2812B_Init(void);
void WS2812B_Reset(void);
void WS2812B_WriteColor(Color_TypeDef *pColor);void RGB_LED_Write_24Bits(uint8_t green, uint8_t red, uint8_t blue);
void RGB_LED_Red(void);
void RGB_LED_Green(void);
void RGB_LED_Blue(void);void WS2812B_RefreshPixel(void);
void WS2812B_FillColor(u16 start,u16 end,Color_TypeDef *pColor);void WS2812B_All_Blue(u8 num);
void WS2812B_All_Red(u8 num);
void WS2812B_All_Green(u8 num);
void WS2812B_All_Yellow(u8 num);
#endif

2.3、KEY.c

#include "key.h"
#include "delay.h"
#include "WS2812B.h"//按键初始化函数
void KEY_Init(void)
{GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟__HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟__HAL_RCC_GPIOH_CLK_ENABLE();           //开启GPIOH时钟GPIO_Initure.Pin=GPIO_PIN_0;            //PA0GPIO_Initure.Mode=GPIO_MODE_INPUT;      //输入GPIO_Initure.Pull=GPIO_PULLDOWN;        //下拉GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速HAL_GPIO_Init(GPIOA,&GPIO_Initure);GPIO_Initure.Pin=GPIO_PIN_13;           //PC13GPIO_Initure.Mode=GPIO_MODE_INPUT;      //输入GPIO_Initure.Pull=GPIO_PULLUP;          //上拉GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速HAL_GPIO_Init(GPIOC,&GPIO_Initure);GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3; //PH2,3HAL_GPIO_Init(GPIOH,&GPIO_Initure);
}//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,WKUP按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!!
u8 KEY_Scan(u8 mode)
{static u8 key_up=1;     //按键松开标志if(mode==1)key_up=1;    //支持连按if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1)){delay_ms(10);key_up=0;if(KEY0==0)       return KEY0_PRES;else if(KEY1==0)  return KEY1_PRES;else if(KEY2==0)  return KEY2_PRES;else if(WK_UP==1) return WKUP_PRES;          }else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;return 0;   //无按键按下
}void KEY_LED_Control(void)
{switch(KEY_Scan(0)){case KEY0_PRES:{WS2812B_All_Blue(30);delay_ms(100);WS2812B_RefreshPixel();     //更新显示}break;case KEY1_PRES:{WS2812B_All_Red(30);delay_ms(100); WS2812B_RefreshPixel();     //更新显示}break;case KEY2_PRES:{WS2812B_All_Green(30);delay_ms(100);WS2812B_RefreshPixel();        //更新显示}break;case WKUP_PRES:{WS2812B_All_Yellow(30);delay_ms(100);WS2812B_RefreshPixel();       //更新显示}break;}
}

2.4、KEY.h

#ifndef _KEY_H
#define _KEY_H
#include "sys.h"#define KEY0        HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3)  //KEY0按键PH3
#define KEY1        HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2)  //KEY1按键PH2
#define KEY2        HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13) //KEY2按键PC13
#define WK_UP       HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)  //WKUP按键PA0#define KEY0_PRES    1
#define KEY1_PRES   2
#define KEY2_PRES   3
#define WKUP_PRES   4void KEY_Init(void);
u8 KEY_Scan(u8 mode);
void KEY_LED_Control(void);#endif

2.5、main.c

#include "sys.h"
#include "delay.h"
#include "key.h"
#include "WS2812B.h"int main(void)
{Cache_Enable();                 //打开L1-CacheHAL_Init();                        //初始化HAL库Stm32_Clock_Init(432,25,2,9);   //设置时钟,216Mhz delay_init(216);                //延时初始化KEY_Init();                       //按键初始化WS2812B_Init();                  //灯带控制IO口初始化while(1){       KEY_LED_Control();  //由此按钮函数控制切换红、绿、蓝、黄四种颜色}
}

遇到的问题

灯带是点亮了,也能控制切换,但是,灯带受外部干扰也很强,不控制的情况下,也可能会不受控制的点亮。

文章参考:

闲来无事,搞了条WS2812B全彩灯带玩一下,驱动程序借助以下两篇文章的大佬的程序修改。
https://blog.csdn.net/Lennon8_8/article/details/108980808
https://blog.csdn.net/weixin_53411486/article/details/127246513
做实验前结合这两位仁兄的贴子,感谢两位大佬。

附带代码连接

有遇到相同实验环境的情况的伙伴,也可以直接使用这份代码实验一下。
https://download.csdn.net/download/weixin_41569625/87452923

WS2812B灯带驱动实验相关推荐

  1. STM32F427库函数PWM+DMA控制ws2812b灯带

    STM32F427IIHx库函数PWM+DMA控制ws2812b灯带 一.参考资料 查看ws2812b用户手册可知: 二.代码部分 添加文件ws2812b.c,ws2812b.h 配置的F427IIH ...

  2. ws2812b灯带容易坏_吊灯吸顶灯筒灯壁灯射灯灯带LED线条灯……都是个啥?

    装修时,灯具作为照明工具,自然是必不可少的装修建材.然而灯具的种类非常多,吊灯.吸顶灯.筒灯.射灯.壁灯.线灯等等,各种灯具琳琅满目,作用也各有不同.不过提醒业主们在选购时,一定要关注灯具的质量.外观 ...

  3. ws2812b灯带容易坏_WS2812灯带问题

    大神,能帮忙看一下吗?非常感谢! [mw_shl_code=arduino,true]#include #include //strip #define PIN   2 #define MAX_LED ...

  4. 【流光溢彩】物联网入门 - ESP8266 + WS2812B 制作流光溢彩灯带

    一.硬件准备 ESP8266 模块 x1 WS2812B 灯带(60/米,根据显示器四周长度买即可) x1 杜邦线 若干 DC 电源 x1 二.软件准备 1. ESP8266 串口驱动 一般购买详情页 ...

  5. 驱动RGB灯带MCU阐述

    驱动RGB灯带MCU推荐 本文仅分享个人工作中积累的经验,无任何商业行为,若有更好的方案欢迎交流共同进步. 一.RGB灯带驱动IC简介 市面上存在多种RGB驱动IC,比如:WS2812,YX1903B ...

  6. wifi智能氛围灯esp8266,ws2812灯带

    没有录视频就直接上图吧,还是挺好看的. 硬件设备:esp8266nodemcu开发板(32也是可以的),ws2812灯带工3米共90灯珠,电源模块and杜邦线 需要用到blinker库,esp8266 ...

  7. FPGA驱动RGB灯带WS2812B

    记录一下短学期做的东西 -- FPGA驱动RGB灯带WS2812B 设计目标 1.有多种模式,按键调节模式等参数: 2.模式1:红绿蓝白四色循环显示,速度.亮度可调: 3.模式2:7彩虹+白色,闪烁, ...

  8. Linux 自带的 LED 灯驱动实验

    目录 一.配置内核 二.设备树节点编写 1.确定compatible 属性值 2.编写节点 三.验证 测试 其实 Linux 内核已经自带了 LED 灯驱动,要使用 Linux 内核自带的 LED 灯 ...

  9. Linux 自带的LED 灯驱动实验

    目录 Linux 内核自带LED 驱动使能 Linux 内核自带LED 驱动简介 LED 灯驱动框架分析 module_platform_driver 函数简析 gpio_led_probe 函数简析 ...

最新文章

  1. python上海培训哪里比较好-上海培训python一般多少钱?
  2. 爱情,这种高级玩意儿--一个码农的自白
  3. 翻译器DIY它———算在英文文本中的单词数,字符和行数
  4. (三)Linux查看和修改文件权限
  5. UE3 使用光源函数
  6. 优化mysql的21个建议_MySQL优化小建议
  7. android 如何实现多级树形结构图(至少5级)
  8. 【Data guard】Switchover切换
  9. Bailian3470 整理扑克牌【贪心+二分】
  10. Spelling, Edit Distance, and Noisy Channels 拼写、编辑距离和噪声通道
  11. 软工文档-操作手册和用户手册的区别
  12. gp数据库与pg数据库
  13. 【已成功安装但无法使用】Python 3.10.2 安装pyodbc
  14. 什么是CSS hack及写法
  15. 图像可视化——matplotlib绘图入门基础
  16. 【阿朱洞察】中国大数据行业的下一步走向
  17. 位于0/nut文件里的'Calculated'边界条件是什么意思?【翻译】
  18. 如何在VMware虚拟机上安装运行Mac OS系统(详细图文教程)
  19. ai绘画小程序源码1.3更新版
  20. 当h5页面横向不能滚动,如何优雅的显示表格数据

热门文章

  1. 使用easygui制作app
  2. python处理PPOCRLabel标注的数据用于LPRNet与Yolo的训练
  3. mac系统启动spring项目报错
  4. Ajax之父Jesse James Garrett在adaptive path工作坊上的演讲《用户体验的要素》
  5. DISPO与EKGRP 的关系(MRP控制者和采购组)
  6. C++ 引用作为函数返回值
  7. 如何将SQL语句进行自动翻译
  8. 最短路算法 :Bellman-ford算法 Dijkstra算法 floyd算法 SPFA算法 详解
  9. flutter中的可选参数
  10. adobe reader java_请问,如何用JAVA读PDF文件在浏览器中显示,不需要在本地系统中安装Adobe Reader。求java代码...