当前位置: 幻彩灯珠>>灯珠资讯>> 5050RGB贴片灯珠电路 5050RGB灯珠

5050RGB贴片灯珠电路 5050RGB灯珠

5050RGB贴片灯珠电路 5050RGB灯珠

5050RGB贴片灯珠电路(5050RGB灯珠)

前面是根据涂鸦平台的宠物自动喂食器,打开这个跳跃,已经有了小夜灯的功能,焦躁的心因此而平静下来。功能和华丽。那么,除了让他变得华丽,画手们的涂饰风格以外,作为电子工程师,必须用我们的方法进行美化。正好手上有ws2812的灯笼,全色模式开始。

ws2812特征:

1.ws2812灯珠内置控制电路和RGB芯片集成在5050包的元装置中,构成完全的外部控制像素点。

2.各像素点的3个基色实现256级的亮度显示,完成167777216色的全真色显示,扫描频率不低于400Hz/s。

3.串行级联接口,其可以通过一条信号线来接收和解码数据。

4.在刷新速率为30帧/秒的情况下,低速模式级联数为512点以上,高速模式为1024点以下。

5.数据传输速度达到800Kbps。

数据传输:

在ws2812的各珠的控制中需要24位的数据,被分成8位的绿色+8位的红色+8位的蓝色,各像素点的3基色的颜色能够实现256级的亮度显示,完成1677216色的全真色显示。在灯珠之间采用串行级联并通电复位之后,控制器可以向灯带发送一系列24比特的数据,例如,需要点亮10个灯,我们将10个24比特的数据发送到第一灯第一灯的DIN端接收从控制器发送来的24比特的数据,第一灯珠在提取出第一24比特的数据后,将该数据发送给数据锁存器,其余的数据通过内部整形电路向下传送,直到所有灯获取24比特数据为止。这10个24比特数据的发送间隔不能超过50us。否则,下一个颜色数据将首先重新锁定,未完成完全亮灯。

在这里,需要将重点放在关于时间的知识上,首先看定时波形图和数据传输时间表。

从上述两个图可知,ws2812的电平反转为纳秒电平,所以在使用单片机的外置的情况下,需要控制单片机的外置的传输速度,速度慢而不能点亮。

开始操作:

在驱动ws2812的情况下PWM或SPI的方式是一般的,这两个速度比直接使用IO端口进行电平反转更方便,控制效果高。这里采用SPI方式。由于点灯时的数据发送间隔的限制,SPI如果大量使用发送数据,中途中断的话可能会切断点亮,所以使用SPI的DMA进展控制,不会受到其他影响。

通过硬件SPI模拟ws2812的通信定时。单片机将STM32F103、主频率72M、SPI1的分频设定为8,将SPI1的通信频率设为9M。时间足够,使用SPI2的话,需要减小分频系数。否则不亮。我在这里采用的是SPI2,4分钟。SPI1因为被我的屏幕占据着。

.h文件只要定义了珠子的个数和0码1码。只是变更不同的珠数PIXELNUM的值。

#ifndef __ws2812_H

#define __ws2812_H

#include #34;stm32f10x.h#34;

#define PIXEL_NUM 24

//通过硬件spi模拟ws2811序列SPI的8位数据模拟ws281x的1位数据)

//将系统时钟设定为56M,将分频设定为8时SPI的通信频率为7M,传输1位数据的时间约143纳秒(ns)

//3*143=429ns5*143=715ns适合ws281x芯片的通信定时。

//_____

//| |___| 11111000 high level

//___

//| |_____| 11100000 LOW level

#define WS_HIGH 0XF8

#define WS_LOW 0XE0

void ws281x_Init(void);

void ws281x_closeAll(void);

void ws281x_rainbowCycle(uint8_t wait);

uint32_t ws281x_color(uint8_t red, uint8_t green, uint8_t blue);

void ws281x_setPIXELcolor(uint16_t n ,uint32_t GRBcolor);

void ws281x_show(void);

void ws281x_theaterChase(uint32_t c, uint8_t wait);

void ws281x_colorWipe(uint32_t c, uint8_t wait);

void ws281x_rainbow(uint8_t wait);

void ws281x_theaterChaseRainbow(uint8_t wait);

#endif /* __ws2812_H */

代码复制#include #34;…/BOARD/ws2812/ws2812.h#34;

#include #34;usart.h#34;

#include #34;delay.h#34;

uint8_t pixelBufferPIXEL_NUM24 ;

