我的賬戶
中國電子DIY

科技成就未來

親愛的游客,歡迎!

已有賬號,請

如尚未注冊?

【光立方】初級教程,含 原理圖+源代碼+經驗

  [復制鏈接]
42192 94
愛上科技 發表于 2015-5-2 09:28:48 | 只看該作者 |閱讀模式 打印 上一主題 下一主題

光立方,我在三年前從一個國外網站上就見到了。那時候剛開始玩電子,就心血一熱,開始做光立方。費了一個星期的功夫才把主題的LED顯示體搭建完成了,而且當時的焊接功底實在不敢恭維。(后面有圖為證)

后來由于畢業的緣故,沒有繼續做下去,光立方被我當做裝飾品放再書桌上。

今年上半年的時候,看到了很多人的作品,想起我那個光立方。回憶起當年的時光,決定將它繼續做完。

很順利,不管是硬件搭建還是軟件編程。

我看了很多教程,相比來說,我最開始看的老外的比較好。他們用的元件并不是我們常用的元件,但是上面的理論講解很重要。

如果真的想做好,必須懂得原理,而不是一味的仿造。不知道有哪些朋友已經做過很好的教程,我把我的想法分享出來,供大家參考借鑒。

概要

首先,我的作品并沒有完成多么炫的效果,我只是搭建了一個設計的平臺。尤其是比較容易修改的顯示程序,要炫的效果,完全可以大家自己設計!!!!

第二,硬件上,可能與平時大家所見的不同(受多個設計方案的影響,沒選好一個方案),但我會介紹如何元件替代(包含單片機、行列驅動芯片的替換)。

第三,內容寫得比較抽象,希望大家仔細看,并且多看別人作品,多看程序代碼,先思考了再問,不是說不想回答,只是不想回答沒有思考過的問題。

第四,設計屬于睡神耗子自己所想的,所以和你以前見過的光立方可以不一樣的架構。一位網友給我看了另一種電路,確實是設計精妙。不過本設計對于設計程序,以及理解是比較容易的。可以作為初級的教程來看。

第五,設計使用了大量網絡的上圖片資源。由于自己在制作的時候沒有留下照片,而且說實話,做得挺難看的!所以不多配自己的圖了。

作品展示

設計的挺難看,各位大俠就別計較了,各位菜鳥就知道有這么幾個部分組成就可以了。






這是我仿造的杜洋的光立方顯示效果(懶,未仿造全部,部分效果也不好)

以上只是說明我能造出來啊!!!

這是源文件(修正電路圖的錯誤):

光立方.rar (275.37 KB, 下載次數: 234)



下面是重頭戲。

第一.光立方主體焊接

這個沒有什么好法子,大家慢慢,仔細的焊接吧。考驗焊接功夫和耐性的時刻到了。

給幾個別人的圖做參考。



先找個木板鉆8*8=64個孔,(什么,你沒有木板和電鉆。那找個替換,真不行,上紙箱板)。每個孔的間距一樣,具體多長,量一下LED的負極(短的管腳)。比那個長度小大概3~5mm就差不多了(具體值,大家量一量就行了)。

然后彎管腳。為了確保光立方是個正方體,一般情況,都是彎短腳(負極)。

注意方向任意,但是所有的LED是一個方向,具體方向,就看個人喜好了。

8個LED焊接在一塊,一共焊接8條,然后將這8條的LED燈鏈的一端(短引腳沒焊接)焊接在一塊。

為了結實,再在中間及另一端焊接個銅線。注意,要保證銅線是焊接在負極(短管腳上)

這樣,一層就完成了。

總結下,焊接的要領是將一層的負極接到一塊。(當然你非要正極接一塊,也是可以的)。

如此反復,總共焊接8層,然后,將相同的長管腳焊接在一起。(或者,你一層層向上蓋樓也行~!~)。

你會發現每一層都會空余一個管腳未焊接,我就把這個管腳當做層的控制端用了。

如上圖所示,會發現每一層相同位置的LED的正極(長管腳,紅色所指的)連接在一起,相信聰明的童鞋,知道如何控制光立方的某一個燈亮了:

在正極上加正電壓,在層的控制端上加負電壓即可了。

