#include "WS281x.h"
#include "stdio.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_gpio.h"
#include "misc.h"
uint16_t WS_SendBuff[(LED_NUM*24) + 58] = {0,0,0};
uint16_t WS2_SendBuff[(LED_NUM*24) + 58] = {29,58,0};
uint16_t WS3_SendBuff[(LED_NUM*24) + 58] = {0,0,0};
uint16_t WS4_SendBuff[(LED_NUM*24) + 58] = {0,0,0};
//ÈýÖÖÔÉ« RGB
uint8_t colorss[][3] =
{
{0xFF, 0x00, 0x00}, // ºì
{0x00, 0xFF, 0x00}, // ÂÌ
{0x00, 0x00, 0xFF}, // ˦
// {0xFF, 0xFF, 0xFF}, //
// {0xFF, 0xFF, 0x00}, //
// {0x00, 0xFF, 0xFF}, //
// {0x00, 0xFF, 0xFF}, //
// {0x00, 0x80, 0xFF}, //
// {0x00, 0x00, 0xFF}, //
// {0x80, 0x00, 0xFF}, //
// {0xFF, 0x00, 0xFF}, //
// {0xFF, 0x00, 0x80} //
};
/************************
**³ÌÐòÃû³Æ:Delay
**²ÎÊý:
**·µ»ØÖµ: none
**˵Ã÷:
************************/
void Delay(__IO uint32_t nCount)
{
while(nCount--)
{
}
}
/************************
**³ÌÐòÃû³Æ:WS_RCC_Config
**²ÎÊý: ÎÞ
**·µ»ØÖµ: none
**˵Ã÷: TIM \ GPIO \ DMA µÈʹÄÜÇëÇóÅäÖÃ
************************/
void WS_RCC_Config(void)
{
/*ʹÄܶ¨Ê±Æ÷ʱÖÓ */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* GPIOA and GPIOB clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
/*ʹÄܶ¨Ê±Æ÷ʱÖÓ */ //sq add 2018-8-21 20:01:38
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* DMA clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}
/************************
**³ÌÐòÃû³Æ:WS_GPIO_Config
**²ÎÊý: ÎÞ
**·µ»ØÖµ: none
**˵Ã÷: IO ¹Ü½ÅÅäÖÃ
************************/
void WS_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//sq add 2018-8-21 15:35:22
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/************************
**³ÌÐòÃû³Æ:WS_TIM1_ModeConfig
**²ÎÊý: none
**·µ»ØÖµ: none
**˵Ã÷: ÅäÖÃTIM1Êä³öµÄPWMÐźŵÄģʽ£¬ÈçÖÜÆÚ¡¢¼«ÐÔ¡¢Õ¼¿Õ±È
************************/
static void WS_TIM1_ModeConfig(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //ʱ¼ä¼ÆÊý½á¹¹Ìå
TIM_OCInitTypeDef TIM_OCInitStructure; //¶¨Ê±Æ÷³õʼ»¯½á¹¹Ìå
// NVIC_InitTypeDef NVIC_InitStructure;
/*******************
PWM1+CH1ͨµÀ£¬ÅäÖÃPWM1ΪÊä³öģʽ ÅäÖÃΪ800KHzµÄƵÂÊ ÄÚºËʱÖÓ 72/90 = 800kHz£¬ WS2812B µÄ¸ßµÍµçƽÈçÏÂ
TIMCLK = 72ZHZ WSTIM=WSH+WSL = 1.25
0Â룺 H0(0.4us) + L0(0.85us) = 1.25us Îó²î ¡À150ns ¼´ pulseL0 = (0.85 *90) / 1.25 = 61.2
1Â룺 H1(0.8us) + L1(0.45us) = 1.25us Îó²î ¡À150ns ¼´ pulseL1 = (0.45 *90) / 1.25 = 32
***************************/
//ÉèÖÃÏÂÒ»¸ö¸üÐÂʼþתÈë»î¶¯µÄ×Ô¶¯ÖØ×°¼Ä´æÆ÷ÖÜÆÚµÄÖµ È¡Öµ·¶Î§±ØÐëÔÚ0x0000 ~ 0xFFFF
TIM_TimeBaseStructure.TIM_Period = TIMER_PERIOD - 1;
//ÉèÖÃʱÖÓƵÂʳýÊýµÄÔ¤·ÖƵֵ = ϵͳʱÖÓ/ TIM_Prescaler
TIM_TimeBaseStructure.TIM_Prescaler = 0;
//ÉèÖÃʱÖÓ·Ö¸î
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
//Ñ¡Ôñ¼ÆÊýÆ÷ģʽ ÉèÖÃΪÏòÉϼÆÊýģʽ
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/*PWM2ģʽ£¬ÔÚÏòÉϼÆÊýʱ£¬µ±TIM1_CNT < TIM1_CRRʱ£¬Í¨µÀΪÎÞЧµçƽ£¬·ñÔòΪÓÐЧµçƽ£¬ÈôÊÇPWM1ÔòÏà·´ channel2 µÄģʽÅäÖÃ*/
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // Ö¸¶¨TIMģʽ
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // ÕýÏòÊä³öʹÄÜ
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //Ö¸¶¨TIM»¥²¹µÄÊä³ö±È½Ï״̬
// Ö¸¶¨Òª¼ÓÔص½²¶»ñ±È½Ï¼Ä´æÆ÷ÖеÄÂö³åÖµ Õ¼¿Õ±ÈÉèÖà ռ¿Õ±È = CCR_Val / TIM_Period
TIM_OCInitStructure.TIM_Pulse = WS_SendBuff[0]; //61; //CCR2_Val; 61;//
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM_OCPolarity_Low; //Ö¸¶¨Êä³ö¼«ÐÔ
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//TIM_OCNPolarity_Low; //Ö¸¶¨Êä³ö»¥²¹µçƽֵ
/*Ö¸¶¨¿ÕÏÐ״̬ϵÄTIMÊä³ö±È½Ïpin״̬ ÊÇTIM_Output_Compare_Idle_State*/
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
/*Ö¸¶¨¿ÕÏÐ״̬ϵÄTIMÊä³ö±È½Ïpin״̬ ÊÇTIM_Output_Compare_N_Idle_State*/
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC3Init(TIM1, &TIM_OCInitStructure); //ÉèÖÃͨµÀ2
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_DMACmd ( TIM1, TIM_DMA_Update, ENABLE );
/*¶¨Ê±Æ÷1ʹÄÜ */
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE); //¶¨Ê±Æ÷1 PWMÊä³öʹÄÜ
}
/************************
**³ÌÐòÃû³Æ:WS_DMA_Config
**²ÎÊý: none
**·µ»ØÖµ: none
**˵Ã÷: DMA²ÎÊýÅäÖÃ
************************/
void WS_DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
// NVIC_InitTypeDef NVIC_InitStructure;
/* DMA1 Channel5 Config */
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR3_Address; //Ö¸¶¨ÍâΧDMAy ChannelxµÄ»ù±¾µØÖ·
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)WS_SendBuff; //Ö¸¶¨MAy ChannelxµÄÄÚ´æ»ùµØÖ·
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //Ö¸¶¨ÍâÉèÊÇÔ´»¹ÊÇÄ¿µÄ
DMA_InitStructure.DMA_BufferSize = (LED_NUM*24)+58; //(LED_NUM*24); //3 ; //(LED_NUM*24) + 24; //Ö¸¶¨Í¨µÀµÄÊý¾Ýµ¥ÔªµÄ»º³åÇø´óС£¬Êý¾Ýµ¥ÔªµÈÓÚDMA_PeripheralInc_Disable»òÕßDMA_MemoryDataSize³ÉÔ±Öд«Êä·½ÏòÉèÖõÄÅäÖÃ
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //Ö¸¶¨ÍâÉèµØÖ·¼Ä´æÆ÷ÊÇ·ñµÝÔö
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Ö¸¶¨ÄÚ´æµØÖ·¼Ä´æÆ÷ÊÇ·ñµÝÔö
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // Ö¸¶¨ÍâΧÊý¾Ý¿í¶È
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //Ö¸¶¨ÄÚ´æÊý¾Ý¿í¶È
// Ö¸¶¨DMAY channelxµÄ²Ù×÷ģʽ ÈôÊÇÄÚ´æµ½Äڴ棬²»ÄÜʹÓÃÑ»·»º´æÇøģʽ
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // DMA_Mode_Circular; // DMA_Mode_Circular; //
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //Ö¸¶¨DMAY CHANNELx µÄÈí¼þÓÅÏȼ¶
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //Ö¸¶¨ÊÇ·ñÔÚÄÚ´æµ½ÄÚ´æ´«ÊäÖÐʹÓÃDMAYͨµÀx
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel5, ENABLE);
}
/************************
**³ÌÐòÃû³Æ:WS_SendBuff
**²ÎÊý:
**·µ»ØÖµ: none
**˵Ã÷: ·¢ËÍËùÓÐÊý¾Ý
************************/
void WS_SendData(uint16_t buffsize)
{
DMA_SetCurrDataCounter(DMA1_Channel5, buffsize); // load number of bytes to be transferred
TIM_SetCounter(TIM1,0x0000);
//DMA1ͨµÀ2\5\7ʹÄÜ
DMA_Cmd(DMA1_Channel5, ENABLE);
TIM_Cmd(TIM1, ENABLE);
while(!DMA_GetFlagStatus(DMA1_FLAG_TC5)) ; // wait until transfer complete
DMA_Cmd(DMA1_Channel5, DISABLE); // disable DMA channel 2
DMA_ClearFlag(DMA1_FLAG_TC5);
TIM_Cmd(TIM1, DISABLE); // disable Timer 2
}
/************************
**³ÌÐòÃû³Æ:WS_Set_OnePiexl
**²ÎÊý: (*color)[3] : RGB ÑÕÉ«
len: µÆÖéÊýÁ¿
**·µ»ØÖµ: none
**˵Ã÷: ³õʼ»¯ËùÓвÎÊý
************************/
void WS_Set_OnePiexl(uint8_t (*color)[3], uint16_t len)
{
uint8_t i;
uint16_t memaddr=0;
uint16_t buffersize;
buffersize = (len * 24)+ 58;
memaddr = 48;
// memset(WS_SendBuff,0,buffersize); //sq add 2018-8-22 09:44:47
while (len--)
{
for(i=0; i<8; i++) // GREEN data
{
WS_SendBuff[memaddr++ ] = ((color[0][1]<< i) & 0x0080) ? WS2812_1 : WS2812_0 ;
}
for(i=0; i<8; i++) // RED
{
WS_SendBuff[memaddr++] = ((color[0][0]< }
for(i=0; i<8; i++) // BLUE
{
WS_SendBuff[memaddr++] = ((color[0][2]< }
}
//===================================================================//
//bug£º×îºóÒ»¸öÖÜÆÚ²¨Ðβ»ÖªµÀΪʲôȫÊǸߵçƽ£¬¹ÊÔö¼ÓÒ»¸ö²¨ÐÎ
WS_SendBuff[memaddr ++] = ((color[0][2]<<8) & 0x0080) ? WS2812_1 : WS2812_0;
//===================================================================//
while(memaddr < buffersize)
{
WS_SendBuff[memaddr++] = 0;
}
WS_SendData(buffersize);
}
/************************
**³ÌÐòÃû³Æ:WS_TIM2_ModeConfig
**²ÎÊý: none
**·µ»ØÖµ: none
**˵Ã÷: ÅäÖÃTIM1Êä³öµÄPWMÐźŵÄģʽ£¬ÈçÖÜÆÚ¡¢¼«ÐÔ¡¢Õ¼¿Õ±È
************************/
static void WS_TIM2_ModeConfig(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //ʱ¼ä¼ÆÊý½á¹¹Ìå
TIM_OCInitTypeDef TIM_OCInitStructure; //¶¨Ê±Æ÷³õʼ»¯½á¹¹Ìå
// NVIC_InitTypeDef NVIC_InitStructure;
/*******************
PWM1+CH1ͨµÀ£¬ÅäÖÃPWM1ΪÊä³öģʽ ÅäÖÃΪ800KHzµÄƵÂÊ ÄÚºËʱÖÓ 72/90 = 800kHz£¬ WS2812B µÄ¸ßµÍµçƽÈçÏÂ
TIMCLK = 72ZHZ WSTIM=WSH+WSL = 1.25
0Â룺 H0(0.4us) + L0(0.85us) = 1.25us Îó²î ¡À150ns ¼´ pulseL0 = (0.85 *90) / 1.25 = 61.2
1Â룺 H1(0.8us) + L1(0.45us) = 1.25us Îó²î ¡À150ns ¼´ pulseL1 = (0.45 *90) / 1.25 = 32
***************************/
//ÉèÖÃÏÂÒ»¸ö¸üÐÂʼþתÈë»î¶¯µÄ×Ô¶¯ÖØ×°¼Ä´æÆ÷ÖÜÆÚµÄÖµ È¡Öµ·¶Î§±ØÐëÔÚ0x0000 ~ 0xFFFF
TIM_TimeBaseStructure.TIM_Period = TIMER_PERIOD - 1;
//ÉèÖÃʱÖÓƵÂʳýÊýµÄÔ¤·ÖƵֵ = ϵͳʱÖÓ/ TIM_Prescaler
TIM_TimeBaseStructure.TIM_Prescaler = 0;
//ÉèÖÃʱÖÓ·Ö¸î
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
//Ñ¡Ôñ¼ÆÊýÆ÷ģʽ ÉèÖÃΪÏòÉϼÆÊýģʽ
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/*PWM2ģʽ£¬ÔÚÏòÉϼÆÊýʱ£¬µ±TIM1_CNT < TIM1_CRRʱ£¬Í¨µÀΪÎÞЧµçƽ£¬·ñÔòΪÓÐЧµçƽ£¬ÈôÊÇPWM1ÔòÏà·´ channel2 µÄģʽÅäÖÃ*/
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // Ö¸¶¨TIMģʽ
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // ÕýÏòÊä³öʹÄÜ
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //Ö¸¶¨TIM»¥²¹µÄÊä³ö±È½Ï״̬
// Ö¸¶¨Òª¼ÓÔص½²¶»ñ±È½Ï¼Ä´æÆ÷ÖеÄÂö³åÖµ Õ¼¿Õ±ÈÉèÖà ռ¿Õ±È = CCR_Val / TIM_Period
TIM_OCInitStructure.TIM_Pulse = 61; //WS2_SendBuff[0]; //61; //CCR2_Val; 61;//
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM_OCPolarity_Low; //Ö¸¶¨Êä³ö¼«ÐÔ
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//TIM_OCNPolarity_Low; //Ö¸¶¨Êä³ö»¥²¹µçƽֵ
/*Ö¸¶¨¿ÕÏÐ״̬ϵÄTIMÊä³ö±È½Ïpin״̬ ÊÇTIM_Output_Compare_Idle_State*/
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
/*Ö¸¶¨¿ÕÏÐ״̬ϵÄTIMÊä³ö±È½Ïpin״̬ ÊÇTIM_Output_Compare_N_Idle_State*/
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM2, &TIM_OCInitStructure); //ÉèÖÃͨµÀ2
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_DMACmd ( TIM2, TIM_DMA_Update, ENABLE );
/*¶¨Ê±Æ÷TIM2ʹÄÜ */
TIM_Cmd(TIM2, ENABLE);
TIM_CtrlPWMOutputs(TIM2, ENABLE); //¶¨Ê±Æ÷1 PWMÊä³öʹÄÜ
}
/************************
**³ÌÐòÃû³Æ:WS_DMA_Config
**²ÎÊý: none
**·µ»ØÖµ: none
**˵Ã÷: DMA²ÎÊýÅäÖÃ
************************/
void WS_DMA1_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
// NVIC_InitTypeDef NVIC_InitStructure;
/* DMA1 Channel5 Config */
DMA_DeInit(DMA1_Channel2);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM2_CCR1_Address; //Ö¸¶¨ÍâΧDMAy ChannelxµÄ»ù±¾µØÖ·
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)WS2_SendBuff; //Ö¸¶¨MAy ChannelxµÄÄÚ´æ»ùµØÖ·
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //Ö¸¶¨ÍâÉèÊÇÔ´»¹ÊÇÄ¿µÄ
DMA_InitStructure.DMA_BufferSize = (LED_NUM*24)+58; //(LED_NUM*24); //3 ; //(LED_NUM*24) + 24; //Ö¸¶¨Í¨µÀµÄÊý¾Ýµ¥ÔªµÄ»º³åÇø´óС£¬Êý¾Ýµ¥ÔªµÈÓÚDMA_PeripheralInc_Disable»òÕßDMA_MemoryDataSize³ÉÔ±Öд«Êä·½ÏòÉèÖõÄÅäÖÃ
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //Ö¸¶¨ÍâÉèµØÖ·¼Ä´æÆ÷ÊÇ·ñµÝÔö
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Ö¸¶¨ÄÚ´æµØÖ·¼Ä´æÆ÷ÊÇ·ñµÝÔö
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // Ö¸¶¨ÍâΧÊý¾Ý¿í¶È
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //Ö¸¶¨ÄÚ´æÊý¾Ý¿í¶È
// Ö¸¶¨DMAY channelxµÄ²Ù×÷ģʽ ÈôÊÇÄÚ´æµ½Äڴ棬²»ÄÜʹÓÃÑ»·»º´æÇøģʽ
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // DMA_Mode_Circular; // DMA_Mode_Circular; //
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //Ö¸¶¨DMAY CHANNELx µÄÈí¼þÓÅÏȼ¶
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //Ö¸¶¨ÊÇ·ñÔÚÄÚ´æµ½ÄÚ´æ´«ÊäÖÐʹÓÃDMAYͨµÀx
DMA_Init(DMA1_Channel2, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel2, ENABLE);
}
/************************
**³ÌÐòÃû³Æ:WS_SendBuff
**²ÎÊý:
**·µ»ØÖµ: none
**˵Ã÷: ·¢ËÍËùÓÐÊý¾Ý
************************/
void WS2_SendData(uint16_t buffsize)
{
DMA_SetCurrDataCounter(DMA1_Channel2, buffsize); // load number of bytes to be transferred
TIM_SetCounter(TIM2,0x0000);
//DMA1ͨµÀ2\5\7ʹÄÜ
DMA_Cmd(DMA1_Channel2, ENABLE);
TIM_Cmd(TIM2, ENABLE);
while(!DMA_GetFlagStatus(DMA1_FLAG_TC2)) ; // wait until transfer complete
DMA_Cmd(DMA1_Channel2, DISABLE); // disable DMA channel 2
DMA_ClearFlag(DMA1_FLAG_TC2);
TIM_Cmd(TIM2, DISABLE); // disable Timer 2
}
/************************
**³ÌÐòÃû³Æ:WS_Set_OnePiexl
**²ÎÊý: (*color)[3] : RGB ÑÕÉ«
len: µÆÖéÊýÁ¿
**·µ»ØÖµ: none
**˵Ã÷: ³õʼ»¯ËùÓвÎÊý
************************/
void WS2_Set_OnePiexl(uint8_t (*color)[3], uint16_t len)
{
uint8_t i;
uint16_t memaddr=0;
uint16_t buffersize;
buffersize = (len * 24)+ 58;
memaddr = 48;
while (len--)
{
for(i=0; i<8; i++) // GREEN data
{
WS2_SendBuff[memaddr++ ] = ((color[0][1]<< i) & 0x0080) ? WS2812_1 : WS2812_0 ;
}
for(i=0; i<8; i++) // RED
{
WS2_SendBuff[memaddr++] = ((color[0][0]< }
for(i=0; i<8; i++) // BLUE
{
WS2_SendBuff[memaddr++] = ((color[0][2]< }
}
//===================================================================//
//bug£º×îºóÒ»¸öÖÜÆÚ²¨Ðβ»ÖªµÀΪʲôȫÊǸߵçƽ£¬¹ÊÔö¼ÓÒ»¸ö²¨ÐÎ
WS2_SendBuff[memaddr ++] = ((color[0][2]<<8) & 0x0080) ? WS2812_1 : WS2812_0;
//===================================================================//
while(memaddr < buffersize)
{
WS2_SendBuff[memaddr++] = 0;
}
WS2_SendData(buffersize);
}
/************************
**³ÌÐòÃû³Æ:WS_InitConfig
**²ÎÊý: none
**·µ»ØÖµ: none
**˵Ã÷: ³õʼ»¯ËùÓвÎÊý
************************/
void WS_InitConfig(void)
{
WS_RCC_Config();
WS_GPIO_Config();
WS_TIM1_ModeConfig();
WS_DMA_Config();
WS_TIM2_ModeConfig();
WS_DMA1_Config();
}
/************************
**³ÌÐòÃû³Æ:WS_Run
**²ÎÊý: none
**·µ»ØÖµ: none
**˵Ã÷:
************************/
void WS_Run(void)
{
uint8_t i=0;
for(i=0;i<3;i++)
{
WS_Set_OnePiexl(&colorss[i],LED_NUM);
// WS2_Set_OnePiexl(&colorss[0],LED_NUM);
Delay(0x300000);
}
}
#ifndef __WS2811X_H
#define __WS2811X_H
#include "stm32f10x.h"
#define WS_NUM 10 //WS2812¸öÊý
#define LED_NUM 24 // µÆÖé¸öÊý
#define TIM1_CCR2_Address 0x40012C38
#define TIM1_CCR3_Address 0x40012C3C
#define TIM2_CCR1_Address 0x40000034
#define TIM2_CCR2_Address 0x40000038
#define TIM2_CCR3_Address 0x4000003C
#define TIM2_CCR4_Address 0x40000040
/*******************
PWM1+CH1ͨµÀ£¬ÅäÖÃPWM1ΪÊä³öģʽ ÅäÖÃΪ800KHzµÄƵÂÊ ÄÚºËʱÖÓ 72/90 = 800kHz£¬ WS2812B µÄ¸ßµÍµçƽÈçÏÂ
TIMCLK = 72ZHZ WSTIM=WSH+WSL = 1.25
0Â룺 H0(0.4us) + L0(0.85us) = 1.25us Îó²î ¡À150ns ¼´ pulseL0 = (0.85 *90) / 1.25 = 61.2
1Â룺 H1(0.8us) + L1(0.45us) = 1.25us Îó²î ¡À150ns ¼´ pulseL1 = (0.45 *90) / 1.25 = 32
***************************/
#define TIMER_PERIOD ( 90 ) // 800kHz / S ´«ÊäËÙÂÊ
#define WS2812_0 ( 29 ) // 0Âë
#define WS2812_1 ( 58 ) // 1Âë
#define WS2812_RESET ( 0 ) // ÖØÖÃ
void Delay(__IO uint32_t nCount) ;
void WS_RCC_Config(void) ;
void WS_GPIO_Config(void) ;
static void WS_TIM1_ModeConfig(void) ;
static void WS_TIM2_ModeConfig(void) ;
void WS_DMA_Config(void) ;
void WS_DMA1_Config(void);
void WS_InitConfig(void) ;
void WS_SendData(uint16_t buffsize) ;
void WS2_SendData(uint16_t buffsize) ;
void WS_Set_OnePiexl(uint8_t (*color)[3], uint16_t len) ;
void WS2_Set_OnePiexl(uint8_t (*color)[3], uint16_t len);
void WS_Run(void) ;
#endif