ws2812驅動相信有不少人都用過,大家對這款彩色LED真的是又愛又恨,愛的是它它使用簡單,采用單總線通信方式,節約IO口,而且可以多級串聯。而普通的彩色LED不是共陰就是共陽,每個顏色一個引腳,一般都是用PWM驅動,想要控制亮度、顏色就要分別控制每個引腳上的PWM占空比,想要驅動多個LED就更麻煩了。恨的是ws2812對時序的要求比較高,對低速單片機不太友好而且開發比較復雜。
今天我們就針對基于ME8S003硬件PWM如何快速實現控制ws2812的驅動。其中ME8S003提供的2路PWM模塊可以輕松實現當下流行的LED驅動WS2812的通信,不需要過多占用CPU時間。敏矽微提供整套軟、硬件解決方案,幫助用戶快速開發;
1、概述
“WS2812”解決方案
ME8S003是內嵌8051兼容的1T高性能8位微控制器。該系列控制器具有高性能、高適應范圍和超低成本特點。內置48MHz主時鐘和獨立的低速(30K/1.5M可切換)時鐘,常用外設8路1M高速12位的ADC轉換器,允許4路輸入2個比較器,2+3通道PWM,2個UART串口,SPI接口,I2C總線接口,3通用16位計數器/定時器。低功耗支持深度睡眠和掉電模式。提供M2調試端口,實現系統仿真。
2、WS2812基本說明
“WS2812”快速解決方案
WS2812B是一款全彩LED控制IC,單總線控制,何為單總線我的理解就是數據線在一根線上傳輸的控制方式就是單總線。
WS2812是一個集控制電路與發光電路于一體的智能外控LED光源,外形一般為5050封裝,每個LED燈珠為一個像素點,支持RGB無極調色,同時每顆燈珠內部集成有智能數字接口數據鎖存信號整形放大驅動電路,還包含有高精度的內部振蕩器和可編程定電流控制部分,有效保證了像素點光的顏色高度一致。
3、ME8S003使用PWM實現數據移位輸出
“WS2812”快速解決方案
ME8S003內嵌一個PWM模塊,可以支持兩個獨立的16位PWM輸出。同時還可以配置成為兩個定時器,或者兩路PWM合并支持載波輸出(如實現38K Irda應用),或者配置兩個不同的PWM輸出來對應bit數據0/1并合并在一起,從而實現使用PWM進行bit流數據的移位輸出。
下面我們將討論如何使用PWM模塊實現bit流數據的移位輸出:
首先,我們將對PWM0和PWM1進行周期和占空比分別配置,其中PWM0的周期(PWM0CRCH/ PWM0CRCL)和占空比(PWM0CCH/ PWM0CCL)將用來代表數據0,PWM1的周期(PWM1CRCH/ PWM1CRCL)和占空比(PWM1CCH/ PWM1CCL)將用來代表數據1。0和1的周期和占空比是不同的,以WS2812應用為例,PWM0的周期和占空比分別為1.2us和0.3us,PWM0的周期和占空比分別為1.2us和0.9us。
當我們使能PWM的數據移位功能時,要輸出數據0,PWM移位輸出管腳(PWMSHT)就PWM0配置的波形;要輸出數據1,PWM移位輸出管腳就PWM1配置的波形。
最后的問題就是如何連續輸出一個bit數據流。ME8S003 PWM為這個移位功能設置一個乒乓緩存(PWMSHIFTDAT0/ PWMSHIFTDAT1),我們只需要來回切換并不斷把需要發出的數據喂入乒乓緩存即可。
當所有數據傳輸結束,關閉PWM。
4、WS2812控制實程
“WS2812”快速解決方案
ME8S003提供了全套的驅動,其中關于PWM 移位數據功能有PWM配置函數和PWM數據移位輸出函數;
PWM配置函數:
voidPWM_DataShift_Cfg(unsignedlongcyclefreq,unsignedcharduty0inpercentage,unsignedcharduty1inpercentage) cyclefreq:PWM周期頻率,單位hz duty0inpercentage:數據0輸出占空比的百分比 duty1inpercentage:數據1輸出占空比的百分比 voidPWM_DataShift_Cfg(unsignedlongcyclefreq,unsignedcharduty0inpercentage,unsignedcharduty1inpercentage) { unsignedlongtemp,temp1; unsignedcharclkshift; clkshift=(PWMCON0 0x07)+1; if(clkshift>2) temp=SystemClock>>clkshift; else temp=SystemClock; temp=temp/cyclefreq; PWM0CRCL=temp 0xFF; PWM0CRCH=(temp>>8) 0xFF; PWM1CRCL=PWM0CRCL; PWM1CRCH=PWM0CRCH; temp1=(temp*duty0inpercentage)/100; PWM0CCL=temp1 0xFF; PWM0CCH=(temp1>>8) 0xFF; temp1=(temp*duty1inpercentage)/100; PWM1CCL=temp1 0xFF; PWM1CCH=(temp1>>8) 0xFF; set_PWMCON1_SHIFTDIR; }
PWM數據移位輸出函數:
voidPWM_DataShift(unsignedchar*dataptr,unsignedcharlen) dataptr:輸出數據起始指針 len:數據長度 voidPWM_DataShift(unsignedchar*dataptr,unsignedcharlen) { PWMSHIFTDAT0=*dataptr++; PWMSHIFTDAT1=*dataptr++;; PWM_DATASHIFT_START; len-=2; //shiftalldata while(len) { if(PWMSTA_DAT0BF==0) { PWMSHIFTDAT0=*dataptr++; len--; } if(len==0)break; if(PWMSTA_DAT1BF==0) { PWMSHIFTDAT1=*dataptr++; len--; } } while(PWM_DATASHIFT_BUSY); PWM_DATASHIFT_STOP; }
3個WS2812 驅動的LED燈實例程序:
Main.c //----------------------------------------------------------------------------- //Includes //----------------------------------------------------------------------------- #include"me8s003.h"http://SFRdeclarations #include"io_mux.h" #include"sfr_macro.h" #include"sys.h" #include"pwm.h" //----------------------------------------------------------------------------- //main()Routine //----------------------------------------------------------------------------- //3ledunsignedcharcolor_data[9]={0xFF,0x80,0x40,0x40,0xFF,0x80,0x80,0x40,0xFF}; unsignedcharmax_data_no=9; unsignedintdata_index; voidmain(void) { Modify_System_Clock(HCLK_48M); P0_5_INIT(P0_5_PIO); P0_Output_Enable(IO_BIT5); P1_2_INIT(P1_2_PWMSHT); PWM_Init(PWM_CLK_DIVIDED_BY_1); PWM_DataShift_Cfg(833000,25,75);//833K=~1.2usPWMcycle,25%=~0.3us,75%=~0.9us while(1) { //shiftdata PWM_DataShift(color_data,max_data_no); //preparenextdata for(data_index=0;data_index<=max_data_no;data_index++) ????????{ ????????????color_data[data_index]=color_data[data_index]+1; ????????} ????????P0_5?=!P0_5;?????????????????????//?Turn?onoff?LE ????????Ddelay(800);?//Reset,?>80us } }
來源:敏矽MCU
審核編輯:湯梓紅
-
微控制器
+關注
關注
48文章
7542瀏覽量
151316 -
led
+關注
關注
242文章
23252瀏覽量
660582 -
PWM
+關注
關注
114文章
5181瀏覽量
213808 -
定時器
+關注
關注
23文章
3246瀏覽量
114720 -
WS2812
+關注
關注
0文章
32瀏覽量
6170
發布評論請先 登錄
相關推薦
評論