/****************联盛德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();
}
}
/**************************************************/
/**************************************************/
/**************************************************/
/**************************************************/