基於51單片機的旋轉LED

大三的期末設計(大三好幾個期末設計),當初感覺這個東西挺酷炫的,就去搞了一下,然而未曾料到,大三期末太多設計,同時51單片機的項目以前有做過,就沒花很多時間在這個設計上,做了一週多,效果差強人意。

先來看看視頻效果:鏈接:http://pan.baidu.com/s/1gfiESpX 密碼:1f3w

本來可以更好的,還想在垂直面上加一排led做爲顯示的,結果就是學校的PCB板太重,加上去的話電機轉速不夠,所以就只有水平面的顯示。

下面給出製作方案,僅供參考:

(1)功能框架:


圖1、整體框架

(2)使用器件:

①89C52單片機(由於51內部儲存有限,選擇52型號)、DS1302芯片;

②紅外接收模塊(一體化紅外接收頭、1.2K電阻);

③紅外對管(接收與發射各一個);

④紅LED燈16個、電容電阻若干;

⑤無線供電線圈一對;

⑥直流電機、底座硬件。

二、電路工作原理:

人眼具有視覺暫留的錯覺,無法區分間隔小於0.1s的圖像。 

因此,我們所要設計的旋轉時鐘大體有兩部分構成:單片機控制系統部分和電機轉動部分。 

單片機控制部分由一系列的二極管及單片機最小系統組成。主要用來控制各二極管的亮與滅、計時等,以正確顯示相應時間所對應的數字。 

電機轉動部分是一個直流電機,帶上負載後,轉速有所下降,電機帶動單片機系統板和外圍LED板轉動。 

這樣,旋轉時鐘的基本框架就已構成:通過單片機控制二極管的亮滅,利用電機的轉動,使人眼產生視覺暫留的錯覺,呈現出數字時鐘的走動的圖像。

三、編程流程圖:


圖2、編程流程圖

 

四、製作過程:

(1)仿真原理圖:

圖3、仿真原理圖

LED以共陽相接,無線供電模塊包括整流電路。

(2)PCB製作:

圖4.1、PCB製作

左邊爲單片機主控模塊和DS1302數字芯片模塊,左下爲整流電路,右邊爲LED顯示模塊。由於提供的PCB爲單面板,在背面會有幾個跳線,最終只打印頂層(紅色)。中間三塊的銅片是軸心位置。後期又另外加上了兩個模塊的小板。

(3)硬件搭建:

①底座部分:

圖5.1、底座部分

底座由兩塊塑料板構成,主要以平整、寬大來儘量保證旋轉時能保持整體穩定,各支撐點使用膠槍加固。

②旋轉部分:


圖5.2.1、正面

圖5.3、旋轉部分反面

由於單面板的限制,有些電路連接需要通過跳線連接,軸心(即感應線圈)兩側重量基本一致,紅外對管接收調節模塊爲了使信號更加靈敏。

③整體:

圖6、整體

最後經過各種測試修改後,我們不得不重新制作新的PCB,模塊大致相同,與圖6.1相比少了側面LED模塊(由於太重,軸心太靠一邊,如若要使得整體左右平衡需要添加更多的重物,從而使得電機無法帶動這麼重的板子)和放棄了74595芯片(由於放棄了側面板,單片機引腳完全夠用,所以沒必要用595驅動)。

(4)調試以及問題解決:

①結構問題:

我們認爲,整機的機械結構是決定作品成敗的關鍵。經過試驗,結構強度對穩定性影響很大,因此採用四個長螺絲爲支架,以半徑較大的厚塑料闆闆爲底,同時對轉盤進行平衡調節,基本解決了轉動的穩定性問題。

②供電問題:

由於我們的電路板是隨主框架一起高速旋轉的,所以不可能使用導線進行供電,因爲這樣會把導線纏上。於是採用無線供電,用兩個感應線圈在旋轉中產生供應的電,再經過整流電路來產生穩定的5V電壓以供單片機以及其他元件的供電。

③、信號傳輸問題 

由於控制單片機是在旋轉的支架上,從外部到單片機的數據傳送也成了一個問題。數據的傳輸不能採用電刷來進行,因此採用了紅外傳輸的方式。使用了帶有放大和解調功能的接收模塊,很好地解決了這一問題,但由於高速旋轉,遙控信號的接收有時也不太靈敏。 

④、同步問題 

顯示的圖像或文字要穩定,同步是關鍵。要達到同步的目的,同步信號的取得是關鍵。最後使用了紅外對管以及增加靈敏度的比較器模塊來校準每一圈,達到很好的效果。

下面給出代碼:

#include<reg52.h>

#include"HW.h"

#define ucharunsigned char

#define uintunsigned int

uchar yiwei=0;   //移位

uchar KSZ=0;     //默認從第0個字開始移動

uchar ZS;            //控制顯示字數

uchar ZQLC=0;           // 逐圈亮參數

uchar ZQMC=0;         // 逐圈滅參數

bit YW               =0;

bit start      =0;

bit done     =0;

