欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: 基于STC單片機的觸摸式電鋼琴制作 [打印本頁]

作者: 橙子不灑脫    時間: 2017-5-16 13:31
標題: 基于STC單片機的觸摸式電鋼琴制作
觸摸式電鋼琴

       這個世界上有很多讓人上癮的事情,除了抽煙,喝酒這些壞毛病外,其實往51黑論壇發(fā)稿也是會上癮的。這不,我又急著來向大家展示我的作品~~話入正題,單片機制作無非聲、光、動、傳感,這次就來做點跟聲音有關的吧。這次帶來的是一款觸摸式電鋼琴,細心的網友可能會注意到,我用的是電鋼琴而不是電子琴,這兩者有區(qū)別么?我的回答是肯定的,因為這正是本作品的亮點所在。單片機演奏音樂大家肯定都不會陌生,用單片機內部的定時器,送入不同的頻率,每一個頻率對應著一個音調,然后按照事先編排好的順序驅動蜂鳴器發(fā)聲,就可以演奏出音樂了。至于電子琴只需要把不同的頻率映射到對應按鍵上即可。之所以說是電子琴,是因為這種方法只能演奏出單調的方波音頻。想不想讓聲音不再單調,而是發(fā)出動聽的鋼琴音色呢?如果想的話,請拿出你的熱情并且打開你的烙鐵的開關,跟我一起往下制作吧!
          名稱        說明       數量

        STC12C5A60S2    單片機主控     1片

        40腳芯片座    與單片機配套使用   1片

         LM386L       功放芯片       1片

       220uf電解電容  功放芯片配套使用    1個

       10uf電解電容   功放芯片配套使用     1個

        萬用電路板      大一點的     1張

          LED      任何你喜歡的顏色    1個

        耳機插座       3.5毫米       1個

         蜂鳴器      功放喇叭        1個

         排針         4PIN         1個

        長條貼紙    打印好琴鍵的圖案     1張

         釘書針     作為觸摸點使用     72個

        免刮漆包線     飛線連接       1卷

        撥動開關    耳機/功放輸出切換    1個

        0.1uf瓷片電容    電源濾波        1個

       制作所需的元器件如上表所示,本著精簡制作的原則,用到的都是很普通的元器件,數量也很少,所以硬件制作的難度不是很大。連接部分則是過錫走線加飛線,烙鐵溫度在350度左右即可。電路圖如下所示,值得說明的一點是,圖中的矩陣觸摸按鍵這里只畫出了一組,其實有三組,共起來的一端分別與  P0.0、   P2.2、P2.1連接。剩下部分的電路都很明了,有創(chuàng)造力的朋友看電路圖自行發(fā)揮就好,新手可以參考下我的布局。

先把打印好的琴鍵圖片裁好,用雙面膠貼在洞洞板上。(如圖1、2、3 )








       怎么樣,是不是很有電鋼琴的樣子?什么?你說觸摸按鍵在哪里?別著急,讓我請出下面這位特別來賓——釘書針。為了整個制作的美觀跟手感,觸摸點的選取費了我很大的心思,試了很多種導體都無法達到滿意的效果,直到有一天無意中把釘書針掉在了洞洞板上,發(fā)現它那細長又導電的身體,長度剛剛好可以插進洞洞板,才有了這個有趣的設計。如圖4、5所示,按照琴鍵的位置插好釘書針并在背面壓緊。




       以此類推,完成36個鍵不會想你想象的那么枯燥,美妙的琴聲在等著你。之后用雙面膠把揚聲器粘在板子正面,并完成揚聲器導線、單片機、下載口、撥動開關、耳機插座、LED、功放芯片以及電解電容的焊接。焊接好的樣子如圖6所示。




       接下來是觸摸按鍵矩陣后與單片機的連接了,我的方法是過錫加飛線。先把單片機正下方的一組矩陣按鍵與兩邊矩陣共起來的部分過錫連接到I/O口上(如圖7),

然后用免刮漆包線把兩側矩陣要與I/O連接的地方向中間過錫部分連接(如圖8)

       按道理制作到這里硬件的部分就大功告成了,但是在后期測試的過程中,總會有上電時亂響的問題。仔細思考后發(fā)現問題所在:因為觸摸按鍵是基于增強型51單片機的I/O口高阻狀態(tài)(下文會詳細介紹),這種狀態(tài)對電流的波動很敏感,會受到電源雜波的干擾。所以在正極跟地之間加了一個104電容,效果有很大好轉。順便一提,使用電池供電效果最好。到此就剩下載程序了,在最下方可以下載到源程序跟編譯好的HEX文件,然后用STC-ISP軟件下載到單片機里。注意,如果單片機是新的或者上一次使用連接了晶振的話,要先連接好晶振才能下載進程序。軟件設置如圖9。

