how to drive a WS2812 RGB LED using PWM and DMA

#include <stm32f10x.h>

void Delay(__IO uint32_t nCount)
{
while(nCount--)
{
}
} #define TIM3_CCR1_Address 0x40000434 // physical memory address of Timer 3 CCR1 register #define d2r (3.14159265/180) TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure; /* Buffer that holds one complete DMA transmission
* Ensure that this buffer is big enough to hold
* all data bytes that need to be sent
*
* The buffer size can be calculated as follows: number of LEDs * 24 bytes + 42 bytes
*
* This leaves us with a maximum string length of (2^16 bytes per DMA stream - 42 bytes) / 24 bytes per LED = 2728 LEDs
*/
uint16_t LED_BYTE_Buffer[ ]; /* this array holds the RGB values to represent a color wheel using 256 steps on each emitter 256^3 = 16777216 colors
*/
uint8_t eightbit[ ][ ] =

{
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , },
{ , , }, }; void Timer3_init( void )
{
uint16_t PrescalerValue; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
/* GPIOA Configuration: TIM3 Channel 1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStructure ); RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE );
/* Compute the prescaler value */
PrescalerValue = (uint16_t) ( SystemCoreClock / ) - ;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = ; // 800kHz
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = ;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit( TIM3, &TIM_TimeBaseStructure ); /* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = ;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init( TIM3, &TIM_OCInitStructure ); /* configure DMA */
/* DMA clock enable */
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE ); /* DMA1 Channel6 Config */
DMA_DeInit( DMA1_Channel6 ); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) TIM3_CCR1_Address; // physical address of Timer 3 CCR1
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) LED_BYTE_Buffer; // this is the buffer memory
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // data shifted from memory to peripheral
DMA_InitStructure.DMA_BufferSize = ;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // automatically increase buffer index
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // stop DMA feed after buffer size is reached
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init( DMA1_Channel6, &DMA_InitStructure ); /* TIM3 CC1 DMA Request enable */
TIM_DMACmd( TIM3, TIM_DMA_CC1, ENABLE );
} /* This function sends data bytes out to a string of WS2812s
* The first argument is a pointer to the first RGB triplet to be sent -- color
* The seconds argument is the number of LEDs in the chain -- len
*
* This will result in the RGB triplet passed by argument 1 being sent to
* the LED that is the furthest away from the controller (the point where
* data is injected into the chain)
*/
void WS2812_send( uint8_t (*color)[ ], uint16_t len )
{
uint8_t i, j;
uint8_t led;
uint16_t memaddr;
uint16_t buffersize; buffersize = ( len * ) + ; // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes
memaddr = ; // reset buffer memory index
led = ; // reset led index // fill transmit buffer with correct compare values to achieve
// correct pulse widths according to color values
while ( len )
{
for ( j = ; j < ; j++ ) // GREEN data
{
if ( ( color[ led ][ ] << j ) & 0x80 ) // data sent MSB first, j = 0 is MSB j = 7 is LSB
{
LED_BYTE_Buffer[ memaddr ] = ; // compare value for logical 1
}
else
{
LED_BYTE_Buffer[ memaddr ] = ; // compare value for logical 0
}
memaddr++;
} for ( j = ; j < ; j++ ) // RED data
{
if ( ( color[ led ][ ] << j ) & 0x80 ) // data sent MSB first, j = 0 is MSB j = 7 is LSB
{
LED_BYTE_Buffer[ memaddr ] = ; // compare value for logical 1
}
else
{
LED_BYTE_Buffer[ memaddr ] = ; // compare value for logical 0
}
memaddr++;
} for ( j = ; j < ; j++ ) // BLUE data
{
if ( ( color[ led ][ ] << j ) & 0x80 ) // data sent MSB first, j = 0 is MSB j = 7 is LSB
{
LED_BYTE_Buffer[ memaddr ] = ; // compare value for logical 1
}
else
{
LED_BYTE_Buffer[ memaddr ] = ; // compare value for logical 0
}
memaddr++;
} led++;
len--;
} // add needed delay at end of byte cycle, pulsewidth = 0
while ( memaddr < buffersize )
{
LED_BYTE_Buffer[ memaddr ] = ;
memaddr++;
} DMA_SetCurrDataCounter( DMA1_Channel6, buffersize ); // load number of bytes to be transferred
DMA_Cmd( DMA1_Channel6, ENABLE ); // enable DMA channel 6
TIM_Cmd( TIM3, ENABLE ); // enable Timer 3
while ( !DMA_GetFlagStatus( DMA1_FLAG_TC6 ) )
; // wait until transfer complete
TIM_Cmd( TIM3, DISABLE ); // disable Timer 3
DMA_Cmd( DMA1_Channel6, DISABLE ); // disable DMA channel 6
DMA_ClearFlag( DMA1_FLAG_TC6 ); // clear DMA1 Channel 6 transfer complete flag
} int main( void )
{
Timer3_init( ); int16_t i; while ( )
{
/* first cycle through the colors on 2 LEDs chained together
* last LED in the chain will receive first sent triplet
* --> last LED in the chain will 'lead'
*/
for ( i = ; i < ; i += )
{
WS2812_send( &eightbit[ i ], );
Delay( 50000L );
} /* cycle through the colors on only one LED
* this time only the first LED that data is
* fed into will update
*/
for ( i = ; i < ; i += )
{
WS2812_send( &eightbit[ i ], );
Delay( 50000L );
}
}
}

