久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6111|回復: 19
收起左側

用ws2812b燈珠制作32位搖搖棒

  [復制鏈接]
ID:885138 發表于 2021-2-28 18:50 來自手機 | 顯示全部樓層 |閱讀模式
用了一片hc89s003,32個ws2812b燈珠(5050),8只104電容一個滾珠開關,一個帶保護板的鋰電池(160mAh),一個電源開關,一個USB口,簡易充電電路,導線及0歐貼片電阻若干,還有30cm長的pvc線槽。
制作小技巧:
一、ws2812燈珠旋轉個小角度,直接手拉手串接,電路簡潔(圖三,燈串兩側+-電源,第一燈外接輸入);
二、滾珠開關斜向上45度左右安裝;
三、usb口可用于充電,同時借用usb的D+/D-改為串口txd/rxd,接自制一條假usb真串口線時又可下載固件,很方便。下方串口下載四針仍保留;
四、電路除單片機(ssop20封裝,圖中轉接板背面)和usb接口用了pcb板,其余均用導線加熱熔膠方式,適合單件DIY;
五、軟件參照論壇搜到的普通led燈搖搖棒程序,最低層改用了ws2812b驅動,延時參數邊試邊調整。
上加工后的實物圖(搖時的閃爍圖肉眼可見連續效果,手機拍不了)
IMG_20210228_180827.jpg
IMG_20210228_181042.jpg
IMG_20210228_181129.jpg

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:328014 發表于 2021-2-28 23:44 | 顯示全部樓層
干的漂亮,能分享下程序嗎?
回復

使用道具 舉報

ID:885138 發表于 2021-3-1 07:31 來自手機 | 顯示全部樓層
51hei團團 發表于 2021-2-28 23:44
干的漂亮,能分享下程序嗎?


/*
*32只WS2812+滾珠開關制作的搖搖棒*
*演示在上方16個LED上顯示“你真棒”三個漢字
*CPU:HC89S003F4 16K bytes flash ROM, 256+256 bytes data RAM
*WS2812 接P22(推挽驅動) ,滾珠開關接P00(下降沿中斷方式)
*晶振頻率:32MHz,Fosc 16MHz
*程序版本:V1.00
*硬件平臺:003F4 V1.00

*編寫軟件:Keil uVision4
*編寫:xxd0708

*聲明:本程序只供學習使用,未經作者許可,不得用于其它任何用途
*/

#define ALLOCATE_EXTERN
#include "HC89S003F4.h"
#include <intrins.h>






/**********************************************************
程序名稱:LED搖搖棒顯示64*16像素
簡要說明:外部中斷方式INT0顯示;取模方式:縱向取模、字節倒序
(取點方式:縱向8點上高位,字節排列:上到下左到右)
**********************************************************/

sbit WS2812_IO = P2^2        ;


u8 KY;       //防止重影的控制變量     
u8 cont_rock=0;         
u8 cont_col=0;
u8 col_r,col_g,col_b;


// 你(0) 真(1) 棒(2)
code u8 dat_word1[]=
{
0x00,0x80,0x01,0x00,0x06,0x00,0x1F,0xFF,0xE0,0x00,0x02,0x08,0x04,0x30,0x18,0xC0,
0xF0,0x02,0x10,0x01,0x13,0xFE,0x10,0x00,0x10,0x80,0x14,0x60,0x18,0x18,0x00,0x00,/*"你",3*/
0x00,0x08,0x20,0x08,0x20,0x09,0x2F,0xFA,0x2A,0xAC,0x2A,0xA8,0x2A,0xA8,0xFA,0xA8,
0x2A,0xA8,0x2A,0xA8,0x2A,0xAC,0x2F,0xFA,0x20,0x09,0x20,0x08,0x00,0x08,0x00,0x00,/*"真",4*/
0x08,0x20,0x08,0xC0,0x0B,0x00,0xFF,0xFF,0x09,0x00,0x08,0x80,0x22,0x48,0x2A,0x88,
0x2B,0x28,0x2E,0x28,0xFA,0xFF,0x2A,0x28,0x2B,0x28,0x2A,0x88,0x22,0x48,0x00,0x00,/*"棒",5*/
};



