W806控制WS2812彩灯

[复制链接]
909|2
 楼主| 1764376441 发表于 2021-12-2 16:53 | 显示全部楼层 |阅读模式
利用W806通过寄存器控制IO口来控制WS2812彩灯。
  1. /****************联盛德W806寄存器操作******************/
  2. /****************参考资料:QQ:774145445****************/
  3. /****************功能:WS2812点亮**********************/
  4. /****************快手:共同学习stm8*********************/
  5. /****************AboutCDK 2.10.1***********************/
  6. #include <stdio.h>
  7. #include "wm_hal.h"

  8. static volatile unsigned int key_flag = 1;
  9. /**************************************************/
  10. #define                GPIOB_DATA                        (*(volatile unsigned int*)(0x40011400+0x0000))
  11. #define                GPIOB_DATA_EN                (*(volatile unsigned int*)(0x40011400+0X0004))
  12. #define                GPIOB_DIR                        (*(volatile unsigned int*)(0x40011400+0X0008))

  13. #define                wei0                0b0000000000000001
  14. #define                wei1                0b0000000000000010
  15. #define                wei2                0b0000000000000100
  16. #define                wei3                0b0000000000001000

  17. #define                wei4                0b0000000000010000
  18. #define                wei5                0b0000000000100000
  19. #define                wei6                0b0000000001000000
  20. #define                wei7                0b0000000010000000

  21. #define                wei8                0b0000000100000000
  22. #define                wei9                0b0000001000000000
  23. #define                wei10                0b0000010000000000
  24. #define                wei11                0b0000100000000000

  25. #define                wei12                0b0001000000000000
  26. #define                wei13                0b0010000000000000
  27. #define                wei14                0b0100000000000000
  28. #define                wei15                0b1000000000000000

  29. #define                led1_h                GPIOB_DATA|=wei0 // led1灯灭(高电平)
  30. #define                led1_l                GPIOB_DATA&=~wei0 // led1灯亮(低电平)

  31. #define                led2_h                GPIOB_DATA|=wei1
  32. #define                led2_l                GPIOB_DATA&=~wei1

  33. #define                led3_h                GPIOB_DATA|=wei2
  34. #define                led3_l                GPIOB_DATA&=~wei2

  35. #define                WS2812                (wei5)  //PB5引脚
  36. #define                WS2812L                GPIOB_DATA&=~WS2812
  37. #define                WS2812H                GPIOB_DATA|= WS2812
  38. /**************************************************/

  39. void delay_300ns(void); // 延时100ns
  40. void delay_300us(void); // 延时300us
  41. void RGB_LED_Write0(void); // 写0
  42. void RGB_LED_Write1(void); // 写1
  43. void RGB_LED_Reset(void);
  44. void RGB_LED_Write_Byte(unsigned char byte); // 写一个字节(8bit)
  45. void RGB_LED_Write_24Bits(unsigned char green,unsigned char red,unsigned char blue); // 写24个字节(绿、红、蓝三色)

  46. void WS2812_Clear();
  47. void WS2812_ChangeRGB1(unsigned char num);
  48. void WS2812_Light1(unsigned char num,unsigned char R,unsigned char G,unsigned char B,unsigned char L);
  49. void WS2812_Breath1(unsigned char num,unsigned char R,unsigned char G,unsigned char B);

  50. /**************************************************/
  51. int main(void)
  52. {
  53.         unsigned char n;
  54.         /**************************************************/
  55.         GPIOB_DATA_EN                |=WS2812;
  56.         GPIOB_DIR                        |=WS2812;
  57.         GPIOB_DATA                        |=WS2812;
  58.         /**************************************************/
  59.         SystemClock_Config(CPU_CLK_160M); // 设置系统时钟
  60.         printf("enter main\r\n");
  61.         while (1)
  62.         {
  63.                 WS2812_ChangeRGB1(18); // 特效1
  64. //                HAL_Delay(500);
  65. //                WS2812_Clear();
  66. //                HAL_Delay(500);
  67.                 //WS2812_Breath1(18,243,98,243);
  68.         }
  69.         return 0;
  70. }


  71. /*******************************************************/
  72. /*
  73. * 函数名:RGB_LED_Write0
  74. * 输入参数:空
  75. * 功能:发送0
  76. * 发送0对时许要求很严格,需要测试delay_100ns()是否满足时序*/
  77. void RGB_LED_Write0(void)
  78. {
  79.         WS2812H; // 灭
  80.         delay_300ns();
  81.        
  82.         WS2812L; // 亮
  83.         delay_300ns();
  84.         delay_300ns();
  85.         delay_300ns();
  86. }
  87. /*
  88. * 函数名:RGB_LED_Write1
  89. * 输入参数:空
  90. * 功能:发送1
  91. * 发送1对时许要求很严格,需要测试delay_100ns()是否满足时序*/
  92. void RGB_LED_Write1(void)
  93. {
  94.         WS2812H; // 灭
  95.         delay_300ns();
  96.         delay_300ns();
  97.         delay_300ns();
  98.        
  99.         WS2812L; // 亮
  100.         delay_300ns();
  101. }
  102. /*
  103. * 函数名:RGB_LED_Reset
  104. * 输入参数:空
  105. * 功能:停止 Reset*/
  106. void RGB_LED_Reset(void)
  107. {
  108.         WS2812L; // 灭
  109.         delay_300us();
  110. }
  111. /*
  112. * 函数名:RGB_LED_Write_Byte
  113. * 输入参数:byte
  114. * 功能:按照WS2812协议写一个字节*/
  115. void RGB_LED_Write_Byte(unsigned char byte)
  116. {
  117.         unsigned char i=0;

  118.         for(i=0;i<8;i++)
  119.                 {
  120.                         if(byte&0x80)
  121.                                 {
  122.                                         RGB_LED_Write1();
  123.                         }
  124.                         else
  125.                                 {
  126.                                         RGB_LED_Write0();
  127.                         }
  128.                 byte <<= 1;
  129.         }
  130. }
  131. /*
  132. * 函数名:RGB_LED_Write_24Bits
  133. * 输入参数:red\green\blue三色素
  134. * 功能:设置颜色*/
  135. void RGB_LED_Write_24Bits(unsigned char red,unsigned char green,unsigned char blue)
  136. {
  137.         RGB_LED_Write_Byte(green);
  138.         RGB_LED_Write_Byte(red);
  139.         RGB_LED_Write_Byte(blue);
  140. }

  141. /*
  142. * 函数名:WS2812_Clear()
  143. * 输入值:空
  144. * 功能:熄灭WS2812灯,默认熄灭255个*/
  145. void WS2812_Clear()
  146. {
  147.         unsigned char i = 0;
  148.         for(i=0;i<255;i++)
  149.         {
  150.                 RGB_LED_Write_24Bits(0,0,0);
  151.         }
  152. }
  153. /*
  154. * 函数名:WS2812_ChangeRGB1
  155. * 输入值:num 彩色灯的个数
  156. * 功能:红、绿、蓝三种颜色每隔500ms交替变换*/
  157. void WS2812_ChangeRGB1(unsigned char num)
  158. {
  159.         unsigned char i = 0;
  160.         for(i=0;i<num;i++)
  161.         {
  162.                 RGB_LED_Write_24Bits(255,0,0); // 红色
  163.                
  164.         }
  165.         RGB_LED_Reset(); // 停止
  166.         HAL_Delay(500); // 延时500ms
  167.         for(i=0;i<num;i++)
  168.         {
  169.                 RGB_LED_Write_24Bits(0, 255, 0); // 绿色
  170.                
  171.         }
  172.         RGB_LED_Reset();
  173.         HAL_Delay(500);
  174.         for(i=0;i<num;i++)
  175.         {
  176.                 RGB_LED_Write_24Bits(0, 0, 255); // 蓝色
  177.                
  178.         }
  179.         RGB_LED_Reset();
  180.         HAL_Delay(500);
  181.         for(i=0;i<num;i++)
  182.         {
  183.                 RGB_LED_Write_24Bits(255, 237, 45); // 黄色
  184.                
  185.         }
  186.         RGB_LED_Reset(); // 停止
  187.         HAL_Delay(500); // 延时500ms
  188.         for(i=0;i<num;i++)
  189.         {
  190.                 RGB_LED_Write_24Bits(235, 20, 255); // 紫色
  191.                
  192.         }
  193.         RGB_LED_Reset(); // 停止
  194.         HAL_Delay(500); // 延时500ms
  195.         for(i=0;i<num;i++)
  196.         {
  197.                 RGB_LED_Write_24Bits(56, 255, 238); // 淡蓝色
  198.                
  199.         }
  200.         RGB_LED_Reset(); // 停止
  201.         HAL_Delay(500); // 延时500ms
  202. }
  203. /*
  204. * 函数名:WS2812_Light1
  205. * 输入值:num 彩色灯的个数 R\G\B                  L(亮度0~100)
  206. * 功能:设置亮度*/
  207. void WS2812_Light1(unsigned char num,unsigned char R,unsigned char G,unsigned char B,unsigned char L)
  208. {
  209.         unsigned char i = 0;
  210.         R = (unsigned char) R*L/100; // 此处运算量较大,有可能造成不满足时许问题
  211.         G = (unsigned char) G*L/100; // 此处运算量较大,有可能造成不满足时许问题
  212.         B = (unsigned char) B*L/100; // 此处运算量较大,有可能造成不满足时许问题
  213.         for(i=0;i<num;i++)
  214.         {
  215.                 RGB_LED_Write_24Bits(R,G,B);
  216.         }
  217.         RGB_LED_Reset();
  218. }
  219. /*
  220. * 函数名:WS2812_Breath1
  221. * 输入值:num 彩色灯的个数 R\G\B
  222. * 功能:呼吸灯
  223. * 需要调用WS2812_Light1函数,WS2812_Light1函数运算量较大,有可能超出时序*/
  224. void WS2812_Breath1(unsigned char num,unsigned char R,unsigned char G,unsigned char B)
  225. {
  226.         unsigned char i = 0;
  227.        
  228.         for(i=0;i<100;i++)
  229.         {
  230.                 WS2812_Light1(num,R,G,B,i);
  231.                 HAL_Delay(20);
  232.         }
  233.         for(i=100;i>0;i--)
  234.         {
  235.                 WS2812_Light1(num,R,G,B,i);
  236.                 HAL_Delay(20);
  237.         }
  238. }


  239. /**************************************************/
  240. /*
  241. * 函数名:delay_300ns
  242. * 输入值:空
  243. * 功能:ns级延时,延时300ns
  244. * 该函数误差较大,需要自己用示波器调整,修改for循环此时可以该表延时时间
  245. * 尝试过用定时器延时,可惜本人技术不精,用定时器只能做到us级延时*/
  246. void delay_300ns(void) // 延时300ns
  247. {
  248.         unsigned char i=0;
  249.         for(i=10;i>0;i--)
  250.                 __NOP();
  251. }
  252. /*
  253. * 函数名:delay_300us
  254. * 输入值:空
  255. * 功能:us级延时,延时300us
  256. * 该函数误差较大,需要自己用示波器调整,修改for循环此时可以该表延时时间
  257. * WS2812对此函数对精度要求较低*/
  258. void delay_300us(void) // 延时300us
  259. {
  260.         uint32_t i=0;
  261.        
  262.         for (i = 0; i < (45 * 5); i++)
  263.         {
  264.                 __NOP();
  265.         }
  266. }
  267. /**************************************************/
  268. /**************************************************/
  269. /**************************************************/
  270. /**************************************************/


W806_WS2812.zip

2.54 KB, 下载次数: 20

W806通过寄存器控制IO口控制WS2812

34af9uc 发表于 2021-12-2 16:57 | 显示全部楼层
给你点一个赞
34af9uc 发表于 2021-12-5 13:31 | 显示全部楼层
这个不错,赞

1

主题

1

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部