STM32F1-workarea : how to drive a WS2812 RGB LED using PWM and DMA的更多相关文章

  1. arduino 蓝牙控制RGB LED灯

    /* 日期:2016.9.2 功能:arduino 蓝牙控制RGB LED灯 元件: 跳线公公头 * 8 rgbled, 220欧电阻 蓝牙模块 接线: 蓝牙模块VCC,GND分别接5V,GND;TX ...

  2. Arduino 各种模块篇 RGB LED灯

    示例代码: 类似与这样的led,共阴rgb led,通过调节不同的亮度,组合成不同的颜色. 示例代码: /* 作者:极客工坊 时间:2012年12月18日 IDE版本号:1.0.1 发布地址:www. ...

  3. 张高兴的 Windows 10 IoT 开发笔记:使用 Lightning 中的软件 PWM 驱动 RGB LED

    感觉又帮 Windows 10 IoT 开荒了,所以呢,正儿八经的写篇博客吧.其实大概半年前就想写的,那时候想做个基于 Windows 10 IoT 的小车,但树莓派原生不支持 PWM 啊.百度也搜不 ...

  4. 用树莓派实现RGB LED的颜色控制——C语言版本号

    用树莓派实现RGB LED的颜色控制  RGB色彩模式是工业界的一种颜色标准.是通过对红(R).绿(G).蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代 表红.绿 ...

  5. 共阳极RGB LED二极管

    1)RGB LED二极管有四个引脚,它把3个普通led被封装在其内部,这三个led颜色分别为红.绿.蓝三种颜色,通过控制各个LED的亮度,你可以混合出几乎任何你想要的颜色,如下图: 2)RGB LED ...

  6. Arduino 操作共阴极RGB LED

    一.原理图 注:电阻选用1k的 二. 实物图 三.完整事例代码,三种颜色不停的交替闪烁 实验结果自己运行观察

  7. 小伙伴们来看啊!开源智能机 Librem 5 规格发布。

    下图是 Librem 5 的高配版规格: (看到这配置,忍不住吐槽一句:放到三年前都看不上……) Librem 5 的更详细规格如下: CPU: i.MX8M @ max. 1.5GHz 四核 Cor ...

  8. 0xWS2812 STM32 driver for WS2812(B) RGB LEDs

    0xWS2812 STM32 driver for WS2812(B) RGB LEDs 0xWS2812 pronounced "hex-WS2812" This code ai ...

  9. 玩转X-CTR100 l STM32F4 l WS2812全彩LED灯

    更多塔克创新资讯欢迎登陆[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ]      WS2812B RGB全彩LED灯珠,只需通过一根信号线控制多个 ...

随机推荐

  1. mac 无法验证副本

    转: 这个是拆机后断了电源,导致时间不对,也就是说现在电脑的时间比U盘制作的时间还早,所以有这样的错误提示. 在终端里面修改时间请参考下面的代码,按回车键确认:date 062614102014.30 ...

  2. Git Pull Failed: cannot lock ref 'refs/remotes/origin/xxxxxxxx': unable to resolve ref

    1.xxxxxxxx代表目录名称,我要pull的目录是supman_creditmall_v5: 2.从代码库中pull代码时报这个错误,代码pull失败: 3.解决办法,看下图,删除文件后再pull ...

  3. HDU 4608 I-number 2013 Multi-University Training Contest 1 1009题

    题目大意:输入一个数x,求一个对应的y,这个y满足以下条件,第一,y>x,第二,y 的各位数之和能被10整除,第三,求满足前两个条件的最小的y. 解题报告:一个模拟题,比赛的时候确没过,感觉这题 ...

  4. Windows::Docker::Ubuntu 做 SLAM

    如题,这是一件很蛋疼的事情. 为了完成这一件事情,需要达成目标: Ubuntu GUI 必须要能够显示. Ubuntu 可以链接 USB Camera. 目标一 目标1很容易达成. 在 Win10 中 ...

  5. linux网桥浅析

    linux网桥浅析 原文链接:http://hi.baidu.com/_kouu/item/25787d38efec56637c034bd0 什么是桥接?简单来说,桥接就是把一台机器上的若干个网络接口 ...

  6. C# 压缩文件 的创建

    using System;using System.IO.Compression; using System.Collections.Generic;using System.Linq;using S ...

  7. Python_oldboy_自动化运维之路_paramiko,mysql(十二)

    本节内容: paramiko mysql 1.paramiko http://www.cnblogs.com/wupeiqi/articles/5095821.html paramiko是一个模块,s ...

  8. mac zsh环境配置java_home环境变量

    用zsh,修改-/.zshrc 修改这些文件之后,重修打开terminal,配置不会丢 首先确保已经安装了jdk: ## check the present running java which ja ...

  9. Java编程的逻辑 (71) - 显式锁

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  10. 事务ACID特性

    所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位.例如,银行转帐工作:从一个帐号扣款并使另一个帐号增款,这两个操作要么都执行,要么都不执行. 数据库事务必须具备 ...