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. ARC 之内存转换

    CHENYILONG Blog ARC 之内存转换 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilo ...

  2. 采用jacob实现word转pdf

    网络上已经有很多这方面的内容,在用之前也是参考了好多别人的文章,下面记录下我自己的整合过程.整个过程都比较简单: 开发环境:win8 64位系统,在2008下面部署也是一样的. 文档要求jdk的版本要 ...

  3. 经典sql-获取当前文章的上一篇和下一篇

    我们在做资讯类的网站的时候,肯定会有这么一个需求,就是在资讯内容页的下方需要给出上一篇和下一篇资讯的链接.上次我一同事兼好友兼室友就遇到了这么一个需求,一开始我们都把问题想复杂了,先取的是符合条件的资 ...

  4. Linux下创建软Raid

    1- Linux下创建软Raid   步骤1.创建磁盘,并转换为fd #fdisk /dev/sdb //这里使用新的磁盘sdb 然后输入n ,创建分区 使用默认的起始点 输入大小为+100M 然后重 ...

  5. Eureka的自我保护模式

    一 Eureka的自我保护模式 进入自我保护模式最直观的体现就是Eureka Server首页的警告,如下图: 默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,E ...

  6. LeetCode(21):合并两个有序链表

    Easy! 题目描述: 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出:1- ...

  7. java JVM指令2

    https://www.cnblogs.com/dreamroute/p/5089513.html 指令码 助记符 说明 0x00 nop 什么都不做 0x01 aconst_null 将null推送 ...

  8. CF601A 【The Two Routes】

    看数据范围,然后果断邻接矩阵$Floyd$啊 对于公路和铁路,各建一个图,分别跑最短路,然后取最大值即可 #include<iostream> #include<cstdio> ...

  9. HDOJ题目分类

    模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 104 ...

  10. IntelliJ IDEA快捷键:F12

    The F12 key moves the focus from the editor to the last focused tool window. 将焦点从编辑器移动到最后一个聚焦的工具窗口.