第二:顯示原理

為了下面層驅動與陣列驅動的講解,想說明一下光立方的顯示原理。

玩過LED點陣或多位數碼管的童鞋,更容易理解——對,動態掃描原理。

其實不同層的燈是不可能同是亮的。那么人怎么感覺亮呢,只要LED等閃得足夠快,就可以了。人眼的視覺暫留大概24幀/秒(這也是為什么電影大多是這個值,請查看你電影文件的屬性)。那么只要你能夠將LED燈閃到這個速度就沒問題了。對于電路來書,μs(微妙)級是很容易實現的,所以,這不是問題。

光立方其實就相當于64*8的LED點陣。你理論上只能讓一層(64)的燈可以隨意亮滅(一直保持,并且不相互干擾)。

當一定的速度,先點亮第一層,然后再點亮第二層……一直循環,就達到你要的效果了。

寫得抽象,不懂得童鞋,去看看LED點陣,或者多位數碼管的顯示原理就可以。

第三:層驅動電路

層選,是要求這一層的控制端加負電壓(因為這一層的負極都接一塊了)。那么我們很容易的想用三極管的開關作用就可以了。對我就直接使用的三極管。

****有熱心網友發現了我的錯誤,8550是PNP型三極管,而我寫文章,畫電路都寫的NPN,我查看了下,是我自己的疏忽,真實設計是PNP,程序也是按照PNP寫的。在此,十分感謝給予批評幫助的人。*******

MCU是單片機控制,一般要串個電阻,用來限流,這里講原理,就不畫了(具體去看附件中的原理圖)。Layer_x指某一層的控制端。加了一個上拉電阻,保證平時狀態下控制端處在高電壓(那樣就不會亮燈了。)

當MCU輸出高時,PNP三極管就導通了,Layerer_x就連接到地上,那么層選就打開了。

PNP型三極管有很多,比如我用的就是S8550,相信許多童鞋是用過的。

有些童鞋說,他們見別人用的不是三極管,而是ULN2803。我以前是沒用過的,查了查:是八路NPN達林頓連接晶體管,也就是說其實里面就相當于集成了8個三極管,用起來更方便。所以,大家手頭有什么就用什么唄。

啥,ULN2803怎么用?看下圖,我懶得畫封裝圖了,用一個插座代替了,管腳順序可沒有改,別照抄啊!!!!

我的設計里,用了16個S8550,2個一組。原因是為了防止一個三極管承受不了這么大的電流(64個LED燈的電流)。

第四.陣列驅動

這是我起的名字,也就是一層64個燈的驅動。

64個燈,驅動那是相當麻煩了,用單片機直接驅動是不現實的,管腳不夠,電流太大。那么我們考慮拓展單片機的IO口。

用很多芯片是可以用的:例如HC164, HC377,HC573,HC574,HC595等等。只要有8位輸出就可以。大家用的比較多的應該是HC573,最初的時候我照著葫蘆畫瓢,非要買HC574。它倆沒有什么大區別,只是鎖存的信號不一樣罷了。

借用一個574的圖(573一樣的接法,CLK改為HC573的LE即可)。有八片HC574,每一個HC574可以輸出8位,這樣就可以同時輸出64位了,對應64個燈。

HC138是為了節省管腳的,我圖省事,就直接用單片機的管腳接每個片子。

數據線是共用的,一次給一個片子寫數據,輪流寫,將所有的片子寫完。那么陣列驅動數據就完成了。

當使能輸出(許多片子有OE端),層選打開時,就可以點亮特定的燈了。

附HC164和HC595的驅動圖。這兩個片子都是串行轉并行了,使用的單片機管腳更少一些!!

注意:所有輸出端要加限流電阻,至于加多大,要看你的LED燈了。一般情況下的直插LED燈,紅色的加的電阻大一些,綠色的小一些,實際情況自己測試就可以了。

一定要先計算一下你需要多大的電流,因為這關系到你選用多大電流的電源。

當然,一般情況下,最多亮64個LED(瞬間只能亮64個)。一般的充電器類都能達到這個電流水平(什么,你要用電池!別扯了***)。

第五.控制板

