|
近日在B站看到許多PC流光溢彩效果,如:https://www.bilibili.com/video/BV1fJ411B7bp?from=search&seid=16736407731500993634還有https://www.bilibili.com/video/BV1MC4y1h7iB?from=search&seid=16736407731500993634
效果是真不錯(cuò),還有許多制作的視頻帖子,但是。。。。。。都是基于arduino制作的,我手頭上只有一塊自制的arduino uno,個(gè)頭有點(diǎn)大,洞洞板上還沒(méi)有usb轉(zhuǎn)串口,有點(diǎn)麻煩。正好上次制作rgb環(huán)形時(shí)鐘的硬件符合條件,板上60顆燈珠,stc主控,帶usb轉(zhuǎn)串口,那么我們就用這個(gè)stc來(lái)做流光溢彩吧。
查了一下網(wǎng)上也沒(méi)有stc的教程,就自己分析了一下運(yùn)行過(guò)程。
首先由PC機(jī)運(yùn)行AmbiBox軟件抓取屏幕點(diǎn),取得rgb顏色數(shù)據(jù)。
然后由串口發(fā)送至單片機(jī)解析。
解析后的數(shù)據(jù)刷新至rgbled顯示。
過(guò)程貌似比較簡(jiǎn)單,但我們得分析其中的協(xié)議。
網(wǎng)查資料得到 Ada模式協(xié)議如下:
前三個(gè)字節(jié)分別是Ada,然后3個(gè)字節(jié)的前2個(gè)是led個(gè)數(shù),最后一個(gè)是校驗(yàn)碼,接著就是對(duì)應(yīng)個(gè)數(shù)的rgb數(shù)據(jù),每個(gè)led3字節(jié),分別對(duì)應(yīng)r,g,b。
有了這個(gè)就簡(jiǎn)單了。構(gòu)建程序流程如下
單片機(jī)主頻33.1776(為了配合串口波特率)
啟動(dòng)程序->初始化串口(定時(shí)器2,波特率115200,)->初始化led數(shù)組 ->檢測(cè)顯示(紅,綠,藍(lán)各顯示一遍)->開(kāi)啟串口接收中斷->主循環(huán)判斷如果不允許中斷則刷新rgbled,刷新完成后開(kāi)啟中斷,如果允許中斷則等待不允許中斷。
中斷函數(shù)中流程->依次判斷接收字符是否對(duì)應(yīng),如果前3個(gè)字節(jié)對(duì)應(yīng)則 接收電燈數(shù)據(jù),并將數(shù)據(jù)保存至數(shù)組中,接收一組數(shù)據(jù)完畢,失能中斷,這樣不會(huì)因中斷接收數(shù)據(jù)影響刷新。
圖我也懶得拍照了,程序上傳上來(lái),大家想做的可以自己畫(huà)個(gè)板子,燒上代碼就行了,至于AmbiBox自行某度即可。
單片機(jī)源程序如下:
- #include "stc15.h"
- #include "ws2812.h"
- uchar xdata rgb[60][3];//led數(shù)組
- uchar sendrgb=0;//預(yù)發(fā)送rgb變量
- uchar h=0,l=0,o=0;
- uchar in=0;
- void delayms(int x)
- {
- int i,j;
- for(i=0;i<x;i++)
- for(j=0;j<1000;j++);
- }
- void UartInit(void) //115200bps@33.1776MHz
- {
- SCON = 0x50; //8位數(shù)據(jù),可變波特率
- AUXR |= 0x01; //串口1選擇定時(shí)器2為波特率發(fā)生器
- AUXR |= 0x04; //定時(shí)器2時(shí)鐘為Fosc,即1T
- T2L = 0xB8; //設(shè)定定時(shí)初值
- T2H = 0xFF; //設(shè)定定時(shí)初值
- AUXR |= 0x10; //啟動(dòng)定時(shí)器2
- ES = 1; //使能串口1中斷
- }
- void initrgb(uchar st,uchar sp,uchar rg0,uchar rg1,uchar rg2)//起始位,結(jié)束位,rgb1,2,3(初始化數(shù)組)
- {
- uchar i,j;
- for(i=st;i<sp;i++)
- {
- for(j=0;j<3;j++)
- {
- switch(j)
- {
- case 0:
- rgb[i][j]=rg0;
- break;
- case 1:
- rgb[i][j]=rg1;
- break;
- case 2:
- rgb[i][j]=rg2;
- break;
- }
- }
- }
- }
- void display() //刷新rebled輸出函數(shù)
- {
- uchar i,j,k;
- for(i=0;i<60;i++)
- {
- for(j=0;j<3;j++)
- {
- sendrgb=rgb[i][j];
- for(k=0;k<8;k++)
- {
- if(sendrgb&0x80)
- st1();
- else
- st0();
- sendrgb<<=1;
- }
- }
- }
- stop();
- }
- void main()
- {
- UartInit();//初始化串口
- initrgb(0,60,50,0,0); //測(cè)試綠
- display();
- delayms(1000);
- initrgb(0,60,0,50,0); //測(cè)試紅
- display();
- delayms(1000);
- initrgb(0,60,0,0,50); //測(cè)試藍(lán)
- display();
- delayms(1000);
- initrgb(0,60,0,0,0); //清屏
- display();
- delayms(1000);
- EA = 1; //開(kāi)啟中斷,可接收數(shù)據(jù)
-
- while(1)
- {
- if(EA==0)//當(dāng)中斷關(guān)閉,表示一幀數(shù)據(jù)接收完畢
- {
- display();//將當(dāng)前數(shù)據(jù)刷新
- EA=1;//開(kāi)啟中斷,接收下一幀數(shù)據(jù)
- }
- }
- }
- void Uart() interrupt 4 //串口中斷
- {
- uchar dat=0;
- if (RI)
- {
- dat=SBUF;
- RI = 0; //清除RI位
- if(dat==0x41&&in==0)
- {
- in=1; //判斷數(shù)據(jù)0位(A)
- SBUF=in;
- return;
- }
- if(dat==0x64&&in==1) //判斷數(shù)據(jù)1位(d)
- {
- in=2;
- SBUF=in;
- return;
- }
- else if(dat==0x61&&in==2) //判斷數(shù)據(jù)2位(a)
- {
- in=3;
- SBUF=in;
- return;
- }
- else if(in==3) //讀取高位LED個(gè)數(shù)
- {
- h=dat;
- in++;
- return;
- }
- else if(in==4) //讀取低位LED個(gè)數(shù)
- {
- l=dat;
- in++;
- return;
- }
- else if(in==5) //讀取校驗(yàn)值
- {
- o=dat;
- if(o!=(h^l^0x55)) in=0; //校驗(yàn)
- else in++;
- return;
- }
- else if(in>=6) //進(jìn)入數(shù)據(jù)讀取階段
- {
- rgb[(in-6)/3][(in-6)%3]=dat;//將數(shù)據(jù)寫入數(shù)組
- if((in-6)/3==l) //根據(jù)發(fā)來(lái)的led個(gè)數(shù)確定數(shù)據(jù)是否接收完畢
- {
- in=0;
- EA=0;
- return;
- }
- else in++;
- return;
- }
- else //如果in小于6,且中途數(shù)據(jù)中斷。則重新開(kāi)始。
- {
- in=0;
- return;
- }
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
流光溢彩.rar
(35.49 KB, 下載次數(shù): 38)
2020-10-19 20:13 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|