//延時子函數-16Mhz 1ms延時
void delayMs_16Mhz(u16 ms)
{
        u16 j;
        for(; ms>0; ms--)
                for(j=1596; j>0; j--);
}

//延時函數-16Mhz 1us延時
void delayUs_16Mhz(u8 us)
{
        for(; us>0; us--)
        {
                _nop_();
                _nop_();
                _nop_();
        }       
}


void ws2812_rst(void)
{       

        WS2812_IO = 0;
        delayUs_16Mhz(80);
}

void ws2812_write_byte( u8 dat)
{       
        u8 i = 8;
        dat <<= 1;         //最高位進入CY
        while(i)
        {
                 //高電平時間小于0.45uS為邏輯0,大于時為邏輯1
                WS2812_IO = 1;
                //如果主頻較高可在此處適當增加_nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                WS2812_IO = CY;
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                //如果主頻較高可在此處適當增加_nop_();
                WS2812_IO = 0;        //位發送完保持低電平,時間不大于50us。否則復位
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                dat <<= 1;         //最高位進入CY
                i--;                       
        }

}

/*顯示關閉*/
void display_off(void)
{
        uchar i;
        i=0;
        while( i< 32 )
        {
                ws2812_write_byte( 0x00);
                ws2812_write_byte( 0x00);
                ws2812_write_byte( 0x00);
                i++;
        }
        ws2812_rst();
}
  
/*顯示子程序 在上方16個LED上顯示三個漢字*/
void display_3word(void)
{
        uchar i,j,temp;
        //ws2812_rst();
        i=0;
        j=0;

        while(j<96)         //3個漢字3*16*2個字節
        {
                i=0;
                while( i< 16 )         //下16不顯示 可修改
                {
                        //與普通LED主要更改點,有顯示時發三個分量數據,否則發三個0
                        ws2812_write_byte( 0x00);
                        ws2812_write_byte( 0x00);
                        ws2812_write_byte( 0x00);
                        i++;
                }               
                temp = dat_word1[j+1];//上方16位先送第二字節(依取模方式而定)
                i=0;
                while( i< 8 )
                {
                        if(temp&0x01)           //從低到高送顯示位(依取模方式而定)
                        {
                                //與普通LED主要更改點,有顯示時發三個分量數據,否則發三個0
                                ws2812_write_byte( col_g);
                                ws2812_write_byte( col_r);
                                ws2812_write_byte( col_b);
                        }
                        else
                        {
                                //與普通LED主要更改點,有顯示時發三個分量數據,否則發三個0
                                ws2812_write_byte( 0x00);
                                ws2812_write_byte( 0x00);
                                ws2812_write_byte( 0x00);
                        }
                        i++;
                        temp = temp >>1;        //下一位
                }
                temp = dat_word1[j]; //上方16位再送第一字節(依取模方式而定)
                while( i< 16 )
                {
                        if(temp&0x01)         //從低到高送顯示位(依取模方式而定)
                        {
                                //與普通LED主要更改點,有顯示時發三個分量數據,否則發三個0
                                ws2812_write_byte( col_g);
                                ws2812_write_byte( col_r);
                                ws2812_write_byte( col_b);
                        }
                        else
                        {
                                //與普通LED主要更改點,有顯示時發三個分量數據,否則發三個0
                                ws2812_write_byte( 0x00);
                                ws2812_write_byte( 0x00);
                                ws2812_write_byte( 0x00);
                        }
                        temp = temp >>1;   //下一位
                        i++;
                }
          
           delayUs_16Mhz(200);  //延時量自行調整,當搖的速度一定時,延時越大,字越寬但能顯示字數減少
                j +=2;        //漢字下一列
        }

        //發送完三個漢字后清屏       
        display_off();

}