可以選用的單片機是很多的。

考慮管腳夠用,至少也要十幾個IO口吧。用個DIP40,LQFP32妥妥的。

51.AVR.PIC……隨便哪個都可以,方便、易學、好買上選擇,用STC的51就行了。我用了庫存的STC12C5A60S2,相信這個單片機很多人都在用。

當然你用STC89C系列或者STC15系列也是可以的,他們區別在定時上,我使用的是定時器,你可以用STC給的工具來修改定時時間。


第六.程序

相信很多人都不喜歡這個。

見好多童鞋做好的電路,到處找程序。為了不改程序,能照搬電路就照搬。當出了問題也不知道是硬件還是軟件的問題。

好吧,恰好我是苦逼的程序員。好歹也寫了兩年程序。

以下是講解,其實講得不好,因為自己的水平,還有程序這事就是多磨多練的功夫。

我用的是KEILC51,相信很多童鞋,看到這么多文件就傻了。不用擔心,文件多了,許多文件你根本不用理解。

Main,是主程序。App是應用文件,comAssistant是串口助手,stc12cIntProcess是中斷函數。還有一堆displayxx是顯示效果函數。

簡單的說,主程序調用APP文件中的函數,App函數又調用displayxx(xx表示01,02什么的)函數,來顯示特效。

由于我使用的是HC574+MCU層選,但是有很多其他方式可以使用。修改app.c文件中的CubeLoop函數即可。由于各種方案很多,如有需求,請留言請教之。

我將顯示效果設計成8*8的數組。因為數組元素是unsigned char(uint8_t)型,也就是說每一位表示一個LED燈。你只要在displayxx函數里修改cubeBuf[8][8]這個數組即可。 說明一下,這個數組是如何對應的光立方的LED的。數組每一個元素(char型),對應每一層所有相同位置的LED燈(即正極相連的),請看第7圖那個紅色對應的一條燈鏈。 還有,我為了方便設計,將更新顯示最小的單位是100ms,即0.1s。也就是說,你想顯示刷新的速度最快是100ms,其實這個時間是相對比較長了,可以改短一點,程序在stc12cIntProcess.c中第61行:

if(++cubeCounter>10)

{

cubeCounter = 0;

cubeUpdateFlag = TRUE;

}

把10改小一點就可以了。




參與人數 3貢獻 +8 刀幣 +20 收起 理由
逆天小白兔 + 8 + 5
中心小學 + 5 贊一個!
diyhome + 10 支持DIY精神!

查看全部評分總評分 : 貢獻 +8 刀幣 +20

收藏
收藏27
分享
分享
支持
支持2
反對
反對0

精彩評論94