void ws281x_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

SPI_InitTypeDef SPI_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //PORTA时钟使能

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); //SPI1时钟使能

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输

/* pA7 SPI1_MOSI */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_pp; //PA7多重推挽输出SPI

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, GPIO_InitStructure);//初始化GPIOA

SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //SPI设置单向或双向数据模式:SPI设置为双线双向全双工

SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI动作模式:主SPI

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI数据大小的设置:SPI接收8比特帧结构的发送

SPI_InitStructure.SPI_CpOL = SPI_CpOL_LOW; //串行同步时钟的空闲状态低

SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //对串行同步时钟的第二个跳跃边缘(上升或下降)数据进行采样

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号是通过硬件NSS管脚还是软件(使用SSI比特)来管理的:内部NSS信号中有SSI比特控制

SPI_InitStructure.SPI_BaudRateprescaler = SPI_BaudRateprescaler_4; //定义波特率的预分频值。波特率的预分频值是16。

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输是从MSB位开始还是从LSB位开始。数据传输从MSB位开始。

SPI_InitStructure.SPI_CRCpolynomial = 7; //CRC值计算的多项式

SPI_Init(SPI2, SPI_InitStructure); //SPI_根据InitStruct指定的参数初始化周边设备SPIx寄存器

SPI_Cmd(SPI2, ENABLE); //使能SPI周边设备

SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);

DMA_DeInit(DMA1_Channel5); //将DMA的信道1寄存器重置为默认值

DMA_InitStructure.DMA_peripheralBaseAddr = (uint32_t) (SPI2 -gt; DR); //cpar; //DMA外设ADC基地址

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pixelBuffer; //cmar; //DMA内存基地址

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传送方向、从存储器读取向外部设备发送

DMA_InitStructure.DMA_BufferSize = PIXEL_NUM * 24; //cndtr; //DMA通道的DMA缓存大小

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_DISABLE; //周边设备地址寄存器不变

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_ENABLE; //内存地址寄存器增加

DMA_InitStructure.DMA_peripheralDataSize = DMA_peripheralDataSize_Byte; //数据宽度8位

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度8位

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //以通常的高速缓存模式动作

DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA信道x拥有中的优先级

DMA_InitStructure.DMA_M2M = DMA_M2M_DISABLE; //DMA信道x未被设定为从存储器向存储器的传送

DMA_Init(DMA1_Channel5, DMA_InitStructure); //DMA_的InitStruct中指定的参数初始化DMA的通道usart1Tx_DMA_Channel识别的寄存器

ws281x_closeAll(); //关闭全部灯光

delay_ms(100); //关掉所有的灯都要花时间

}

void ws281x_closeAll(void)

{

uint16_t i;

uint8_t j;

for(i = 0; i lt; PIXEL_NUM; ++i)

{

for(j = 0; j lt; 24; ++j)

{

pixelBufferij = WS_LOW;

}

}

ws281x_show();

}

uint32_t ws281x_color(uint8_t red, uint8_t green, uint8_t blue)

{

return green lt;lt; 16 | red lt;lt; 8 | blue;

}

void ws281x_setPIXELcolor(uint16_t n ,uint32_t GRBcolor)

{

uint8_t i;

if(n lt; PIXEL_NUM)

{

for(i = 0; i lt; 24; ++i)

{

pixelBufferni = (((GRBcolor lt;lt; i) 0X800000) WS_HIGH : WS_LOW);

}

}

}

void ws281x_setPIXELRGB(uint16_t n ,uint8_t red, uint8_t green, uint8_t blue)

{

uint8_t i;

if(n lt; PIXEL_NUM)

{

for(i = 0; i lt; 24; ++i)

{

pixelBufferni = (((ws281x_color(red,green,blue) lt;lt; i) 0X800000) WS_HIGH : WS_LOW);

}

}

}

void ws281x_show(void)

{

DMA_Cmd(DMA1_Channel5, DISABLE ); //usart关闭1TxDMA1所示的频道

DMA_ClearFlag(DMA1_FLAG_TC5);

DMA_SetCurrDataCounter(DMA1_Channel5,24 * PIXEL_NUM );//DMA通道的DMA缓存大小

DMA_Cmd(DMA1_Channel5, ENABLE); //使能usart1TxDMA1所示的信道

}

//Input a value 0 to 255 to get a color value。

//The colours are a transition r – g – b – back to r。

