OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3154|回复: 3

STM32F103C8T6驱动WS2812色彩异常

[复制链接]

16

主题

92

帖子

0

精华

高级会员

Rank: 4

积分
767
金钱
767
注册时间
2017-5-11
在线时间
100 小时
发表于 2018-1-16 14:37:44 | 显示全部楼层 |阅读模式
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]

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

16

主题

92

帖子

0

精华

高级会员

Rank: 4

积分
767
金钱
767
注册时间
2017-5-11
在线时间
100 小时
 楼主| 发表于 2018-1-16 14:41:56 | 显示全部楼层
这个是源程序

DMA驱动WS2812.rar

4.66 MB, 下载次数: 200

回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-1-17 01:14:56 | 显示全部楼层
参考我们的RGB LED模块例程吧
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

16

主题

92

帖子

0

精华

高级会员

Rank: 4

积分
767
金钱
767
注册时间
2017-5-11
在线时间
100 小时
 楼主| 发表于 2018-1-17 13:24:07 | 显示全部楼层
正点原子 发表于 2018-1-17 01:14
参考我们的RGB LED模块例程吧

已经参考的那个模块例程也参考了飞行器的程序,看原子哥的模块例程是驱动9813来实现的,我是打算直接驱动LED进行改变颜色,于是借鉴了飞行器上面的,奈何发生这种情况
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-11 12:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表