/*中斷服務程序*/
void intersvr0(void) interrupt 0 using 1
{

        //當從右向左搖時,產生中斷,KY取反變為1,此時不顯示,不運行下面的語句
        delayMs_16Mhz(10);
        if(~P0^0)//10mS消抖
        {
                cont_rock ++;          //判斷中斷次數
                if(cont_rock >= 20)
                   cont_rock = 20;
      //每個搖動來回滾珠開關會在擺幅兩端分別產生下降沿中斷,只提取其中一次
                   delayMs_16Mhz(30);                //延時量改變首字顯示位置,越大越靠后
                if((cont_rock&0x01) == 0) //偶數時顯示(或奇數次,依初值和開關方向而定)
                {
                  display_3word();   
                }
                else
                {
                        display_off();
                }
        }
    PINTF0 &= 0xFE;//  HC89S003需軟件清標志位INT0F
}



/**************************************************************************************
  * @實現效果        將Fosc設置為16MHz,Fcpu設置為16MHz
**************************************************************************************/
void main()
{

/************************************系統初始化****************************************/
        WDTCCR = 0x00;                                                //關閉看門狗
                                                //本例程為方便測試關閉看門狗,實際使用中,建議客戶打開看門狗,詳見WDT復位例程
        CLKSWR = 0x51;                                                //選擇內部高頻RC為系統時鐘,內部高頻RC 2分頻,Fosc=16MHz
        CLKDIV = 0x01;                                                //Fosc 1分頻得到Fcpu,Fcpu=Fosc

/**********************************相關配置初始化**************************************/

        P2M1 = P2M1&0xF0|0x08;                                //WS2812信號 P22設置為推挽輸出
        P0M0 = P0M0&0xF0|0x06;                        //滾珠開關P00設置為帶施密特上拉輸入        (作為外部中斷)
        P00DBC = 0xFF;                              //滾珠開關P00端口消抖,約250uS

        PITS0 = PITS0&0xFC|0x01;          //外部中斷0下降沿中斷
        EX0=1;                                                           //開外部中斷
        EA=1;                                                        //開總中斷

        cont_col = 0;  //顏色索引初值
        display_off();

        while(1)     //主程序中只檢測按鍵
        {
                cont_rock = 0;
                delayMs_16Mhz(1000);
                if(cont_rock == 0) //檢測1秒內搖擺次數,如無則顏色回初值
                {
                        cont_col = 0;
                }
                else
                {
                        //顏色索引每秒加一改變一次顏色
                        if(cont_col >=5)                          //暫用6種顏色
                        {
                           cont_col = 0;
                         }
                         else
                         {
                                 cont_col ++;        //改變顏色
                         }
                         //按索引賦顯示顏色分量值
                        col_r = 0;
                        col_g = 0;
                        col_b = 0;
                        switch(cont_col)
                        {
                           case 0: col_r = 0x20;break;
                           case 1: col_g = 0x20;break;
                           case 2: col_b = 0x20;break;
                           case 3: col_r = 0x20;col_g = 0x20;break;
                           case 4: col_g = 0x20;col_b = 0x20;break;
                           case 5: col_b = 0x20;col_r = 0x20;break;
                           default: cont_col=0; col_r = 0x20;break;
                        }
                }               

        }

}


評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:57657 發表于 2021-3-1 11:38 | 顯示全部樓層
ws2812b 并不適合制作搖搖棒(最多只能顯示出幾種顏色),因為內部RGB芯片是通過PWM驅動的LED,只有線性驅動才可以搖出1600萬種顏色。
回復

使用道具 舉報

ID:885138 發表于 2021-3-1 12:33 來自手機 | 顯示全部樓層
npn 發表于 2021-3-1 11:38
ws2812b 并不適合制作搖搖棒(最多只能顯示出幾種顏色),因為內部RGB芯片是通過PWM驅動的LED,只有線性驅動 ...

是的,所以只能玩玩。程序里僅設了6種顏色,比單色或雙色稍強一點。不過線路的確比沒芯片的LED簡單些

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:885138 發表于 2021-3-1 13:41 | 顯示全部樓層
一手拿手機另一只手搖,視頻有點晃眼哈

