|  | 
 
| 使用定时器3的PWM驱动 使用WS2812_send函数可以直接驱动LED
 
 
 
 
 
 复制代码.h文件
#define TIMING_ONE  50                        //搞电平时间
#define TIMING_ZERO 25                        //低电平时间
#define W2812_SIZE        29                        //LED个数
extern uint16_t LED_BUF[10+24*W2812_SIZE];//LED数据缓存
void TIME_3_init(void);
void WS2812_send(uint8_t (*color)[3], uint16_t len);
void WS2812_Set_color_bit(u8 r,u8 g,u8 b,u8 lan);//设置单个LED颜色
void WS2812_update(void);//更新显示
void WS2812_OFF(void);
void WS2812_ALL(u8 r,u8 g,u8 b);
 复制代码.c文件
uint16_t LED_BUF[10+24*W2812_SIZE];//LED数据缓存
#define DMA_CH_Channe        DMA1_Channel3
#define DMA_CH_Flag                   DMA1_FLAG_TC3
#define TIME_CH                           TIM3
#define TIME_CCR                CCR3
void TIME_3_init(void)
{
                        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
                        TIM_OCInitTypeDef TIM_OCInitStructure;
                        GPIO_InitTypeDef GPIO_InitStructure;
                        DMA_InitTypeDef DMA_InitStructure;
                        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
                        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                        GPIO_Init(GPIOB, &GPIO_InitStructure);
                        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
                        TIM_TimeBaseStructure.TIM_Period = 90-1; 
                        TIM_TimeBaseStructure.TIM_Prescaler = 0;
                        TIM_TimeBaseStructure.TIM_ClockDivision = 0;
                        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
                        TIM_TimeBaseInit(TIME_CH, &TIM_TimeBaseStructure);
                        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
                        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
                        TIM_OCInitStructure.TIM_Pulse = 45; 
                        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
                        TIM_OC3Init(TIME_CH, &TIM_OCInitStructure);
                        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
                        DMA_DeInit(DMA_CH_Channe);
                        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&TIME_CH->TIME_CCR);
                        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)LED_BUF;
                        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
                        DMA_InitStructure.DMA_BufferSize = 42;
                        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;
                        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
                        DMA_InitStructure.DMA_Priority = DMA_Priority_High;
                        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
                        DMA_Init(DMA_CH_Channe, &DMA_InitStructure);
                        TIM_DMACmd(TIME_CH, TIM_DMA_Update, ENABLE);
}
void WS2812_send(uint8_t (*color)[3], uint16_t len)
{
                        uint8_t i;
                        uint16_t memaddr;
                        uint16_t buffersize;
                        buffersize = (len*24)+43;
                        memaddr = 0;
                        while (len)
        {   
                        for(i=0; i<8; i++) 
                {
                        LED_BUF[memaddr] = ((color[0][1]<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
                        memaddr++;
                }
                        for(i=0; i<8; i++) 
                {
                        LED_BUF[memaddr] = ((color[0][0]<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
                        memaddr++;
                }
                        for(i=0; i<8; i++) 
                {
                        LED_BUF[memaddr] = ((color[0][2]<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
                        memaddr++;
                }
                        len--;
        }
                        LED_BUF[memaddr] = ((color[0][2]<<8) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
                        memaddr++;  
                        LED_BUF[memaddr] = ((color[0][2]<<8) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
                        memaddr++; 
                        while(memaddr < buffersize)
        {
                        LED_BUF[memaddr] = 0;
                        memaddr++;
        }
                        DMA_SetCurrDataCounter(DMA_CH_Channe, buffersize); 
                        DMA_Cmd(DMA_CH_Channe, ENABLE);
                        TIM_Cmd(TIME_CH, ENABLE);
                        while(!DMA_GetFlagStatus(DMA_CH_Flag)) ;  
                        TIM_Cmd(TIME_CH, DISABLE);  
                        DMA_Cmd(DMA_CH_Channe, DISABLE); 
                        DMA_ClearFlag(DMA_CH_Flag); 
}
void WS2812_Set_color_bit(u8 r,u8 g,u8 b,u8 lan)//设置单个LED颜色
{
                        uint8_t i;
                        
                        for(i=0; i<8; i++) 
                {
                        LED_BUF[lan*24+i] = ((g<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
                        LED_BUF[lan*24+i+8] = ((r<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
                        LED_BUF[lan*24+i+16] = ((b<<i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
                }
                        LED_BUF[W2812_SIZE*24+1]=0;
                        LED_BUF[W2812_SIZE*24+2]=0;
}
void WS2812_update()//更新显示
{
                        DMA_SetCurrDataCounter(DMA_CH_Channe, W2812_SIZE*24); 
                        DMA_Cmd(DMA_CH_Channe, ENABLE);
                        TIM_Cmd(TIME_CH, ENABLE);
                        while(!DMA_GetFlagStatus(DMA_CH_Flag)) ;  
                        TIM_Cmd(TIME_CH, DISABLE);  
                        DMA_Cmd(DMA_CH_Channe, DISABLE); 
                        DMA_ClearFlag(DMA_CH_Flag); 
}
void WS2812_OFF()
{
                        u16 q;
                        for(q=0;q<W2812_SIZE;q++)
        {
                        WS2812_Set_color_bit(0,0,0,q);
        }
                        WS2812_update();
}
void WS2812_ALL(u8 r,u8 g,u8 b)
{
                        u16 q;
                        for(q=0;q<W2812_SIZE;q++)
        {
                        WS2812_Set_color_bit(r,g,b,q);
        }
                        WS2812_update();
}
 
 | 
 
×本帖子中包含更多资源您需要 登录 才可以下载或查看,没有账号?立即注册 
  |