263 lines
6.9 KiB
C
263 lines
6.9 KiB
C
/*****************************************************************
|
||
;Project: Light
|
||
;MCU:
|
||
;Date:
|
||
;File:
|
||
;Function:
|
||
******************************************************************/
|
||
#include "ws2812.h"
|
||
#include "delay.h"
|
||
#include "gpio.h"
|
||
/*---------------------------------------------------------------*/
|
||
//变量定义
|
||
unsigned char gLedBuffer[LED_NUM][GRB] = {0}; //亮灯数据缓存
|
||
/*---------------------------------------------------------------*/
|
||
//函数声明
|
||
static void WS_Port_Init(void);
|
||
static void WS_DIN_Clear(void);
|
||
static void WS_Write_0(void);
|
||
static void WS_Write_1(void);
|
||
/*---------------------------------------------------------------*/
|
||
//WS2812初始化
|
||
void WS_Init(void)
|
||
{
|
||
WS_Port_Init();
|
||
WS_CloseAll();
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//WS供电使能
|
||
void WS_Power(FunctionalState NewState)
|
||
{
|
||
GPIO_Set_Output(U32BIT(WS_EN_PIN));
|
||
|
||
if(NewState != DISABLE)
|
||
GPIO_Pin_Set(U32BIT(WS_EN_PIN));
|
||
else
|
||
GPIO_Pin_Clear(U32BIT(WS_EN_PIN));
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//关闭所有的led
|
||
void WS_CloseAll(void)
|
||
{
|
||
unsigned char led_i, color_i;
|
||
|
||
for(led_i=0;led_i<LED_NUM;led_i++)
|
||
{
|
||
for(color_i=0;color_i<GRB;color_i++)
|
||
{
|
||
gLedBuffer[led_i][color_i] = 0;
|
||
}
|
||
}
|
||
|
||
WS_Show(); //点灯
|
||
|
||
//WS_Power(DISABLE); //关闭WS的供电
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//--清除所有ledbuff 缓存
|
||
void LedBuff_CleanAll(void)
|
||
{
|
||
unsigned char led_i,color_i; //用于for循坏
|
||
|
||
for(led_i=0;led_i<LED_NUM;led_i++)
|
||
for(color_i=0;color_i<GRB;color_i++)
|
||
gLedBuffer[led_i][color_i] = 0;
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//点亮所有灯
|
||
void WS_LightAll(void)
|
||
{
|
||
WS_WriteNum(LED_NUM,0xff0000);
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//指定写某个灯写入color数据,不show灯
|
||
void LedBuff_WriteOrder(unsigned char ledOrder, unsigned int color)
|
||
{
|
||
unsigned char color_i;
|
||
|
||
// ledOrder = ledOrder-1;
|
||
//先把要改变的颜色填入到led的buffer中
|
||
for(color_i=0;color_i<GRB;color_i++)
|
||
{
|
||
if(color&0x800000)
|
||
{
|
||
gLedBuffer[ledOrder][color_i] = 1;
|
||
}
|
||
else
|
||
{
|
||
gLedBuffer[ledOrder][color_i] = 0;
|
||
}
|
||
color <<= 1;
|
||
}
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//指定写某个灯的color并显示颜色
|
||
void WS_WriteOrder(unsigned char ledOrder, unsigned int color)
|
||
{
|
||
unsigned char color_i;
|
||
|
||
// ledOrder = ledOrder-1;
|
||
//先把要改变的颜色填入到led的buffer中
|
||
for(color_i=0;color_i<GRB;color_i++)
|
||
{
|
||
if(color&0x800000)
|
||
{
|
||
gLedBuffer[ledOrder][color_i] = 1;
|
||
}
|
||
else
|
||
{
|
||
gLedBuffer[ledOrder][color_i] = 0;
|
||
}
|
||
color <<= 1;
|
||
}
|
||
WS_Show(); //点灯
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//-给前num个led写入color,但不show
|
||
void LedBuff_WriteNum(unsigned char numLed,unsigned int color)
|
||
{
|
||
unsigned char led_i,color_i; //用于for循坏
|
||
unsigned int color_temp;
|
||
|
||
for(led_i=0;led_i<numLed;led_i++)
|
||
{
|
||
color_temp = color;
|
||
for(color_i=0;color_i<GRB;color_i++)
|
||
{
|
||
if(color_temp&0x800000)
|
||
{
|
||
gLedBuffer[led_i][color_i] = 1;
|
||
}
|
||
else
|
||
{
|
||
gLedBuffer[led_i][color_i] = 0;
|
||
}
|
||
color_temp <<= 1;
|
||
}
|
||
}
|
||
color_temp <<= 1;
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//--给前num个led写入color 并显示
|
||
void WS_WriteNum(unsigned char numLed, unsigned int color)
|
||
{
|
||
unsigned char led_i,color_i;
|
||
unsigned int color_temp;
|
||
|
||
//先把要改变的颜色填入到led的buffer中
|
||
for(led_i=0;led_i<numLed;led_i++)
|
||
{
|
||
color_temp = color;
|
||
for(color_i=0;color_i<GRB;color_i++)
|
||
{
|
||
if(color_temp&0x800000)
|
||
{
|
||
gLedBuffer[led_i][color_i] = 1;
|
||
}
|
||
else
|
||
{
|
||
gLedBuffer[led_i][color_i] = 0;
|
||
}
|
||
color_temp <<= 1;
|
||
}
|
||
}
|
||
WS_Show(); //点灯
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//WS驱动IO口初始化
|
||
static void WS_Port_Init(void)
|
||
{
|
||
PIN_Set_GPIO(U32BIT(WS_DIN_PIN) | U32BIT(WS_EN_PIN),PIN_SEL_GPIO); //引脚设置成普通IO口
|
||
GPIO_Set_Output(U32BIT(WS_DIN_PIN) | U32BIT(WS_EN_PIN)); //设置引脚为输出模式
|
||
GPIO_Pin_Clear(U32BIT(WS_DIN_PIN)|U32BIT(WS_EN_PIN)); //WS数据IO和使能IO都清零
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//灯带显示函数
|
||
void WS_Show(void)
|
||
{
|
||
unsigned led_i, color_i;
|
||
|
||
WS_Power(ENABLE);
|
||
|
||
__disable_irq(); //关闭全局中断(防止打断)
|
||
//依次写10个灯
|
||
for(led_i=0; led_i<LED_NUM; led_i++)
|
||
{
|
||
//依次写入每个灯的24bit时序
|
||
for(color_i=0;color_i<GRB;color_i++)
|
||
{
|
||
if(gLedBuffer[led_i][color_i] != 0) //写高
|
||
{
|
||
WS_Write_1();
|
||
}
|
||
else //写低
|
||
{
|
||
WS_Write_0();
|
||
}
|
||
}
|
||
}
|
||
WS_DIN_Clear();
|
||
delay_us(300); //实践证明大于20us就行
|
||
__enable_irq(); //打开全局中断
|
||
|
||
}
|
||
|
||
/*---------------------------------------------------------------*/
|
||
//灯带显示函数但是最后不打开总中断
|
||
void WS_Show_Disable_irq(void)
|
||
{
|
||
unsigned led_i, color_i;
|
||
|
||
WS_Power(ENABLE);
|
||
|
||
__disable_irq(); //关闭全局中断(防止打断)
|
||
//依次写10个灯
|
||
for(led_i=0; led_i<LED_NUM; led_i++)
|
||
{
|
||
//依次写入每个灯的24bit时序
|
||
for(color_i=0;color_i<GRB;color_i++)
|
||
{
|
||
if(gLedBuffer[led_i][color_i] != 0) //写高
|
||
{
|
||
WS_Write_1();
|
||
}
|
||
else //写低
|
||
{
|
||
WS_Write_0();
|
||
}
|
||
}
|
||
}
|
||
WS_DIN_Clear();
|
||
delay_us(300); //实践证明大于20us就行
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//WS的数据清零
|
||
static void WS_DIN_Clear(void)
|
||
{
|
||
GPIO_Set_Output(U32BIT(WS_DIN_PIN));
|
||
GPIO_Pin_Clear(U32BIT(WS_DIN_PIN));
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//写bit_0
|
||
static void WS_Write_0(void)
|
||
{
|
||
WS_DIN_HIGH;
|
||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||
WS_DIN_LOW;
|
||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||
}
|
||
/*---------------------------------------------------------------*/
|
||
//写bit_1
|
||
static void WS_Write_1(void)
|
||
{
|
||
WS_DIN_HIGH;
|
||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||
WS_DIN_LOW;
|
||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||
}
|
||
/*---------------------------------------------------------------*/
|