标题: STC8系列单片机WS2812驱动程序 [打印本页]

作者: 田贺    时间: 2021-1-11 23:02
标题: STC8系列单片机WS2812驱动程序
依照STC-Y6指令集编写,编译时Keil优化选项默认,理论上STC8全系列通用。
只需配置IO口和系统工作时钟即可使用,系统时钟目前适配范围为5.5296-48MHz。
STC8H8K64S4U@12.0MHz驱动效果如下图:
(分别点亮三个灯,颜色为B,G,R)


主要使用的单字节数据发送函数如下:

  1. #include "ws2812.h"

  2. void WS2812_SendByte(unsigned char dat)
  3. {
  4.     unsigned char i = 8;
  5.     dat <<= 1;
  6.     while (i)
  7.     {
  8.         WS2812_IO = 1;

  9.         //5.5296 - 6.8
  10.         #if SYS_FREQ < 55296 || SYS_FREQ > 480000
  11.         #error 频率未适配, 不在 5.5296-48MHz
  12.         #else
  13.         _nop_();
  14.         #endif

  15.         //6.8 - 10.8
  16.         #if SYS_FREQ >= 68000
  17.         _nop_();
  18.         #endif

  19.         //10.8 – 21.4
  20.         #if SYS_FREQ >= 108000
  21.         _nop_();
  22.         _nop_();
  23.         #endif

  24.         //21.4 – 29.5
  25.         #if SYS_FREQ >= 214000
  26.         _nop_();
  27.         _nop_();
  28.         #endif

  29.         //29.5 – 35.0
  30.         #if SYS_FREQ >= 295000
  31.         _nop_();
  32.         _nop_();
  33.         #endif

  34.         //35.0 – 40.7
  35.         #if SYS_FREQ >= 350000
  36.         _nop_();
  37.         _nop_();
  38.         #endif

  39.         //40.7 – 46.8
  40.         #if SYS_FREQ >= 407000
  41.         _nop_();
  42.         _nop_();
  43.         #endif

  44.         //46.8 – 48
  45.         #if SYS_FREQ >= 468000
  46.         _nop_();
  47.         _nop_();
  48.         #endif

  49.         WS2812_IO = CY;
  50.         //5.5296 - 6.8
  51.         #if SYS_FREQ < 55296 || SYS_FREQ > 480000
  52.         #error 频率未适配
  53.         #else
  54.         _nop_();
  55.         #endif

  56.         //6.8 - 10.8
  57.         #if SYS_FREQ >= 68000
  58.         _nop_();
  59.         #endif

  60.         //10.8 – 21.4
  61.         #if SYS_FREQ >= 108000
  62.         _nop_();
  63.         _nop_();
  64.         #endif

  65.         //21.4 – 29.5
  66.         #if SYS_FREQ >= 214000
  67.         _nop_();
  68.         _nop_();
  69.         #endif

  70.         //29.5 – 35.0
  71.         #if SYS_FREQ >= 295000
  72.         _nop_();
  73.         _nop_();
  74.         #endif

  75.         //35.0 – 40.7
  76.         #if SYS_FREQ >= 350000
  77.         _nop_();
  78.         _nop_();
  79.         #endif

  80.         //40.7 – 46.8
  81.         #if SYS_FREQ >= 407000
  82.         _nop_();
  83.         _nop_();
  84.         #endif

  85.         //46.8 – 48
  86.         #if SYS_FREQ >= 468000
  87.         _nop_();
  88.         _nop_();
  89.         #endif
  90.         WS2812_IO = 0;
  91.         dat <<= 1;
  92.         i--;
  93.     }
  94. }

  95. void Send_WS2812RGB(unsigned char r, unsigned char g, unsigned char b)
  96. {
  97.     WS2812_SendByte(g);
  98.     WS2812_SendByte(r);
  99.     WS2812_SendByte(b);
  100. }

  101. void Send_WS2812(unsigned long dat)
  102. {
  103.     WS2812_SendByte(dat >> 8 & 0xff);
  104.     WS2812_SendByte(dat >> 16 & 0xff);
  105.     WS2812_SendByte(dat & 0xff);
  106. }
复制代码
附测试样例:
WS2812.zip (18.51 KB, 下载次数: 268)

作者: helennew717    时间: 2021-1-12 12:49
方式不错
作者: 人人学会单片机    时间: 2021-1-15 20:58
一开始就移位了,你确定这样数据不出错吗?
作者: 1436405015    时间: 2021-1-20 17:54
如何点亮单个灯呢
作者: 田贺    时间: 2021-1-21 17:22
人人学会单片机 发表于 2021-1-15 20:58
一开始就移位了,你确定这样数据不出错吗?

数据是完整的,用了CY位存储的位移结果,其他运算在数据传输的循环里也不会影响CY。
这是传送了一字节的0x55的波形:


作者: 田贺    时间: 2021-1-21 17:23
1436405015 发表于 2021-1-20 17:54
如何点亮单个灯呢

送几个数据点几个灯
作者: 冬天的野狼    时间: 2021-1-24 21:06
这样的LED在颜色不变时,亮度怎么调呢
作者: suqianfu    时间: 2021-3-4 01:19
冬天的野狼 发表于 2021-1-24 21:06
这样的LED在颜色不变时,亮度怎么调呢

RGB颜色 0-255级别亮度。0就是不亮。0,0,0就是三个颜色都灭了。
作者: eastwife    时间: 2021-11-1 17:19
冬天的野狼 发表于 2021-1-24 21:06
这样的LED在颜色不变时,亮度怎么调呢

按楼主程序,比如开始你是绿色最亮:
  1. Send_WS2812RGB(255,0,0);
复制代码

调整到一半亮度就是255/2=128:
  1. Send_WS2812RGB(128,0,0);
复制代码

作者: Berri    时间: 2022-4-19 14:54
eastwife 发表于 2021-11-1 17:19
按楼主程序,比如开始你是绿色最亮:

调整到一半亮度就是255/2=128:

可是例如RGB(255,255,255)的白色调到一半(128,128,128)变成了灰色,它颜色改变了呀,请问可以不改变颜色只改变亮度吗
作者: 雪玉寐影    时间: 2022-5-31 07:30
Berri 发表于 2022-4-19 14:54
可是例如RGB(255,255,255)的白色调到一半(128,128,128)变成了灰色,它颜色改变了呀,请问可以不 ...

白色变暗,那不就是灰色吗?
作者: kxcuser    时间: 2022-5-31 08:48
刚好前段时间也有弄这个,下载下来参考参考
作者: 快乐眼泪    时间: 2023-4-10 21:15
真在研究这个,谢谢!
作者: maijinzhi    时间: 2023-11-22 09:19
如何点亮单个灯呢
作者: 指北针    时间: 2023-11-26 10:12
想法不错,一会儿测试一下
作者: lihappy    时间: 2023-12-13 17:18
这是IO口点的?




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1