VID_20210301_132547.zip

18.04 MB, 下載次數: 31, 下載積分: 黑幣 -5

回復

使用道具 舉報

ID:63570 發表于 2021-3-1 16:08 | 顯示全部樓層
npn 發表于 2021-3-1 11:38
ws2812b 并不適合制作搖搖棒(最多只能顯示出幾種顏色),因為內部RGB芯片是通過PWM驅動的LED,只有線性驅動 ...

請教,為什么PWM的只能顯示幾種顏色,而線性的可以真彩,是什么原理呢?謝謝。
回復

使用道具 舉報

ID:885138 發表于 2021-3-1 20:42 來自手機 | 顯示全部樓層
yanhengbo 發表于 2021-3-1 16:08
請教,為什么PWM的只能顯示幾種顏色,而線性的可以真彩,是什么原理呢?謝謝。

pwm是脈寬調制,即調節亮與滅的時間,亮時100%亮度,滅時0%亮度,理論上需要25%亮度時就讓亮的時長占一個周期的25%,當時周期不能太大否則會感覺到閃爍。
現在看三色燈,如需RGB分量大小之比為3:2:1,pwm模式下其實是三色的時長為3:2:1,在燈珠靜止時,那看起來是亮度之比(混色成某種橙黃色);而搖搖棒是動態的,所以看起來是擺動寬度之比,即此比例下實際一個周期有三段顏色,第一段RGB都亮(白色),第二段為R+G(黃色),第三段為R(紅色),而不是合成色。
所以ws2812之類的彩燈如用于搖搖棒,實際只能顯示8種顏色的點陣(R,G,B,R+G,R+B,G+B,R+G+B和0,即紅綠藍黃橙青白黑),數值的大小可改變8色之1的點陣掃過的寬度,但不能產生新的顏色。
綜上,用ws2812燈時,靜的時候可以混色,但不能產生平面效果;搖的時候可以產生平面效果,但只有8色。8色顯字或簡單圖案,玩玩是夠了,但真彩還是別想了。
一不小心在手機上輸了這么多字 :-P

評分

參與人數 1黑幣 +40 收起 理由
admin + 40 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:143767 發表于 2021-3-2 11:32 | 顯示全部樓層
WS2812比較適合Arduino驅動,WS2812要求的頻率要高一點
回復

使用道具 舉報

ID:58937 發表于 2021-3-2 17:07 | 顯示全部樓層
好作品 謝謝分享
回復

使用道具 舉報

ID:390416 發表于 2021-3-2 22:05 | 顯示全部樓層
dj3365191 發表于 2021-3-2 11:32
WS2812比較適合Arduino驅動,WS2812要求的頻率要高一點

89單片機也可以驅動的,89C52驅動WS2812 http://www.zg4o1577.cn/bbs/dpj-170855-1.html
回復

使用道具 舉報

ID:390416 發表于 2021-3-2 22:07 | 顯示全部樓層
xxd0708 發表于 2021-3-1 13:41
一手拿手機另一只手搖,視頻有點晃眼哈

你需要DIY一個手機支架,推薦使用80mm的PVC排水管,榮耀10手機 插進去剛剛好
回復

使用道具 舉報

ID:390416 發表于 2021-3-2 22:11 | 顯示全部樓層
npn 發表于 2021-3-1 11:38
ws2812b 并不適合制作搖搖棒(最多只能顯示出幾種顏色),因為內部RGB芯片是通過PWM驅動的LED,只有線性驅動 ...

關鍵是 PWM合成的顏色 也足夠了,真要搞出1600萬色,你眼睛能分辨出來?
回復

使用道具 舉報

ID:63570 發表于 2021-3-3 09:52 | 顯示全部樓層
xxd0708 發表于 2021-3-1 20:42
pwm是脈寬調制,即調節亮與滅的時間,亮時100%亮度,滅時0%亮度,理論上需要25%亮度時就讓亮的時長占一個 ...

