|
使用的芯片為STC15F104W同系列的IRC15F107W,只有該型號的芯片能驅動WS2812的RGB彩燈!
因為該型號的芯片使用內置24Mhz時鐘,而WS2812的時序要求精確到ns級別,于是對時鐘的最低要求就是24Mhz
而且IRC15F107W同STC15F104W,只有8個引腳的簡單封裝,并且內部自帶震蕩源無須外部晶振,插上電直接就能用
最重要的是和其它C51單片機通用頭文件,所以引用的時候只需要包含reg52.h文件即可!
所以該單片機非常適合新手入門,即便是小白看了也能學會!
/*
IRC15F107W 管腳(默認內部震蕩源24Mhz)
1 P3.4
2 VCC 3.8--5.5V
3 P3.5
4 GND
5 P3.0 接燒錄器的TXD
6 P3.1 接燒錄器的RXD
7 P3.2
8 P3.3
*/
然后是代碼部分,我用的雙色流水燈做的范例- #include "reg52.h"
- #include "intrins.h"
- #define WS2812_NUM 60 //燈的數量
- sbit Led_Pin = P3^0; //控制燈的引腳
- unsigned short G_0=191;//流水燈第一個顏色定義
- unsigned short R_0=98;
- unsigned short B_0=10;
- unsigned short G_1=11;//流水燈第二個顏色定義
- unsigned short B_1=45;
- unsigned short R_1=14;
復制代碼 然后就是用STC燒錄軟件自帶的延時計算器一鍵推出的延遲函數- void delay_ms(unsigned int ms) //@24.000MHz
- {
- unsigned char data i, j;
- while(ms--){
- _nop_();
- i = 24;
- j = 85;
- do
- {
- while (--j);
- } while (--i);
- }
- }
- void Delay75us(void) //@24.000MHz
- {
- unsigned char data i, j;
- i = 2;
- j = 189;
- do
- {
- while (--j);
- } while (--i);
- }
復制代碼 然后是WS2812寫入0和1的程序- void ws2812_writebit1(void){
- Led_Pin=1;
- _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- Led_Pin=!Led_Pin;
- //_nop_();_nop_();_nop_();
- }
- void ws2812_writebit0(void){
- Led_Pin=1;
- _nop_();_nop_();_nop_();_nop_();_nop_();
- Led_Pin=!Led_Pin;
- _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();
- }
復制代碼 然后是寫入單個顏色和總體顏色的程序
- void ws2812_writecolor(unsigned short dat){
- //由于STC8G1K08執行左移或者右移等移位操作耗時太久(2us,無符號短整型都這樣),導致時序嚴重落后,所以用原始的if-else代碼進行代替
- if(dat&0x80)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x40)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x20)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x10)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x08)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x04)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x02)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- if(dat&0x01)
- ws2812_writebit1();
- else
- ws2812_writebit0();
- }
- void ws2812_writeled(unsigned short green,unsigned short red,unsigned short blue){
- ws2812_writecolor(green);
- ws2812_writecolor(red);
- ws2812_writecolor(blue);
- }
復制代碼 然后是WS2812執行到最后一顆燈用的結尾程序,以及清屏程序- void ws2812_rest()
- {
- Led_Pin=0;
-
- Delay75us();
- }
- void ws2812_clear()
- {
- static int j=0;
- for(j=0;j<WS2812_NUM;j++)
- {
- ws2812_writeled(0,0,0);
- }
- ws2812_rest();
- ws2812_rest();
- ws2812_rest();
- }
復制代碼 流水燈主程序- void WS2812_DIS()
- {
- static int j=0;
- int i;
- j%=WS2812_NUM;
- j++;
- for(i=0;i<WS2812_NUM;i++)
- {
- if(i>j&&(i<j+10))
- {
- ws2812_writeled(G_0,R_0,B_0);
- }
- else
- {
- ws2812_writeled(G_1,R_1,B_1);
-
- }
- }
-
- }
- void main(void)
- {
- ws2812_clear();
- while(1)
- {
- WS2812_DIS();
- delay_ms(50);
- }
- }
復制代碼
希望大家能學到東西!完整代碼在壓縮包里!
|
評分
-
查看全部評分
|