void show(ucharzishu,uchar lieshu,uchar a[][48],bit b);

void ZQL();

void ZQM();

void shownum(uchara[24]);

void init()

{

       EX0=1;

        EX1=1;

        IT0=0;

        IT1=0;

        EA=1;       

}

void delay(uint a)

{

        uint b;

        for(a;a>0;a--)

                  for(b=0;b<112;b++)

                  ;

}

void delayus(uinta)

{

        while(a--);

}

void main()

{

        uint GNCST;

        init();;

        P2=0X7f;

        P0=0Xff;

       IRinit();

        //Initial_DS1302();

    while(1)

    {

                  IRstart();

                  switch(GNCS)

                  {

                            case 0X01:show(ZS,24,zimo,YW);break;//0 顯示相應的按鍵值

                            case 0x02:shownum(shuzi[1]);break;//1

                            case 0x03:shownum(shuzi[2]);break;//2

                            case 0X04:shownum(shuzi[3]);break;//3

                            case 0X05:shownum(shuzi[4]);break;//4

                            case 0X06:shownum(shuzi[5]);break;//5

                            case 0X07:shownum(shuzi[6]);break;//6

                            case 0X08:shownum(shuzi[7]);break;//7

                            case 0X09:shownum(shuzi[8]);break;//8

                            case 0X0a:shownum(shuzi[9]);break;//9

 

                            case0X0b:{ZS--;GNCS=GNCST;};break;//"-"

                            case 0X0c:{ZS++;GNCS=GNCST;};break;//+

                            case 0X0d:{YW=!YW;GNCS=GNCST;};break;//   >||暫停

                            case 0X0e:ZQL();break;//   |<<

                            case 0X0f:ZQM();break;//    >>|

             default:

                            {

                                   P0=0X00;

                                    P2=0X00;

                                    };break;

                                  

                   }

                   if(ZS>8)ZS=8;

                   if(ZS<1)ZS=1;

                   GNCST=GNCS;

        }

}

       

 

void DuiGuan(void)interrupt 0//紅外對管

{

        start   =1;           

}

 

void ZQL()//逐圈亮

{

        if(start)

        {

               EX0=0;

                  if(ZQLC<8)                                                      

                  {

                           P0=(0x7f>>ZQLC);

                           P2=0xff;

                  }elseif((ZQLC>7)&&(ZQLC<16))

                  {

                           P2=(0x7f>>(ZQLC%8));

                           P0=0x00;  

                  }

                  else

                           ZQLC=0;  

                  ZQLC++;

                  delay(200);

                  start=0;

        }

        EX0=1;

}

 

void ZQM()//逐圈滅

{

        if(start)

        {

               EX0=0;

                  if(ZQMC<8)                                                     

                  {

                           P0|=(0x80>>ZQMC);

                           P2=0x00;

                  }elseif((ZQMC>7)&&(ZQMC<16))

                  {

                           P2|=(0x7f>>(ZQMC%8));

                           P0=0xff;             

                  }

                  else

                                    ZQMC=0; 

                  ZQMC++;

                 delay(200);

                  start=0;

        }

        EX0=1;

}

void shownum(uchara[24])

{

        uchar i;

        if(start)

        {

               EX0=0;

                  for(i=0;i<12;i++)

                  {

                           P0=a[i*2]; 

            P2=a[i*2+1];         

                           delayus(10);

                           P2=0xff;

                           P0=0xff;

                  }      

                  start=0;

        }

        EX0=1;     

}

void show(ucharzishu,uchar lieshu,uchar a[][48],bit b)

{

        uchar i,j,yiweit1,yiweit2;

        if(start) //紅外接收管 判斷起始位

        {       

             EX0=0;

                            yiweit1=yiwei;

                            for(j=KSZ;j<zishu;j++)

                            {

                                     for(i=yiweit1;i<lieshu;i++) //每轉一圈  前進一列

                           {                    

                                  P0=a[j][i*2]; 

                                  P2=a[j][i*2+1];       

                                                       delayus(10);

                                                       P2=0xff;

                                                       P0=0xff;             

                           }

                                     yiweit1=0;

                            }

                            for(j=0;j<KSZ+1;j++)

                            {

                                   if(j==KSZ)

                                              yiweit2=yiwei;

                                    else

                                              yiweit2=lieshu;

 

                                    for(i=0;i<yiweit2;i++)

                                              {                   

                                                       P0=a[j][i*2]; 

                                                       P2=a[j][i*2+1];  

                                                       delayus(10);

                                                       P2=0xff;

                                                       P0=0xff;             

                                              }

                             }

                           if(b)

                           {

                                     yiwei++;

                                     if(yiwei==lieshu)

                                     {

                                            KSZ++;

                                              yiwei=0;

                                     }

                                     if(KSZ==zishu)

                                     {

                                              KSZ=0;

                                              yiwei=0;

                                     }

                            }

                           start=0;

        }

                  EX0=1;

        }      

 

還有紅外解碼的代碼就不給出來了,想了解的網上搜索一下,大把的資料
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章