高级会员

- 积分
- 767
- 金钱
- 767
- 注册时间
- 2017-5-11
- 在线时间
- 100 小时
|
1金钱
之前就有一个帖子提问用DMA+PWM来实现WS2812的灯变幻,结合原子哥的驱动和网上的驱动自己写了一个,已经实现颜色更改,但是有一个bug,只要亮度大于127,绿色就是常亮状态而在小于128的时候(包括127)又都是正常显示。用示波器看了第一个颜色数据应该为0码时,示波器为1码;颜色数据应该为1码时,示波器为0码,明显就是数据反了,但是但不调试的时候赋值又是正确的赋给了缓冲区,排除了硬件问题,已经更换过单片机和WS2812.在只显示一种颜色,不进行颜色更改时又是正确的,下面是调试图与程序[mw_shl_code=c,true]#include "ws2812.h"
#include "delay.h"
#include "stdio.h"
#define H0 29
#define H1 61
u16 buff[(24*LEN+42)];
void WS2812_init()//ws2812³õʼ»¯Òý½Å£¬¶¨Ê±Æ÷(PWM)£¬DMA£¬ÖжÏ
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//ƵÂÊ=72M/((arr+1)*(psc+1))(µ¥Î»£ºHz)
TIM_TimeBaseStructure.TIM_Period = 89;//90 800KHz 1.25us 1ÖÜÆÚ
TIM_TimeBaseStructure.TIM_Prescaler = 0;//1
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//0£»Ê±ÖÓ·Ö¸î
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//ÏòÉϼÆÊýģʽ
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;//ÖØ¸´¼ÆÊýÖµ
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
//TIMÊä³ö±È½Ï¹¦ÄÜ
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆÄ£Ê½1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//±È½ÏÊä³öʹÄÜ
TIM_OCInitStructure.TIM_Pulse = 0;//ÉèÖôý×°Èë²¶»ñ±È½Ï¼Ä´æÆ÷µÄÂö³åÖµ
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;////Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
TIM_OC1Init(TIM4,&TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);//ʹÄÜTIM4 PWM CH1
TIM_DMACmd(TIM4,TIM_DMA_CC1,ENABLE);//ʹÓÃTIM4 CCR1 DMA
//TIM_Cmd(TIM4,ENABLE);
//DMA1 ÅäÖÃ
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&TIM4->CCR1;//Ä¿±êµØÖ·ÎªTIM4CCR1¼Ä´æÆ÷
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buff;//Êý¾Ý´æ´¢µØÖ·
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//ÄÚ´æµØÖ·¼Ä´æÆ÷µÝÔö
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//ÍâÉèµØÖ·¼Ä´æÆ÷²»±ä
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//ÍâÉèÊý¾Ý¿í¶È16λ
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//Êý¾Ý¿í¶ÈΪ16λ
DMA_InitStructure.DMA_BufferSize = 24*LEN+42;//DMAͨµÀ»º´æ´óС
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//Êý¾Ý´«Êä·½Ïò´ÓÄÚ´æµ½ÍâÉè
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//¹¤×÷ģʽ->Õý³£Ä£Ê½
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMAͨµÀÓÅÏȼ¶
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//²»Ê¹ÓÃÄÚ´æµ½ÄÚ´æ´«Êä
DMA_Init(DMA1_Channel1,&DMA_InitStructure);//ͨµÀ1³õʼ»¯
DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);//DMAͨµÀ1´«ÊäÍê³ÉÖжÏ
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//ÇÀÕ¼
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//˳´Ó
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//¿ªÆôDMA´«Êä
//rgb[] : color data
//led : led len
void ws2812_send(struct LED_RGB rgb[],u8 led)
{
u8 i;
u8 len=0;
u16 count=0;
while(len < led)
{
for(i=0;i<8;i++)//green
buff[count++]=((rgb[len].green<<i) & 0x80) ? H1 : H0;
for(i=0;i<8;i++)//red
buff[count++]=((rgb[len].red<<i) & 0x80) ? H1 : H0;
for(i=0;i<8;i++)//blue
buff[count++]=((rgb[len].blue<<i) & 0x80) ? H1 : H0;
len++;
}
for(i=0;i<42;i++)//rest
buff[count++]= 0x00;
TIM_Cmd(TIM4,ENABLE);
DMA_Cmd(DMA1_Channel1,ENABLE);
}
void DMA1_Channel1_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC1)!=RESET)
{
TIM_Cmd(TIM4,DISABLE);
DMA_Cmd(DMA1_Channel1,DISABLE);
DMA_ClearFlag(DMA1_FLAG_TC1);
}
}
[/mw_shl_code]
|
|