跳轉到指定樓層
推薦
 樓主| 愛上科技 發表于 2015-5-2 09:29:07 | 只看該作者
  1. /* Extern Fuction -------------------------------------------------------------*/

  2. extern bool_t Display01(void);

  3. extern bool_t Display02(void);

  4. extern bool_t Display03(void);

  5. extern bool_t Display04(void);

  6. extern bool_t Display05(void);

  7. extern bool_t Display06(void);

  8. extern bool_t Display07(void);

  9. app.c文件中的void CubeBufReload()函數式調用顯示函數的地方。

  10. /*Reload graphical or switch grahical*/

  11. switch(cubeGraphical)

  12. {

  13. case GRAPH_01:

  14. if( TRUE == Display01())

  15. {

  16. cubeGraphical = GRAPH_02;

  17. cubeStage = 0xFF;

  18. }

  19. break;

  20. case GRAPH_02:

  21. if( TRUE == Display02())

  22. {

  23. cubeGraphical = GRAPH_03;

  24. cubeStage = 0xFF;

  25. }

  26. break;

  27. case GRAPH_03:

  28. if( TRUE == Display03())

  29. {

  30. cubeGraphical = GRAPH_04;

  31. cubeStage = 0xFF;

  32. }

  33. break;

  34. case GRAPH_04:

  35. if( TRUE == Display04())

  36. {

  37. cubeGraphical = GRAPH_01;

  38. cubeStage = 0xFF;

  39. }

  40. break;

  41. case GRAPH_05:

  42. if( TRUE == Display05())

  43. {

  44. cubeGraphical = GRAPH_06;

  45. cubeStage = 0xFF;

  46. }

  47. break;

  48. case GRAPH_06:

  49. if( TRUE == Display06())

  50. {

  51. cubeGraphical = GRAPH_07;

  52. cubeStage = 0xFF;

  53. }

  54. break;

  55. case GRAPH_07:

  56. if( TRUE == Display07())

  57. {

  58. cubeGraphical = GRAPH_01;

  59. cubeStage = 0xFF;

  60. }

  61. break;

  62. default:

  63. cubeGraphical = GRAPH_01;

  64. cubeStage = 0xFF;

  65. break;

  66. }

  67. 函數很長,不用看這么多,看一個即可。

  68. case GRAPH_07:

  69. if( TRUE == Display07())

  70. {

  71. cubeGraphical = GRAPH_01;

  72. cubeStage = 0xFF;

  73. }

  74. break;

  75. 當前顯示效果為DISPLAY07,如果顯示完(TRUE==)成立,切換為顯示效果GRAPH_01,cubeStage==0XFF指將顯示階段定位到:顯示效果的第一個顯示(顯示效果是一連串的顯示組成)。CubeStage==0xFF不懂得童鞋,就照抄就可以了。

  76. 繼續,顯示效果函數的格式也是好理解的,例如Display01()

  77. bool_t Display01(void)

  78. {

  79. uint8_t i,j;

  80. bool_t endFlag = FALSE;

  81. switch(cubeStage)

  82. {

  83. case 0: //Clear all

  84. for(i = 0;i<8;i++)

  85. {

  86. for(j=0;j<8;j++)

  87. {

  88. cubeBuf[i][j] = 0x00;

  89. }

  90. }

  91. break;

  92. case 1:

  93. cubeBuf[0][7] = 0x01;

  94. break;

  95. case 2:

  96. cubeBuf[0][6] = 0x01;

  97. break;

  98. case 3:

  99. cubeBuf[0][5] = 0x01;

  100. break;

  101. case 4:

  102. cubeBuf[0][4] = 0x01;

  103. cubeBuf[0][7] = 0x00;

  104. break;

  105. case 5:

  106. cubeBuf[0][3] = 0x01;

  107. cubeBuf[0][6] = 0x00;

  108. break;

  109. case 6:

  110. cubeBuf[0][2] = 0x01;

  111. cubeBuf[0][5] = 0x00;

  112. break;

  113. case 7:

  114. cubeBuf[0][1] = 0x01;

  115. cubeBuf[0][4] = 0x00;

  116. break;

  117. case 8:

  118. cubeBuf[0][0] = 0x01;

  119. cubeBuf[0][3] = 0x00;

  120. break;

  121. case 9:

  122. cubeBuf[1][0] = 0x01;

  123. cubeBuf[0][2] = 0x00;

  124. break;

  125. case 10:

  126. cubeBuf[2][0] = 0x01;

  127. cubeBuf[0][1] = 0x00;

  128. break;

  129. case 11:

  130. cubeBuf[3][0] = 0x01;

  131. cubeBuf[0][0] = 0x00;

  132. break;
  133. case 12:

  134. cubeBuf[4][0] = 0x01;

  135. cubeBuf[1][0] = 0x00;

  136. break;

  137. case 13:

  138. cubeBuf[5][0] = 0x01;

  139. cubeBuf[2][0] = 0x00;

  140. break;

  141. case 14:

  142. cubeBuf[6][0] = 0x01;

  143. cubeBuf[3][0] = 0x00;

  144. break;

  145. case 15:

  146. cubeBuf[7][0] = 0x01;

  147. cubeBuf[4][0] = 0x00;

  148. break;

  149. case 16:

  150. cubeBuf[7][0] = 0x03;

  151. cubeBuf[4][0] = 0x00;

  152. break;

  153. case 17:

  154. cubeBuf[7][0] = 0x07;

  155. cubeBuf[5][0] = 0x00;

  156. break;

  157. case 18:

  158. cubeBuf[7][0] = 0x0F;

  159. cubeBuf[6][0] = 0x00;

  160. break;

  161. case 19:

  162. cubeBuf[7][0] = 0x1F;

  163. break;

  164. case 20:

  165. cubeBuf[7][0] = 0x3F;

  166. break;

  167. case 21:

  168. cubeBuf[7][0] = 0x7F;

  169. break;

  170. case 22:

  171. cubeBuf[7][0] = 0xFF;

  172. break;

  173. case 25:

  174. endFlag = TRUE;

  175. break;

  176. default:

  177. break;

  178. }

  179. return endFlag;

  180. }

