工程師表白神器--炫彩心形DIY
阿新 • • 發佈:2019-01-25
這段時間做了個玩具,用彩色LED搭建了一個心形圖案,並用STC51微控制器驅動,實現心形LED炫彩閃動,超級炫酷的,總工有32個燈,使用了微控制器的所有IO口,可以靈活控制每個LED的閃爍,然後配上適合的音樂,絕對是屌絲工程師表白神器,先上兩張圖看看:
接下來簡單說下實現過程:
將32個LED分成4組LED_P0,LED_P1,LED_P3,LED_P2,每一組代表8個LED燈,也就是講心形分成4個部分, 如下圖所示,這樣,我們只需操作這些值,然後將這些值對應到相應的IO口上就可以了
為了便於操作,我們對每一組單獨做了幾個動作,然後將這些動作已多種方式結合起來,就可以啦。
基本動作:
uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//LED從低位往高位移 uchar code table1[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED從高位往低位移 uchar code table2[]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00};//LED從1個亮到8個都點亮(從低位往高位) uchar code table3[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};//LED從1個亮到8個都點亮(從高位往低位) uchar code table4[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};//LED從8個全亮到一個都不亮(從低位往高位) uchar code table5[]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};//LED從8個全亮到一個都不亮(從高位往低位) uchar code table6[]={0xfe,0xfc,0xfa,0xf6,0xee,0xde,0xbe,0x7e};//LED從低位往高位移(最低位始終為0) uchar code table7[]={0x7f,0x3f,0x5f,0x6f,0x77,0x7b,0x7d,0x7e};//LED從高位往低位移(最高位始終為0)
下面我們將LED順時針旋轉一週,如下:
void disp1() { for(i=0;i<8;i++) { LED_P2=table1[i]; Display(100); } LED_P2=0xff; for(i=0;i<8;i++) { LED_P3=table1[i]; Display(100); } LED_P3=0xff; for(i=0;i<8;i++) { LED_P1=table1[i]; Display(100); } LED_P1=0xff; for(i=0;i<8;i++) { LED_P0=table1[i]; Display(100); } LED_P0=0xff; }
為了方便佈線,我們的LED燈的位置並不是個微控制器IO口嚴格對應的,所以我們要在顯示函式裡面做好對應關係,一起重新整理顯示:
//將LED_P0,LED_P1,LED_P3,LED_P2的值的對應到具體IO口上,並延時 void Display(uint time) { P0 = ((LED_P0 & 0xfe)>>1) + ((LED_P1 & 0x01)<<7); P1 = ((LED_P1 & 0xfe)>>1) + ((LED_P3 & 0x01)<<7); P3 = ((LED_P3 & 0xfe)>>1) + ((LED_P2 & 0x01)<<7); P2 = ((LED_P2 & 0xfe)>>1) + ((LED_P0 & 0x01)<<7); Delayms(time); }
將LED順時針旋轉一週只是一週場景,這裡可以t提供40多種場景,可以自由搭配順序哦,實現方法也是很簡單的:
#define SCENE_COUNT 20//定義迴圈播放發的數量
//可自定義場景,按場景順序播放多種狀態
uchar scene[SCENE_COUNT] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
選擇要顯示的場景函式:
void DispStatus(unsigned char index)
{
switch(index)
{
case 0 :disp0() ; break;
case 1 :disp1() ; break;
case 2 :disp2() ; break;
case 3 :disp3() ; break;
case 4 :disp4() ; break;
case 5 :disp5() ; break;
case 6 :disp6() ; break;
case 7 :disp7() ; break;
case 8 :disp8() ; break;
case 9 :disp9() ; break;
case 10 :disp10() ; break;
case 11 :disp11() ; break;
case 12 :disp12() ; break;
case 13 :disp13() ; break;
case 14 :disp14() ; break;
case 15 :disp15() ; break;
case 16 :disp16() ; break;
case 17 :disp17() ; break;
case 18 :disp18() ; break;
case 19 :disp19() ; break;
case 20 :disp20() ; break;
case 21 :disp21() ; break;
case 22 :disp22() ; break;
case 23 :disp23() ; break;
case 24 :disp24() ; break;
case 25 :disp25() ; break;
case 26 :disp26() ; break;
case 27 :disp27() ; break;
case 28 :disp28() ; break;
case 29 :disp29() ; break;
case 30 :disp30() ; break;
case 31 :disp31() ; break;
case 32 :disp32() ; break;
case 33 :disp33() ; break;
case 34 :disp34() ; break;
case 35 :disp35() ; break;
case 36 :disp36() ; break;
case 37 :disp37() ; break;
case 38 :disp38() ; break;
case 39 :disp39() ; break;
case 40 :disp40() ; break;
case 41 :disp41() ; break;
default: break;
}
}
主函式迴圈播放設定好的場景
void main()
{
int i;
while(1)
{
//按照自定義場景迴圈播放
for(i=0;i<SCENE_COUNT;i++)
{
DispStatus(scene[i]);
}
}
}
這樣一個表白神器就完成了,有需要的或者有其他問題的親猿們,如果有需要可以直接評論我就好了哦。