到此,制作的部分全部完成了。


       如果我現在結尾,肯定有人說我不地道,因為大家最想聽的軟件原理我還沒有說明。別急,聽我娓娓道來。先說觸摸吧,前面提到I/O口的高阻狀態(tài),說到了在這種狀態(tài)下I/O口對電流很敏感,那是不是只要接觸I/O口,就能用人體的生物電完成觸摸了?哎,好事多磨,雖然它很敏感,但是生物電的強度還是不能穩(wěn)定的被感應。怎么辦呢?冷靜下來想一想,只要再叫一個強推狀態(tài)的I/O口來幫忙就好辦了,所謂強推狀態(tài),就是比普通準雙向I/O口上拉能力強很多的一種狀態(tài)。這樣,在我們同時觸碰這兩個I/O時,強推I/O口的電流就通過皮膚流入高阻狀態(tài)的I/O口,從而讀到電平變化,從而實現觸摸操作。這么好用的功能怎么設置呢,請看我從STC數據手冊里截下來的設置方法。


如圖所示,當我們用C語言設置I/O狀態(tài)時,只需向P*M1 P*M0賦值(0x開頭的十六進制格式)即可,如圖10

       接下來到了發(fā)音部分,說到這里要感謝杜洋老師,因為這里的原理跟程序參考了他的SPEAKER32語音盒子。兩者同樣都是用電腦把要播放的音頻先在電腦上用專業(yè)的音頻軟件轉換成ASCII Test數據,稍加改造變成數組后放入單片機60K的ROM里,配合PWM解碼程序,一個在你進門時甜美的說出“你好,歡迎光臨”,一個則是在你觸摸琴鍵后發(fā)出鋼琴的音色。專業(yè)的音頻軟件有很多,我用的是一款名為“Adobe Audition 3.0”的軟件,簡潔的界面,強大的功能,都是我選擇它的原因。接下來是使用方法,準備好從網上下載到的音頻,你可以用鼠標拖入音軌中,也可以對著一條空音軌點擊“右鍵→插入→音頻”來把你的音頻放入音軌中。這時音軌可能沒有緊貼前端,這樣會制造出一段空白音頻,這部分不但影響正常工作還很占空間,用右鍵點住它向前拖動,直到與前端緊貼。如圖11

       之后雙擊音頻,進入編輯模式。在這個模式下我們要做的是刪除空白跟擴大音量。向上滾動滑輪讓時間間隔變小,前端的空白就會變得明顯,去除它的原因跟上面一樣。我們用左鍵框選出空白部分,然后點擊“右鍵→剪切”來刪除空白。如圖12

       隨后按Ctrl+A全選波形,點擊左邊效果欄里的放大,調整好合適的放大倍數后點擊確認以完成放大操作。如圖13

       然后點擊左上角的“文件→另存為”,這時會彈出一個選擇格式跟保存路徑的窗口,下方的保存類型我們選擇“ACW波形(*.wav)”,然后點擊下方的選項,濾波器處改為“PCM”,屬性處改為“8.000kHz,8位,單聲道”,然后“確定→保存”如果彈出窗口點擊確定即可。如圖14


        這樣就把音頻轉成了8位單聲道,為后面的音頻表做好準備。接下來軟件會自動載入剛剛保存的音頻,再點擊左上角的“文件→另存為”在彈出的窗口里選擇“ASCII 文本數據(*.txt)”然后點擊下方的選項,把兩個勾選框的對鉤都點掉,再點擊“確定→保存”就完成了ASCII Test數據的轉換。如圖15

       這樣重復36此之后,我們就得到了36個音調的8位音頻數據了。打開電鋼琴的工程文件,在程序的C語言文件下方有36個用音調名命名的數據表文件。這時只要把剛剛生成的數據復制到對應數據表中就大功告成了,不過要注意開始處數組的定義跟每個數據后的逗號,編譯器可不會被你的急切所打動。我這里只是拋磚引玉,感興趣的話可以在網上找到更多樂器的音色,讓它變得更好玩,更強大。在茶余飯后悄悄的拿出它,為家人彈奏一曲。簡單的兒歌,或者經典的旋律,不管你音樂水平的高低,總能在家人歡樂的笑聲中感受到電子制作帶給你的幸福!




小橙出品,必屬精品。
請大家多多支持宅曉橙!