復制代碼
至于顯示效果的設計,修改displayxx.c文件即可。每一個文件中都只有一個bool_t Display01(void)程序,其中序號01對應displayxx.c文件的序號。該函數名一定要在display.h中聲明,這樣app.c文件才能調用。

這個有25個顯示面組成的。

也就是每一個顯示面都停留100ms,當然,你可以讓多個顯示面顯示一個效果。

注意的是最后一個顯示面一定要有這句話endFlag = TRUE;,這是說明這個顯示效果結束了。

這樣,程序我就解釋完了,不過很抽象,大家想理解,就多研究程序,不懂就問。

我稍講一下編譯的問題,很多童鞋經常問為什么編譯不出來,其實IDE已經告知的很清楚了。不懂就去網上搜搜,再不懂留言,至于像undefined這種編譯錯誤最好不要問了。。。

還有很多人找不到代碼的位置——啥,用搜索啊!KEIL工具欄有個望遠鏡的哪里有個輸入框就是,windows下的程序基本上都是ctrl+F鍵可以直接調用搜索的!還有,跟蹤函數,你看到一個函數,不知道函數體在哪里?點擊到函數名中,右擊選“go to define……”就可以了。睡神耗子先幫你到這了。

還有一個關鍵的地方,做顯示庫。也就是如何給cubeBuf[][]賦值。大家自己去研究下,看看顯示出來什么樣子就可以了。我寫的顯示函數是對應視頻的顯示效果。

可以確定的是cubeBuf[][]所有元素賦值為0xFF,就是光立方全亮,都是0x01就只顯示一層,最上層或最下層,都是0x00,光立方全熄滅。

附件中有取模軟件,兼容我的程序。有點抽象。大家要好好培養自己的立體感。。。
回復

使用道具 舉報

3#
安尚科技 發表于 2015-5-2 09:42:26 | 只看該作者
樓主帖子含金量高,支持一下
回復

使用道具 舉報

4#
zsoop 發表于 2015-5-2 10:46:47 | 只看該作者
感覺沒什么用啊
只有一點觀賞效果
回復

使用道具 舉報

5#
1399109998 發表于 2015-5-2 14:21:41 | 只看該作者
謝謝樓主分享、、、、、、、、、、、、、、、、、、、
回復

使用道具 舉報

6#
sdlcwhg 發表于 2015-5-2 14:29:47 | 只看該作者
高手作品,龐大的工程,欣賞。
回復

使用道具 舉報

7#
 樓主| 愛上科技 發表于 2015-5-2 14:32:54 | 只看該作者
zsoop 發表于 2015-5-2 10:46
感覺沒什么用啊
只有一點觀賞效果

現在很多東西都是用來欣賞的,
回復

使用道具 舉報

8#
a383793621 發表于 2015-5-2 15:29:43 | 只看該作者
大贊,高手!感謝分享
回復

使用道具 舉報

9#
電子愛好者6 發表于 2015-5-2 21:37:17 | 只看該作者
謝謝樓主分享
                 
回復

使用道具 舉報

10#
逆天小白兔 發表于 2015-5-2 23:53:05 | 只看該作者
贊贊贊臟1234567890每次都要編寫字麻煩
回復

使用道具 舉報

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

本版積分規則

關注0

粉絲3

帖子7

發布主題
最新發布
推薦閱讀
關注我們
中國電子DIY官方微信

客服電話:000-000-0000

客服郵箱:776513803@qq.com

周一至周五 9:00-18:00

公司地址:深圳市南山區美麗灣大廈B座

Powered by Discuz! X3.4@ 2001-2013 Comsenz Inc.