一、WS2811簡介
輸出端口耐壓12V
芯片內(nèi)置穩(wěn)壓管,24V以下電源端只需串電阻IC到VDD腳,無需外加穩(wěn)壓管
灰度調(diào)節(jié)電路(256級灰度可調(diào))
內(nèi)置信號整形電路,任何一個IC收到信號后經(jīng)過波形整形后在輸出,保證線路波形畸變不會累加
內(nèi)置上電復位和掉電復位電路
PWM控制端能夠?qū)崿F(xiàn)256級調(diào)節(jié),掃描頻率不低于400HZ/S
串行接口級聯(lián),一根信號線DI完成數(shù)據(jù)的接收與解碼
任意兩點傳輸距離不超過2米無需增加任何電路
當刷新速率30幀/秒時,低速模式級聯(lián)數(shù)不小于512點,高速模式下不小于1024點
數(shù)據(jù)發(fā)送速度可達與400Kbps與800Kbps兩種模式
二、通訊協(xié)議
數(shù)據(jù)協(xié)議采用單線歸零碼的通訊方式, 像素點在上電復位以后, DIN端接受從控制器傳輸過來的數(shù)據(jù), 首先送過來的24bit數(shù)據(jù)被第一個像素點提取后, 送到像素點內(nèi)部的數(shù)據(jù)鎖存器, 剩余的數(shù)據(jù)經(jīng)過內(nèi)部整形處理電路整形放大后通過DO端口開始轉發(fā)輸出給下一個級聯(lián)的像素點, 每經(jīng)過一個像素點的傳輸, 信號減少24bit。 像素點采用自動整形轉發(fā)技術, 使得該像素點的級聯(lián)個數(shù)不受信號傳送的限制, 僅僅受限信號傳輸速度要求。
WS2811 0碼、1碼、reset碼時序、串接方法
數(shù)據(jù)傳輸
需要精確延時的,使用示波器進行查看
三、電路連接
四、開源代碼
WS2811.h
- #ifndef __WS2811_H
- #define __WS2811_H
- #include <stm32f10x.h>
- //#define Time_D 400 //宏定義
- #define nWs 50 // 定義串接級聯(lián)WS2811個數(shù) 50可修改
- //B-R-G 定義顏色24bits
- #define White 0xFFFFFF // 白色
- #define Black 0x000000 // 黑色 (不亮)
- #define Blue 0xFF0000 // 藍色
- #define Red 0x00FF00 // 紅色
- #define Green 0x0000FF // 綠色
- #define Gray 0x22ee22
- extern void WS_GPIO_Init(void);//WS2811端口初始化
- extern unsigned long WsDat_RUN[nWs];//流水燈顯存
- extern unsigned long WsDat[nWs];//流水燈顯存
- //extern void WS_Reset(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin); //復位
- //extern void WS_Set1(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN,unsigned long dat);
- //發(fā)送1個字節(jié)
- extern void WS_Set_Date(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN,unsigned char len,unsigned long dat); //發(fā)送相同數(shù)據(jù)
- extern void WS_SetAll(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN); //發(fā)送所有字節(jié)
- //燈帶控制方案
- extern unsigned long ColorToColor(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN,unsigned long color0, unsigned long color1,unsigned int speed) ;//顏色漸變
- //初始化顯存數(shù)組
- extern void LED_Init(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN,unsigned long color); extern void RUN_LED(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN,unsigned long color,unsigned int speed,unsigned char temp); //跑馬燈
- #endif
復制代碼
WS2811.C
- #include "WS2811.h"
- unsigned long WsDat[nWs]; //顯存
- unsigned long WsDat_RUN[nWs]; //流水燈顯存
- /**************************************************
- * IO初始化(移植時請修改)
- ***************************************************/
- void WS_GPIO_Init()
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE ); //端口時鐘,使能
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; // PIN
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽輸出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度為50MHz
- GPIO_Init(GPIOC, &GPIO_InitStructure); // 端口配置,根據(jù)設定參數(shù)初始化
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //端口時鐘
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_12; // PIN
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽輸出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度為50MHz
- GPIO_Init(GPIOB, &GPIO_InitStructure); // 端口配置,根據(jù)設定參數(shù)初始化
- }
- /**************************
- * 內(nèi)部延時
- ***************************/
- void WS_delay_us(__IO u32 nCount) //簡單的延時函數(shù)
- {
- for(; nCount != 0; nCount--);
- }
- void WS_delay2us()
- {
- unsigned char i;
- for(i=0; i<11; i++);
- }
- void WS_delay05us()
- {
- // unsigned char i;
- // for(i=0; i<1; i++);
- }
- void WS_delay_ms(uint32_t nms)
- {
- while(nms--)
- {
- WS_delay_us(1670); //普通方式延時
- }
- }
- /***************************
- * 發(fā)送一比特
- ****************************/
- void TX0(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin) // 發(fā)送0
- {
- GPIO_SetBits(GPIOx, GPIO_Pin);
- WS_delay05us();
- GPIO_ResetBits(GPIOx, GPIO_Pin);
- WS_delay2us();
- }
- void TX1(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin) // 發(fā)送1
- {
- GPIO_SetBits(GPIOx, GPIO_Pin);
- WS_delay2us();
- GPIO_ResetBits(GPIOx, GPIO_Pin);
- WS_delay05us();
- }
- void WS_Reset(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin) //復位
- {
- GPIO_ResetBits(GPIOx, GPIO_Pin);
- WS_delay_us(50);
- GPIO_SetBits(GPIOx, GPIO_Pin);
- GPIO_ResetBits(GPIOx, GPIO_Pin);
- }
- /************************************************
- * 發(fā)送數(shù)據(jù)
- *************************************************/
- void WS_Set1(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,unsigned long dat)
- {
- unsigned char i;
- for(i=0; i<24; i++)
- {
- if(0x800000 == (dat & 0x800000) )
- TX1(GPIOx,GPIO_Pin);
- else
- TX0(GPIOx,GPIO_Pin);
- dat<<=1; //左移一位
- }
- }
- void WS_Set_Date(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,unsigned char len,unsigned long dat) // 全部發(fā)送同樣的數(shù)據(jù)
- {
- unsigned char i;
- for(i = 0; i <len; i++)
- {
- WS_Set1(GPIOx,GPIO_Pin,dat);
- }
- WS_Reset(GPIOx,GPIO_Pin);
- }
- void WS_SetAll(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin) //發(fā)送所有字節(jié)
- {
- unsigned char i;
- for(i=0;i<nWs;i++)
- {
- WS_Set1(GPIOx,GPIO_Pin,WsDat_RUN[i]);
- }
- WS_Reset(GPIOx,GPIO_Pin);
- WS_delay_ms(500);
- }
- /**************************顏色漸變函數(shù)***************************/
- /*
- 從起始顏色---最終顏色
- */
- unsigned char abs0(int num)//求絕對值
- {
- if(num>0) return num;
- num = -num;
- return (unsigned char) num;
- }
- unsigned long ColorToColor(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,unsigned long color0, unsigned long color1,unsigned int speed)
- {
- unsigned char Red0, Green0, Blue0; // 起始三原色
- unsigned char Red1, Green1, Blue1; // 結果三原色
- int RedMinus, GreenMinus, BlueMinus; // 顏色差(color1 - color0)
- unsigned char NStep; // 需要幾步
- float RedStep, GreenStep, BlueStep; // 各色步進值
- unsigned long color; // 結果色
- unsigned char i;
- // 綠 紅 藍 三原色分解
- Red0 = color0>>8;
- Green0 = color0>>16;
- Blue0 = color0;
- Red1 = color1>>8;
- Green1 = color1>>16;
- Blue1 = color1;
- // 綠 紅 藍 三原色分解 若輸入的顏色非上述三種
- Red0 =( color0&0x00FF00)>>8;
- Green0 = (color0&0xFF0000)>>16;
- Blue0 = color0;
- Red1 = (color1&0x00FF00)>>8;
- Green1 = (color1&0xFF0000)>>16;
- Blue1 = color1;
- // 計算需要多少步(取差值的最大值)
- RedMinus = Red1 - Red0;
- GreenMinus = Green1 - Green0;
- BlueMinus = Blue1 - Blue0;
- //判斷兩個絕對值大小。。a>b為真,則=a;否則=b
- NStep = ( abs0(RedMinus) > abs0(GreenMinus) ) ? abs0(RedMinus):abs0(GreenMinus);
- NStep = ( NStep > abs0(BlueMinus) ) ? NStep:abs0(BlueMinus);
- // 計算出各色步進值
- RedStep = (float)RedMinus / NStep;
- GreenStep = (float)GreenMinus / NStep;
- BlueStep = (float)BlueMinus / NStep;
- // 漸變開始
- for(i=0; i<NStep; i++)
- {
- Red1 = Red0 + (int)(RedStep * i);
- Green1 = Green0 + (int)(GreenStep * i);
- Blue1 = Blue0 + (int)(BlueStep * i);
- color = Green1<<16 | Red1<<8 | Blue1; // 合成 綠紅藍
- WS_Set_Date(GPIOx,GPIO_Pin,nWs,color); //發(fā)送顏色,所有燈帶同色
- WS_delay_ms(speed);
- }
- return color;
- }
- /*************跑馬燈****************
- 000000000000000000000000
- 111100000000000000000000
- 000011110000000000000000
- 000000001111000000000000
- 111100000000111100000000
- 000011110000000011110000
- ***********************************/
- void LED_Init(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,unsigned long color) //初始化顯存數(shù)組
- {
- unsigned char i;
- for(i=0;i<50;i++)
- WsDat_RUN[i]=color;
- WS_SetAll(GPIOx,GPIO_Pin);
- }
- //入口參數(shù) color----speed----temp
- // 顯示顏色--流水速度--間隔距離
- void RUN_LED(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,unsigned long color,unsigned int speed,unsigned char temp)//跑馬燈
- {
- unsigned char i,j;
- for(j=0;j<(nWs-1);j++)
- {
- for(i=nWs;i>0;i--)
- WsDat_RUN[i] = WsDat_RUN[i-1];
- if(j%temp == 0)
- WsDat_RUN[0] = color;
- else
- WsDat_RUN[0] = Black;
- //WS_Set_Date(GPIO_PIN,nWs,WsDat_RUN[i]);
- WS_SetAll(GPIOx,GPIO_Pin);
- WS_delay_ms(speed);
- }
- }
- main.c
- #include "stm32f10x.h"
- #include "WS2811.h"
- int main()
- {
- WS_GPIO_Init();//GPIOC和GPIOB初始化
- ColorToColor(GPIOB,GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_12,Red,Green,10);//顏色漸變端口GPIOB12\13\14\15輸出
- //如果需要其他端口輸出先去WS2811.c修改GPIO口初始化函數(shù)
- }
復制代碼
|