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. the error about “no such file or directory”

    CHENYILONG Blog the error about "no such file or directory" when you get the question like ...

  2. HDU 4627 The Unsolvable Problem 杭电多校联赛第三场1009 数学题

    题意描述:给出一个n,要求在所有满足n = a+b的a和b里面求a和b的最小公倍数最大的两个数的最小公倍数. 解题报告:比赛的时候看到这个题的第一反应就是寻找这两个数一定是在a和b比较接近的地方找,这 ...

  3. 第9月第6天 push pop动画 生成器模式(BUILDER)

    1. https://github.com/MichaelHuyp/QQNews 2.生成器模式(BUILDER) class MazeBuilder { public: virtual void B ...

  4. springboot整合rabbirmq(3.7.9)中使用mandatory参数获取匹配失败的消息以及存入rabbitmq备份交换器中!

    先说下这个参数的作用: /** * Mandatory为true时,消息通过交换器无法匹配到队列会返回给生产者 * 为false时,匹配不到会直接被丢弃 */在一些特定场景下还是有用处的!接下来说一下 ...

  5. 简单解读linux的/proc下的statm、maps、memmap 内存信息文件分析【转】

    转自:https://blog.csdn.net/sctq8888/article/details/7398776 转载自:http://hi.baidu.com/deep_pro/blog/item ...

  6. (windows下)安装mysql

    一.先从mysql的官网上下载对应版本的mysql zip包(适用于windows下的) 二.解压zip包放到自定义的文件夹下(我放的是e盘,路径为E:\mysql-5.6.40-winx64) 三. ...

  7. 转:Vue-cli proxyTable 解决开发环境的跨域问题

    转:http://www.jianshu.com/p/95b2caf7e0da 和后端联调时总是会面对恼人的跨域问题,最近基于Vue开发项目时也遇到了这个问题,两边各自想了一堆办法,查了一堆资料,加了 ...

  8. JQ实现弹幕效果

    JQ实现弹幕效果,快来吐糟你的想法吧 效果图: 代码如下,复制即可使用: <!DOCTYPE html> <html> <head> <meta charse ...

  9. jQuery下的onChange事件在某些情况下无效

    onChage无效的原因: 虽然表面上感觉是当内容发生变化时,就会触发onchange事件,但是那只能在页面上操作.而如果通过dom对象去修改它的value则什么事也不会发生. onchange触发原 ...

  10. [转] 对vuex的表象理解(笔记)

    一个东西,首先要知道为什么用它,为什么要vuex,官方解释为了解决繁杂事件订阅和广播,那么事件的$dispatch,$on,怎么就复杂了?许多人是不是感觉后者还挺简单的,对的 如果简单小型项目,那么不 ...