找回密码
 立即注册
楼主: 梁工

SPI-DMA输出控制WS2812三基色彩灯程序@8H系列/32G系列,不加反相器, CPU休息

  [复制链接]
  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-8-5 10:02:12 | 显示全部楼层
梁工,请问我用STC8G1K08A的芯片驱动这个WS2812然后接了可能五百个灯,我就想用串口发送灯选择和颜色选择,每次一个灯亮就行应该怎么写呀,看这个代码里面看不懂。就是比如说我发996W,就是第九九六个灯亮白色,亮度就最亮,然后其他的灯都是灭的。可以解惑一下莫

点评

WS2812是一个个往后传数据的,每个灯3个字节,每个灯接收到3个字节就旁路掉数据,之后的数据就往后传。你要点亮第996个灯,前面995个灯也要发数据,不亮就发0x00,要先发995*3个字节,接着发3个字节才是第996个灯的  详情 回复 发表于 2024-8-5 14:50
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2024-8-5 14:50:35 | 显示全部楼层
好学*** 发表于 2024-8-5 10:02
梁工,请问我用STC8G1K08A的芯片驱动这个WS2812然后接了可能五百个灯,我就想用串口发送灯选择和颜色选择, ...

WS2812是一个个往后传数据的,每个灯3个字节,每个灯接收到3个字节就旁路掉数据,之后的数据就往后传。你要点亮第996个灯,前面995个灯也要发数据,不亮就发0x00,要先发995*3个字节,接着发3个字节才是第996个灯的数据。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-8-5 15:02:06 | 显示全部楼层
梁*** 发表于 2024-8-5 14:50
WS2812是一个个往后传数据的,每个灯3个字节,每个灯接收到3个字节就旁路掉数据,之后的数据就往后传。你 ...
  1. #define         MAIN_Fosc                11059200        //定义主时钟
  2. #include        "STC8Hxxx.h"
  3. #include  "intrins.h"
  4. #define                WS2812                P54                //GPIO
  5. #define                LED                1             //灯珠个数
  6. unsigned char RED,GREEN,BLUE;
  7. /*----------------------------延时10us@STC-Y6@11.0592MHz----------------------------*/
  8. void Delay_10us(void)
  9. {
  10.         unsigned char i;
  11.         i=35;
  12.         while(--i);
  13. }
  14. /*----------------------------延时x10us----------------------------*/
  15. void Delay_x10us(unsigned char x)
  16. {
  17.         while(x--)
  18.                 Delay_10us();
  19. }
  20. /*----------------------------延时10ms@STC-Y6@11.0592MHz----------------------------*/
  21. //void Delay_10ms(void)
  22. //{
  23. //        unsigned char i,j;
  24. //        _nop_();
  25. //        _nop_();
  26. //        i=144;
  27. //        j=157;
  28. //        do
  29. //        {
  30. //                while(--j);
  31. //        }while(--i);
  32. //}
  33. /*----------------------------延时x10ms----------------------------*/
  34. //void Delay_x10ms(unsigned char x)
  35. //{
  36. //        while(x--)
  37. //                Delay_10ms();
  38. //}
  39. void WS2812_Reset(void)
  40. {
  41.         WS2812=0;
  42.         Delay_x10us(10);
  43. }
  44. void WS2812_Write_Byte(unsigned char data temp)        //STC-Y6@11.0592MHz 0:375ns+1350ns 1:925ns+1350ns
  45. {
  46.         unsigned char data i=8;
  47.         while(i)
  48.         {
  49.                 temp<<=1;
  50.                 WS2812=1;
  51.                 if(CY)
  52.                 {
  53.                         _nop_();
  54.                         _nop_();
  55.                         _nop_();
  56.                         _nop_();
  57.                         _nop_();
  58.                         _nop_();
  59.                         _nop_();
  60.                         _nop_();
  61.                 }
  62.                 WS2812=0;
  63.                 _nop_();
  64.                 _nop_();
  65.                 _nop_();
  66.                 _nop_();
  67.                 _nop_();
  68.                 _nop_();
  69.                 _nop_();
  70.                 _nop_();
  71.                 i--;
  72.         }
  73. }
  74. unsigned int LED_ON = 5;        //第几个亮
  75. void WS2812_Write(void)
  76. {
  77.         unsigned int i;
  78.         WS2812_Reset();
  79.         i=0;
  80.         while(1)
  81.         {
  82.                 if(i==LED_ON)
  83.                 {
  84.                         WS2812_Write_Byte(GREEN);
  85.                         WS2812_Write_Byte(RED);
  86.                         WS2812_Write_Byte(BLUE);
  87.                         break;
  88.                 }
  89.                 else
  90.                 {
  91.                         WS2812_Write_Byte(0);
  92.                         WS2812_Write_Byte(0);
  93.                         WS2812_Write_Byte(0);
  94.                         i++;
  95.                 }
  96.         }
  97. }
  98. void Init(void)
  99. {
  100.             P5M0 = 0x10;
  101.                                                 P5M1 = 0x00;
  102. }
  103. void main(void)
  104. {
  105.         Init();
  106.         while(1)
  107.         {
  108.                 RED=255;        //红 0~255
  109.                 GREEN=0;        //绿 0~255
  110.                 BLUE=0;        //蓝 0~255
  111.                 WS2812_Write();
  112.         }
  113. }