這么說,WS2812燈里面的驅動是三顆R,G,B燈共用的一個PWM?分不同時段驅動3顆燈嗎?我理解是3個PWM同時驅動的R,G,B,如果是3個PWM同時驅動,應該就是真彩了吧?
回復

使用道具 舉報

ID:885138 發表于 2021-3-3 13:19 來自手機 | 顯示全部樓層
yanhengbo 發表于 2021-3-3 09:52
這么說,WS2812燈里面的驅動是三顆R,G,B燈共用的一個PWM?分不同時段驅動3顆燈嗎?我理解是3個PWM同時驅 ...

ws2812b有三路獨立的8位pwm,如果燈珠靜止,占空比就表現為該靜止點的三路燈的亮度,理論可顯24位真彩。
但ws2812b的pwm周期為2.5mS(400Hz),未考慮到快速運動場景。故燈珠快速運動時(平移與旋轉),占空比就表現為一個周期內運動幅度中亮燈狀態運動長度的大小,而不能表現為某個單點的亮度,即在某個具體點三路燈各有亮或暗兩種狀態,共2的3次冪=8種組合,也就是只有8色之一。
所以我前文所指出的,靜可顯真彩但做不了搖搖棒或旋轉屏,動可做搖搖棒或旋轉屏但只有8色。
回復

使用道具 舉報

ID:63570 發表于 2021-3-3 14:04 | 顯示全部樓層
xxd0708 發表于 2021-3-3 13:19
ws2812b有三路獨立的8位pwm,如果燈珠靜止,占空比就表現為該靜止點的三路燈的亮度,理論可顯24位真彩。
...

那是否可以理解為:低于400HZ可以顯示真彩,高于400HZ,就是8位色?
回復

使用道具 舉報

ID:885138 發表于 2021-3-3 14:16 來自手機 | 顯示全部樓層
yanhengbo 發表于 2021-3-3 14:04
那是否可以理解為:低于400HZ可以顯示真彩,高于400HZ,就是8位色?

應該是指2.5mS周期內燈珠基本不動時可顯真彩,與運動速度有關
回復

使用道具 舉報

ID:69115 發表于 2021-3-10 01:41 | 顯示全部樓層
樓主說的很好 PWM 亮度,在運動中顯示,就變成光點的運動長度了.
回復

使用道具 舉報

ID:698161 發表于 2023-3-27 14:31 | 顯示全部樓層
沙發備用
回復

使用道具 舉報

ID:1112801 發表于 2024-3-12 18:51 | 顯示全部樓層
npn 發表于 2021-3-1 11:38
ws2812b 并不適合制作搖搖棒(最多只能顯示出幾種顏色),因為內部RGB芯片是通過PWM驅動的LED,只有線性驅動 ...

線性驅動用什么LED
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美精品日韩精品国产精品 | 久久免费精品视频 | 国产精品毛片av一区 | 久久国产精品久久久久久久久久 | 中文字幕一区二区三区在线观看 | 国产片侵犯亲女视频播放 | 另类亚洲视频 | 亚洲视频在线一区 | 四虎最新视频 | 亚洲区视频| 日本国产一区二区 | 亚洲日本激情 | 在线日韩精品视频 | 亚洲国产一区二区视频 | 伊人免费在线 | 欧美嘿咻 | 日韩二三区| 亚洲国产精久久久久久久 | 国产福利在线 | 免费激情 | 做a网站| 欧美精品一区二区三区在线播放 | 国产精品久久久久久久粉嫩 | 亚洲女人天堂成人av在线 | 一级高清视频 | 日韩在线视频免费观看 | 91在线视频一区 | 午夜影晥 | 国产精品成人久久久久a级 久久蜜桃av一区二区天堂 | 超碰av人人 | 在线观看国产视频 | 欧美一区永久视频免费观看 | 全免费a级毛片免费看视频免 | 99免费在线观看 | 男人天堂久久 | 狠狠久| 成人亚洲| 亚洲精品欧美一区二区三区 | 亚洲成人福利在线观看 | 先锋资源网站 | 天天草天天|