STM32F103控制WS2812B


#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

 

你可能感兴趣的:(STM32F驱动)