复制代码


我这样整但他还是全亮,然后颜色也是白色

点评

时序明显不对,发数据位0时全部是高电平,这是不对的。 数据0:高电平0.9us,低电平大于等于0.35us。 数据1:高电平0.3us,低电平大于等于0.95us。  详情 回复 发表于 2024-8-5 16:12
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2024-8-5 16:12:10 | 显示全部楼层
好学*** 发表于 2024-8-5 15:02
我这样整但他还是全亮,然后颜色也是白色

时序明显不对,发数据位0时全部是高电平,这是不对的。
数据0:高电平0.9us,低电平大于等于0.35us。
数据1:高电平0.3us,低电平大于等于0.95us。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-8-5 17:30:06 | 显示全部楼层
梁*** 发表于 2024-8-5 16:12
时序明显不对,发数据位0时全部是高电平,这是不对的。
数据0:高电平0.9us,低电平大于等于0.35us。
数 ...

按照这个要几个nop函数呀,我看百度说12MHZ一个nop()是1微秒,可是我要延时零点几微秒叻
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-8-5 17:35:45 | 显示全部楼层
梁*** 发表于 2024-8-5 16:12
时序明显不对,发数据位0时全部是高电平,这是不对的。
数据0:高电平0.9us,低电平大于等于0.35us。
数 ...
  1. void send_L(void)
  2. {
  3.          WS2812=0;
  4.        _nop_();
  5.        _nop_();
  6.          WS2812=1;
  7.                         _nop_();
  8.                         _nop_();
  9.                         _nop_();
  10.                         _nop_();
  11.                         _nop_();
  12.                         _nop_();
  13.          WS2812=0;
  14. }
  15. void send_H(void)
  16. {
  17.          WS2812=0;
  18.        _nop_();
  19.        _nop_();
  20.        _nop_();
  21.                _nop_();
  22.        _nop_();
  23.          WS2812=1;
  24.                         _nop_();
  25.                         _nop_();
  26.                         _nop_();               
  27.          WS2812=0;
  28. }
  29. void rest(void)
  30. {
  31.          WS2812=0;
  32.        _nop_();
  33.        _nop_();
  34.        _nop_();
  35.              _nop_();
  36.        _nop_();
  37.        _nop_();       
  38.          WS2812=0;
  39. }
  40. void send_one_byte(unsigned char in_data)
  41. {
  42.           unsigned char temp1=0;
  43.                 unsigned char temp2=0;
  44.                 unsigned char temp3=0;
  45.                 unsigned char i=0;
  46.            temp1=in_data;
  47.             for(i=0;i<8;i++)  //八位,循环八次
  48.                         {
  49.                                 if(temp1&0x01)
  50.                                         send_H();
  51.                                 else
  52.                                         send_L();
  53.                                 temp1 >>= 1;  //从最低位到最高位
  54.                         }
  55. }
  56. void set_one_led(unsigned char R_data,unsigned char G_data,unsigned char B_data)
  57. {
  58.   send_one_byte(R_data);
  59.         send_one_byte(G_data);
  60.         send_one_byte(B_data);
  61. }
  62. void WS2812_Write(void)
  63. {
  64.         unsigned int i;
  65.         WS2812_Reset();
  66.         i=0;
  67.         while(1)
  68.         {
  69.                 if(i==LED_ON)
  70.                 {
  71.                         set_one_led(RED,GREEN,BLUE);
  72.                         break;
  73.                 }
  74.                 else
  75.                 {
  76.                         set_one_led(0,0,0);
  77.                         i++;
  78.                 }
  79.         }
  80. }
复制代码

这样写还是不行,还是全亮

点评

你H和L反了,并且时间也不对。还不知道STC是单周期的?一个NOP是一个时钟。 对于12MHz,发数据1: DIN = 1; 10个NOP; DIN=0; 3个NOP 对于12MHz,发数据1: DIN = 1; 3个NOP; DIN=0; 10个NOP  详情 回复 发表于 2024-8-5 17:51
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2024-8-5 17:51:57 | 显示全部楼层
好学*** 发表于 2024-8-5 17:35
这样写还是不行,还是全亮