uint32_t ws281x_wheel(uint8_t wheelpos) {

wheelpos = 255 – wheelpos;

if(wheelpos lt; 85) {

return ws281x_color(255 – wheelpos * 3, 0, wheelpos * 3);

}

if(wheelpos lt; 170) {

wheelpos -= 85;

return ws281x_color(0, wheelpos * 3, 255 – wheelpos * 3);

}

wheelpos -= 170;

return ws281x_color(wheelpos * 3, 255 – wheelpos * 3, 0);

}

//Fill the dots one after the other with a color

void ws281x_colorWipe(uint32_t c, uint8_t wait) {

for(uint16_t i=0; i

ws281x_setPIXELcolor(i, c);

ws281x_show();

delay_ms(wait);

}

}

void ws281x_rainbow(uint8_t wait) {

uint16_t i, j;

for(j=0; jlt;256; j++) {

for(i=0; i

ws281x_setPIXELcolor(i, ws281x_wheel((i+j) 255));

}

ws281x_show();

delay_ms(wait);

}

}

//Slightly different, this makes the rainbow equally distributed throughout

void ws281x_rainbowCycle(uint8_t wait) {

uint16_t i, j;

for(j=0; jlt;256*5; j++) { //5 cycles of all colors on wheel

for(i=0; ilt; PIXEL_NUM; i++) {

ws281x_setPIXELcolor(i,ws281x_wheel(((i * 256/PIXEL_NUM) + j) 255));

}

ws281x_show();

delay_ms(wait);

}

}

//Theatre-style crawling lights。

void ws281x_theaterChase(uint32_t c, uint8_t wait) {

for (int j=0; jlt;10; j++) { //do 10 cycles of chasing

for (int q=0; q lt; 3; q++) {

for (uint16_t i=0; i lt; PIXEL_NUM; i=i+3) {

ws281x_setPIXELcolor(i+q, c); //turn every third PIXEL on

}

ws281x_show();

delay_ms(wait);

for (uint16_t i=0; i lt; PIXEL_NUM; i=i+3) {

ws281x_setPIXELcolor(i+q, 0); //turn every third PIXEL off

}

}

}

}

//Theatre-style crawling lights with rainbow effect

void ws281x_theaterChaseRainbow(uint8_t wait) {

for (int j=0; j lt; 256; j++) { //cycle all 256 colors in the wheel

for (int q=0; q lt; 3; q++) {

for (uint16_t i=0; i lt; PIXEL_NUM; i=i+3) {

ws281x_setPIXELcolor(i+q, ws281x_wheel((i+j) % 255)); //turn every third PIXEL on

}

ws281x_show();

delay_ms(wait);

for (uint16_t i=0; i lt; PIXEL_NUM; i=i+3) {

ws281x_setPIXELcolor(i+q, 0); //turn every third PIXEL off

}

}

}

}

复制代码const chars5。

int8_t i;

int main(void)

{

//usart1_Init(115200);

delay_Init();

ws281x_Init();

while(1)

{

//Some example procedures showing how to display to the PIXELs:

ws281x_colorWipe(ws281x_color(255, 0, 0), 50); //red

ws281x_colorWipe(ws281x_color(0, 255, 0), 50); //green

ws281x_colorWipe(ws281x_color(0, 0, 255), 50); //Blue

//colorWipe(strip.color(0, 0, 0, 255), 50); //White RGBW

//Send a theater PIXEL Chase in..。

ws281x_theaterChase(ws281x_color(127, 127, 127), 50); //White

ws281x_theaterChase(ws281x_color(127, 0, 0), 50); //red

ws281x_theaterChase(ws281x_color(0, 0, 127), 50); //Blue

//ws281x_rainbow(20);

ws281x_rainbowCycle(20);

ws281x_theaterChaseRainbow(200);

for(i = 0; i lt; PIXEL_NUM; ++i)

{

ws281x_setPIXELcolor(i, ws281x_color(0,250,0));

ws281x_show();

delay_ms(500);

}

}

}

复印代码是ws2812。c移植了AdafritNeoPIXEL库的一部分函数用于实现冷酷的显示效果。

都是贝司SPI,可以不用说无聊的话,在移植中使用。让我们看看效果吧!

原标题:硬件不好看,B格不够,只能收集灯饰-STM32F103SPI驱动ws2812

原作者:尼罗米

本文是21ic有奖征文作品,详情请参见21ic论坛活动专区:第二届万元红包——蓝V达人有奖征文活动,如果你也参加有意思征文活动,欢迎进入论坛参加活动~