單片機源程序:

  1. #define SPEED         72//語速(在12MHz時設置為70最佳,值越小語速越快)
  2. #define X2                 2 //音頻播放倍速(默認值2,增加/減少時音頻速度整倍加/減)
  3. #define A_DA         1600 //音頻數據字節(jié)的數量,即音頻文件的行數。最大值不得大于65535        我的音頻是1600
  4. //(如果有較長的音頻需要播放可以分段處理,每段字節(jié)數不大于65535)//
  5. #define DL_F         1 //音頻播放前的延時(單位:mS)。最大值不得大于65535
  6. #define DL_A         1 //音頻播放后的延時(單位:mS)。最大值不得大于65535

  7. /*********************************************************************************************/

  8. #include<STC12C5A60S2.H> //頭文件
  9. sbit PWM  = P1 ^ 3;//音頻輸出接口(只適用PWM接口)
  10. sbit LED  = P3 ^ 6;//狀態(tài)指示LED燈 正極
  11. sbit LEDG  = P3 ^ 7;//狀態(tài)指示LED燈 負極
  12. unsigned char code  wav1[];//音頻數據表聲明                 
  13. unsigned char code  wav2[];
  14. unsigned char code  wav3[];
  15. unsigned char code  wav4[];
  16. unsigned char code  wav5[];
  17. unsigned char code  wav6[];
  18. unsigned char code  wav7[];
  19. unsigned char code  wav8[];
  20. unsigned char code  wav9[];
  21. unsigned char code wav10[];
  22. unsigned char code wav11[];
  23. unsigned char code wav12[];
  24. unsigned char code wav13[];
  25. unsigned char code wav14[];
  26. unsigned char code wav15[];
  27. unsigned char code wav16[];
  28. unsigned char code wav17[];
  29. unsigned char code wav18[];
  30. unsigned char code wav19[];
  31. unsigned char code wav20[];
  32. unsigned char code wav21[];
  33. unsigned char code wav22[];
  34. unsigned char code wav23[];
  35. unsigned char code wav24[];
  36. unsigned char code wav25[];
  37. unsigned char code wav26[];
  38. unsigned char code wav27[];
  39. unsigned char code wav28[];
  40. unsigned char code wav29[];
  41. unsigned char code wav30[];
  42. unsigned char code wav31[];
  43. unsigned char code wav32[];
  44. unsigned char code wav33[];
  45. unsigned char code wav34[];
  46. unsigned char code wav35[];
  47. unsigned char code wav36[];
  48. sbit  TUI1  =  P2 ^ 1 ;
  49. sbit  TUI2  =  P2 ^ 2 ;
  50. sbit  TUI3  =  P0 ^ 0 ;
  51. sbit  KEY1  =  P2 ^ 3 ;
  52. sbit  KEY2  =  P2 ^ 4 ;
  53. sbit  KEY3  =  P2 ^ 5 ;
  54. sbit  KEY4  =  P2 ^ 6 ;
  55. sbit  KEY5  =  P2 ^ 7 ;
  56. sbit  KEY6  =  P0 ^ 7 ;
  57. sbit  KEY7  =  P0 ^ 6 ;
  58. sbit  KEY8  =  P0 ^ 5 ;
  59. sbit  KEY9  =  P0 ^ 4 ;
  60. sbit  KEY10 =  P0 ^ 3 ;
  61. sbit  KEY11 =  P0 ^ 2 ;
  62. sbit  KEY12 =  P0 ^ 1 ;

  63. unsigned char         xiang           ;
  64. /***********************************************************************/
  65. void DELAY_MS (unsigned int a){//毫秒級CPU延時函數
  66.         unsigned int i;
  67.         while( --a != 0){
  68.                 for(i = 0; i < 600; i++);
  69.         }
  70. }  
  71. /*********************************************************************************************/
  72. void DELAY_NS (unsigned char a){//用于音頻延時
  73.         unsigned int i;
  74.         while( --a != 0){
  75.                 for(i = 0; i < SPEED; i++);
  76.         }
  77. }  
  78. /**********************************************************************************************/
  79. void PWM_init (void){//PWM初始化函數
  80.         CMOD=0x02; //設置PCA定時器
  81.          CL=0x00;
  82.          CH=0x00;
  83.         CCAPM0=0x42; //PWM0設置PCA工作方式為PWM方式(0100 0010)
  84.          CCAP0L=0x00; //設置PWM0初始值與CCAP0H相同
  85.          CCAP0H=0x00; // PWM0初始時為0
  86.          CR=1; //啟動PCA定時器
  87. }  
  88. /**********************************************************************************************/
  89. void PWM0_set (unsigned char a){//PWM0占空比設置函數
  90.         CCAP0L= a; //設置值直接寫入CCAP0L
  91.          CCAP0H= a; //設置值直接寫入CCAP0H
  92. }  

  93. /**********************************************************************************************/
  94. void SP1 (void){//音頻播放函數
  95.         unsigned int a;
  96.     LEDG = 0;//LED燈開
  97.         DELAY_MS (DL_F);//播放前延時
  98.         for(a=0;a<A_DA;a++){ //音頻播放數據長度
  99.                
  100.                 DELAY_NS (X2);//播放數據間隔,即可調整音頻速度和音調
  101.                 if(xiang == 1) {
  102.                 PWM0_set(wav1[a]);}
  103.                 if(xiang == 2) {
  104.                 PWM0_set(wav2[a]);}
  105.                 if(xiang == 3) {
  106.                 PWM0_set(wav3[a]);}
  107.                 if(xiang == 4) {
  108.                 PWM0_set(wav4[a]);}
  109.                 if(xiang == 5) {
  110.                 PWM0_set(wav5[a]);}
  111.                 if(xiang == 6) {
  112.                 PWM0_set(wav6[a]);}
  113.                 if(xiang == 7) {
  114.                 PWM0_set(wav7[a]);}
  115.                 if(xiang == 8) {
  116.                 PWM0_set(wav8[a]);}
  117.                 if(xiang == 9) {
  118.                 PWM0_set(wav9[a]);}
  119.                 if(xiang ==10) {
  120.                 PWM0_set(wav10[a]);}
  121.                 if(xiang ==11) {
  122.                 PWM0_set(wav11[a]);}
  123.                 if(xiang ==12) {
  124.                 PWM0_set(wav12[a]);}
  125.                 if(xiang ==13) {
  126.                 PWM0_set(wav13[a]);}
  127.                 if(xiang ==14) {
  128.                 PWM0_set(wav14[a]);}
  129.                 if(xiang ==15) {
  130.                 PWM0_set(wav15[a]);}
  131.                 if(xiang ==16) {
  132.                 PWM0_set(wav16[a]);}
  133.                 if(xiang ==17) {
  134.                 PWM0_set(wav17[a]);}
  135.                 if(xiang ==18) {
  136.                 PWM0_set(wav18[a]);}
  137.                 if(xiang ==19) {
  138.                 PWM0_set(wav19[a]);}
  139.                 if(xiang ==20) {
  140.                 PWM0_set(wav20[a]);}
  141.                 if(xiang ==21) {
  142.                 PWM0_set(wav21[a]);}
  143.                 if(xiang ==22) {
  144.                 PWM0_set(wav22[a]);}
  145.                 if(xiang ==23) {
  146.                 PWM0_set(wav23[a]);}
  147.                 if(xiang ==24) {
  148.                 PWM0_set(wav24[a]);}
  149.                 if(xiang ==25) {
  150.                 PWM0_set(wav25[a]);}
  151.                 if(xiang ==26) {
  152.                 PWM0_set(wav26[a]);}
  153.                 if(xiang ==27) {
  154.                 PWM0_set(wav27[a]);}
  155.                 if(xiang ==28) {
  156.                 PWM0_set(wav28[a]);}
  157.                 if(xiang ==29) {
  158.                 PWM0_set(wav29[a]);}
  159.                 if(xiang ==30) {
  160.                 PWM0_set(wav30[a]);}
  161.                 if(xiang ==31) {
  162.                 PWM0_set(wav31[a]);}
  163.                 if(xiang ==32) {
  164.                 PWM0_set(wav32[a]);}
  165.                 if(xiang ==33) {
  166.                 PWM0_set(wav33[a]);}
  167.                 if(xiang ==34) {
  168.                 PWM0_set(wav34[a]);}
  169.                 if(xiang ==35) {
  170.                 PWM0_set(wav35[a]);}
  171.                 if(xiang ==36) {
  172.                 PWM0_set(wav36[a]);}

  173.         
  174.         }
  175.         
  176.         xiang = 0;
  177.     DELAY_MS (DL_A);//播放后延時
  178.         LEDG=1;//LED燈關
  179.         PWM0_set(0); //設置PWM占空比

  180.         PWM = 0;//PWM關閉前清0
  181. }   
  182. /**********************************************************************************************/
  183. void main (void){//主函數
  184.     P0M1 = 0xFE;// (11111110)*P0.0(低音)P2.2(中音)P2.1(高音)強推
  185.         P0M0 = 0x01;// (00000001)*P2.3 P2.4 P2.5 P2.6 P2.7 P0.7  
  186.         P2M1 = 0xF8;// (11111000)*P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 高阻
  187.         P2M0 = 0x06;// (00000110)

  188.         PWM0_set(128);//設置PWM到中間值,即音頻波形的基礎電平。
  189.         CR=1; //啟動PCA定時器
  190.         P3M0 = 0xFF;//狀態(tài)指示LED接口強推設置
  191.         PWM = 0;//PWM啟動前準備
  192.         PWM_init(); //PWM初始化
  193.          while(1){
  194.    TUI1 = 1;         
  195.              if(KEY1||KEY2||KEY3||KEY4||KEY5||KEY6||KEY7||KEY8||KEY9||KEY10||KEY11||KEY12 == 1){
  196.                    DELAY_MS (20);
  197.                        if(KEY1 == 1){xiang = 1 ;SP1();while(KEY1  == 1);}
  198.                              if(KEY2 == 1){xiang = 2 ;SP1();while(KEY2  == 1);}
  199.                            if(KEY3 == 1){xiang = 3 ;SP1();while(KEY3  == 1);}

  200. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼


程序以及HEX文件:
PIANO.zip (556.77 KB, 下載次數: 201)




作者: 落雨聽愁    時間: 2017-10-27 12:17
我要學
作者: 無線電菜蟲    時間: 2017-10-31 17:14
只能說樓主很牛B,需要膜拜
作者: wyb7522312    時間: 2017-11-11 13:02
膜拜大佬
作者: c03131401    時間: 2017-11-25 08:37
看起來不錯啊!
作者: 白龍魚服    時間: 2017-11-25 11:37
這個感覺好難
作者: GUOXUAN    時間: 2017-11-25 20:51
老師對音樂真的是熱愛,連鋼琴都想到DIY.
作者: ddplys    時間: 2018-1-6 14:59
學習學習,
作者: 我耳朵7    時間: 2018-1-8 10:16
您好,請問,我在keil里無法生成.hex文件,在您的提供的壓縮包里也沒有看到.hex文件,我剛觸單片機,請麻煩您能給我一份.hex文件吧,謝謝1580808688@qq.com
作者: 我耳朵7    時間: 2018-1-8 10:19
您好,請問,我在keil里無法生成.hex文件,在您的提供的壓縮包里也沒有看到.hex文件,我剛觸單片機,請麻煩您能給我一份.hex文件吧,謝謝1580808688@qq.com
作者: hs88    時間: 2018-3-15 18:25
可以擴展到88個鍵盤嗎
作者: 智性    時間: 2018-3-16 16:16
不錯不錯
作者: Paulol    時間: 2018-4-8 20:33
謝謝 我要學
作者: zy1186    時間: 2018-11-30 13:10
看起來不錯啊!
作者: swustlx86    時間: 2018-11-30 13:19
不得不說   這是一個相當完美的設計            
作者: 熱帶雨林    時間: 2018-11-30 14:16
硬件做得不錯
作者: 鈴戀仙    時間: 2018-11-30 16:07
感謝樓主的分享
作者: 暗影濁流    時間: 2018-12-6 10:40
為什么會提示這個啊?PIANO.c(221): error C202: 'KEY1': undefined identifier 好像所有定義都找不到
作者: dl127    時間: 2018-12-6 14:44
我早三個月在別的論壇找到了一模一樣的帖子,不知道是不是樓主本人發(fā)的,然后內容和文件一模一樣,然后我問了有沒有hex文件,也沒理我,芯片都買了,一直不知道怎么弄,(有熱心的貼友給我導出了hex文件,但是超過60K肯定放不進去)我想問下有人按這個教程做出來了嗎?
作者: zhanghoub    時間: 2018-12-9 18:14
厲害
作者: 快樂眼淚    時間: 2019-4-10 11:03
下載了,編譯后108處警告,怎么回事?也不發(fā)聲
作者: woshiluguode    時間: 2019-8-26 19:15
不知道文件大小如何還有需不需要調用啊
作者: jen51h    時間: 2019-11-26 14:33
學習了,不錯的教程
作者: 快樂眼淚    時間: 2020-3-3 22:18
這個有人做成功了嗎?
作者: brew9    時間: 2020-3-4 11:14
挺好!留個記號。
作者: limonlihai    時間: 2020-6-28 22:32
請問有人做出來了嗎。我按這種寫的聲音不正確。
作者: limonlihai    時間: 2020-6-29 18:12
請問有沒有61鍵的音效的ASCII Test數據啊。自己轉換的沒有up主轉換出來的聲音好聽

作者: XYB1995    時間: 2020-7-1 08:49
還能DIY鋼琴,長見識了。謝謝分享
作者: sxy4609    時間: 2021-12-15 15:03
終于找到了。。。之前一直搜電子琴加音色,原來在這里,淚目.......




歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1