你H和L反了,并且时间也不对。还不知道STC是单周期的?一个NOP是一个时钟。如此简单的时序:
对于12MHz,发数据1:
DIN = 1;
10个NOP;
DIN=0;
3个NOP;

对于12MHz,发数据0:
DIN = 1;
3个NOP;
DIN=0;
10个NOP
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-8-5 18:22:57 | 显示全部楼层
本帖最后由 好学天上 于 2024-8-5 18:25 编辑
梁*** 发表于 2024-8-5 17:51
你H和L反了,并且时间也不对。还不知道STC是单周期的?一个NOP是一个时钟。如此简单的时序:
对于12MHz, ...
  1. <ol class="code_ol_R87" style="list-style-position: initial; list-style-image: initial; font-family: monospace; white-space: pre; background-color: rgb(240, 240, 240);"><li style="padding-left: 5px; list-style-position: initial; list-style-image: initial; border-left: 1px solid rgb(205, 205, 205) !important;"><div class="blockcode"><blockquote>void send_L(void)
  2. {
  3.          WS2812=1;
  4.                         _nop_();
  5.                         _nop_();
  6.                         _nop_();
  7.          WS2812=0;
  8.                         _nop_();
  9.                         _nop_();
  10.                         _nop_();
  11.         _nop_();
  12.                         _nop_();
  13.                         _nop_();
  14.         _nop_();
  15.         _nop_();
  16.                         _nop_();
  17.                         _nop_();
  18. }
  19. void send_H(void)
  20. {
  21.           WS2812=1;
  22.                         _nop_();
  23.                         _nop_();
  24.                         _nop_();
  25.                 _nop_();
  26.                         _nop_();
  27.                         _nop_();
  28.         _nop_();
  29.                         _nop_();
  30.                         _nop_();
  31.         _nop_();
  32.          WS2812=0;
  33.                         _nop_();
  34.                         _nop_();
  35.                         _nop_();
  36. }void send_one_byte(unsigned char in_data)
  37. {
  38.           unsigned char temp1=0;
  39.                 unsigned char temp2=0;
  40.                 unsigned char temp3=0;
  41.                 unsigned char i=0;
  42.            temp1=in_data;
  43.             for(i=0;i<8;i++)  //八位,循环八次
  44.                         {
  45.                                 if(temp1&0x01)
  46.                                         send_H();
  47.                                 else
  48.                                         send_L();
  49.                                 temp1 >>= 1;  //从最低位到最高位
  50.                         }
  51. }
  52. void set_one_led(unsigned char R_data,unsigned char G_data,unsigned char B_data)
  53. {
  54.   send_one_byte(R_data);
  55.         send_one_byte(G_data);
  56.         send_one_byte(B_data);
  57. }
  58. void WS2812_Write(void)
  59. {
  60.         unsigned int i;
  61.         WS2812_Reset();
  62.         i=0;
  63.         while(1)
  64.         {
  65.                 if(i==LED_ON)
  66.                 {
  67.                         set_one_led(RED,GREEN,BLUE);
  68.                         break;
  69.                 }
  70.                 else
  71.                 {
  72.                         set_one_led(0,0,0);
  73.                         i++;
  74.                 }
  75.         }
  76. }
  77. void Init(void)
  78. {
  79.             P5M0 = 0x10;
  80.                                                 P5M1 = 0x00;
  81. }
  82. void main(void)
  83. {
  84.         Init();
  85.                                 WS2812_Reset();
  86.         while(1)
  87.         {
  88.                                        
  89. //                RED=255;        //红 0~255
  90. //                GREEN=0;        //绿 0~255
  91. //                BLUE=0;        //蓝 0~255
  92.           set_one_led(0,255,255);
  93.                                         set_one_led(0,0,0);
  94.                                         WS2812_Reset();
  95.         }
  96. }void WS2812_Reset(void)
  97. {
  98.         WS2812=0;
  99.         Delay_x10us(10);
  100. }
复制代码
这样还是不行
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-03-29 17:35:27

7

主题

62

回帖

537

积分

高级会员

积分
537
发表于 2024-8-5 19:12:53 | 显示全部楼层
梁*** 发表于 2024-8-5 17:51
你H和L反了,并且时间也不对。还不知道STC是单周期的?一个NOP是一个时钟。如此简单的时序:
对于12MHz, ...

真的想不通在下愚钝

点评

仔细看下W2812的手册,MSB先发的哦。 示波器看下波形正常没有。  详情 回复 发表于 2024-8-5 22:42
好好学习天天向上
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2024-8-5 22:42:03 | 显示全部楼层
好学*** 发表于 2024-8-5 19:12
真的想不通在下愚钝

仔细看下W2812的手册,MSB先发的哦。
示波器看下波形正常没有。
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 23:25 , Processed in 0.219552 second(s), 113 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表