- /****************联盛德W806寄存器操作******************/
- /****************参考资料:QQ:774145445****************/
- /****************功能:WS2812点亮**********************/
- /****************快手:共同学习stm8*********************/
- /****************AboutCDK 2.10.1***********************/
- #include <stdio.h>
- #include "wm_hal.h"
- static volatile unsigned int key_flag = 1;
- /**************************************************/
- #define GPIOB_DATA (*(volatile unsigned int*)(0x40011400+0x0000))
- #define GPIOB_DATA_EN (*(volatile unsigned int*)(0x40011400+0X0004))
- #define GPIOB_DIR (*(volatile unsigned int*)(0x40011400+0X0008))
- #define wei0 0b0000000000000001
- #define wei1 0b0000000000000010
- #define wei2 0b0000000000000100
- #define wei3 0b0000000000001000
- #define wei4 0b0000000000010000
- #define wei5 0b0000000000100000
- #define wei6 0b0000000001000000
- #define wei7 0b0000000010000000
- #define wei8 0b0000000100000000
- #define wei9 0b0000001000000000
- #define wei10 0b0000010000000000
- #define wei11 0b0000100000000000
- #define wei12 0b0001000000000000
- #define wei13 0b0010000000000000
- #define wei14 0b0100000000000000
- #define wei15 0b1000000000000000
- #define led1_h GPIOB_DATA|=wei0 // led1灯灭(高电平)
- #define led1_l GPIOB_DATA&=~wei0 // led1灯亮(低电平)
- #define led2_h GPIOB_DATA|=wei1
- #define led2_l GPIOB_DATA&=~wei1
- #define led3_h GPIOB_DATA|=wei2
- #define led3_l GPIOB_DATA&=~wei2
- #define WS2812 (wei5) //PB5引脚
- #define WS2812L GPIOB_DATA&=~WS2812
- #define WS2812H GPIOB_DATA|= WS2812
- /**************************************************/
- void delay_300ns(void); // 延时100ns
- void delay_300us(void); // 延时300us
- void RGB_LED_Write0(void); // 写0
- void RGB_LED_Write1(void); // 写1
- void RGB_LED_Reset(void);
- void RGB_LED_Write_Byte(unsigned char byte); // 写一个字节(8bit)
- void RGB_LED_Write_24Bits(unsigned char green,unsigned char red,unsigned char blue); // 写24个字节(绿、红、蓝三色)
- void WS2812_Clear();
- void WS2812_ChangeRGB1(unsigned char num);
- void WS2812_Light1(unsigned char num,unsigned char R,unsigned char G,unsigned char B,unsigned char L);
- void WS2812_Breath1(unsigned char num,unsigned char R,unsigned char G,unsigned char B);
- /**************************************************/
- int main(void)
- {
- unsigned char n;
- /**************************************************/
- GPIOB_DATA_EN |=WS2812;
- GPIOB_DIR |=WS2812;
- GPIOB_DATA |=WS2812;
- /**************************************************/
- SystemClock_Config(CPU_CLK_160M); // 设置系统时钟
- printf("enter main\r\n");
- while (1)
- {
- WS2812_ChangeRGB1(18); // 特效1
- // HAL_Delay(500);
- // WS2812_Clear();
- // HAL_Delay(500);
- //WS2812_Breath1(18,243,98,243);
- }
- return 0;
- }
- /*******************************************************/
- /*
- * 函数名:RGB_LED_Write0
- * 输入参数:空
- * 功能:发送0
- * 发送0对时许要求很严格,需要测试delay_100ns()是否满足时序*/
- void RGB_LED_Write0(void)
- {
- WS2812H; // 灭
- delay_300ns();
-
- WS2812L; // 亮
- delay_300ns();
- delay_300ns();
- delay_300ns();
- }
- /*
- * 函数名:RGB_LED_Write1
- * 输入参数:空
- * 功能:发送1
- * 发送1对时许要求很严格,需要测试delay_100ns()是否满足时序*/
- void RGB_LED_Write1(void)
- {
- WS2812H; // 灭
- delay_300ns();
- delay_300ns();
- delay_300ns();
-
- WS2812L; // 亮
- delay_300ns();
- }
- /*
- * 函数名:RGB_LED_Reset
- * 输入参数:空
- * 功能:停止 Reset*/
- void RGB_LED_Reset(void)
- {
- WS2812L; // 灭
- delay_300us();
- }
- /*
- * 函数名:RGB_LED_Write_Byte
- * 输入参数:byte
- * 功能:按照WS2812协议写一个字节*/
- void RGB_LED_Write_Byte(unsigned char byte)
- {
- unsigned char i=0;
- for(i=0;i<8;i++)
- {
- if(byte&0x80)
- {
- RGB_LED_Write1();
- }
- else
- {
- RGB_LED_Write0();
- }
- byte <<= 1;
- }
- }
- /*
- * 函数名:RGB_LED_Write_24Bits
- * 输入参数:red\green\blue三色素
- * 功能:设置颜色*/
- void RGB_LED_Write_24Bits(unsigned char red,unsigned char green,unsigned char blue)
- {
- RGB_LED_Write_Byte(green);
- RGB_LED_Write_Byte(red);
- RGB_LED_Write_Byte(blue);
- }
- /*
- * 函数名:WS2812_Clear()
- * 输入值:空
- * 功能:熄灭WS2812灯,默认熄灭255个*/
- void WS2812_Clear()
- {
- unsigned char i = 0;
- for(i=0;i<255;i++)
- {
- RGB_LED_Write_24Bits(0,0,0);
- }
- }
- /*
- * 函数名:WS2812_ChangeRGB1
- * 输入值:num 彩色灯的个数
- * 功能:红、绿、蓝三种颜色每隔500ms交替变换*/
- void WS2812_ChangeRGB1(unsigned char num)
- {
- unsigned char i = 0;
- for(i=0;i<num;i++)
- {
- RGB_LED_Write_24Bits(255,0,0); // 红色
-
- }
- RGB_LED_Reset(); // 停止
- HAL_Delay(500); // 延时500ms
- for(i=0;i<num;i++)
- {
- RGB_LED_Write_24Bits(0, 255, 0); // 绿色
-
- }
- RGB_LED_Reset();
- HAL_Delay(500);
- for(i=0;i<num;i++)
- {
- RGB_LED_Write_24Bits(0, 0, 255); // 蓝色
-
- }
- RGB_LED_Reset();
- HAL_Delay(500);
- for(i=0;i<num;i++)
- {
- RGB_LED_Write_24Bits(255, 237, 45); // 黄色
-
- }
- RGB_LED_Reset(); // 停止
- HAL_Delay(500); // 延时500ms
- for(i=0;i<num;i++)
- {
- RGB_LED_Write_24Bits(235, 20, 255); // 紫色
-
- }
- RGB_LED_Reset(); // 停止
- HAL_Delay(500); // 延时500ms
- for(i=0;i<num;i++)
- {
- RGB_LED_Write_24Bits(56, 255, 238); // 淡蓝色
-
- }
- RGB_LED_Reset(); // 停止
- HAL_Delay(500); // 延时500ms
- }
- /*
- * 函数名:WS2812_Light1
- * 输入值:num 彩色灯的个数 R\G\B L(亮度0~100)
- * 功能:设置亮度*/
- void WS2812_Light1(unsigned char num,unsigned char R,unsigned char G,unsigned char B,unsigned char L)
- {
- unsigned char i = 0;
- R = (unsigned char) R*L/100; // 此处运算量较大,有可能造成不满足时许问题
- G = (unsigned char) G*L/100; // 此处运算量较大,有可能造成不满足时许问题
- B = (unsigned char) B*L/100; // 此处运算量较大,有可能造成不满足时许问题
- for(i=0;i<num;i++)
- {
- RGB_LED_Write_24Bits(R,G,B);
- }
- RGB_LED_Reset();
- }
- /*
- * 函数名:WS2812_Breath1
- * 输入值:num 彩色灯的个数 R\G\B
- * 功能:呼吸灯
- * 需要调用WS2812_Light1函数,WS2812_Light1函数运算量较大,有可能超出时序*/
- void WS2812_Breath1(unsigned char num,unsigned char R,unsigned char G,unsigned char B)
- {
- unsigned char i = 0;
-
- for(i=0;i<100;i++)
- {
- WS2812_Light1(num,R,G,B,i);
- HAL_Delay(20);
- }
- for(i=100;i>0;i--)
- {
- WS2812_Light1(num,R,G,B,i);
- HAL_Delay(20);
- }
- }
- /**************************************************/
- /*
- * 函数名:delay_300ns
- * 输入值:空
- * 功能:ns级延时,延时300ns
- * 该函数误差较大,需要自己用示波器调整,修改for循环此时可以该表延时时间
- * 尝试过用定时器延时,可惜本人技术不精,用定时器只能做到us级延时*/
- void delay_300ns(void) // 延时300ns
- {
- unsigned char i=0;
- for(i=10;i>0;i--)
- __NOP();
- }
- /*
- * 函数名:delay_300us
- * 输入值:空
- * 功能:us级延时,延时300us
- * 该函数误差较大,需要自己用示波器调整,修改for循环此时可以该表延时时间
- * WS2812对此函数对精度要求较低*/
- void delay_300us(void) // 延时300us
- {
- uint32_t i=0;
-
- for (i = 0; i < (45 * 5); i++)
- {
- __NOP();
- }
- }
- /**************************************************/
- /**************************************************/
- /**************************************************/
- /**************************************************/