首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

51單片機簡易電子琴C語言程式設計完整指南

     編輯:C 語言問答

專案概述

本專案實現一款基於AT89S51單片機的簡易電子琴,採用4×4矩陣鍵盤輸入,可演奏16個不同音調。系統利用單片機定時器T0產生方波頻率信號駅動蜂鳴器發聲,定時器T1控制音拍節奏,並透過數碼管顯示當前按鍵對應的音符編碼。

硬體電路設計

核心連接

  • P1.0 → 音頻放大模塊 SPKIN(驅動喇叭/蜂鳴器)
  • P3.0–P3.7 → 4×4矩陣鍵盤 行列掃描接口(C1–C4, R1–R4)
  • P0口 → 數碼管段碼輸出
  • P2.6/P2.7 → 數碼管位選控制(DULA/WELA)

音頻頻率計算原理

採用12MHz晶振,定時器T0工作於模式1(16位定時器)。機器週期1μs,溢出率計算公式:

TH0 = (65536 - 頻率計數值) / 256
TL0 = (65536 - 頻率計數值) % 256

常用音符計數值表(部分):

音符頻率(Hz)計數值
中音DO (C4)52364580
中音RE (D4)58764684
中音MI (E4)65964777
中音FA (F4)69864820
中音SO (G4)78464898
中音LA (A4)88064968
中音SI (B4)98865030
高音DO (C5)104665058

按鍵掃描與消抖邏輯

採用行列反轉掃描法:依次將P3.4–P3.7置低,讀取P3.0–P3.3狀態。雙重延時消抖(50×200循環),確認按鍵穩定後查表獲取對應音符索引。

核心C語言程式碼

#include <AT89X51.H>

unsigned char code seg_table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                  0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned int code freq_table[] = {64021,64103,64260,64400,64524,64580,64684,64777,
                                  64820,64898,64968,65030,65058,65110,65157,65178};

unsigned char temp, key, i, j;
unsigned char STH0, STL0;

void main(void) {
    TMOD = 0x01;  // T0模式1
    ET0 = 1; EA = 1;

    while(1) {
        // 掃描第1行 (P3.4)
        P3 = 0xFF; P3_4 = 0;
        temp = P3 & 0x0F;
        if(temp != 0x0F) {
            for(i=50;i>0;i--) for(j=200;j>0;j--);
            temp = P3 & 0x0F;
            if(temp != 0x0F) {
                switch(temp) {
                    case 0x0E: key=0; break;
                    case 0x0D: key=1; break;
                    case 0x0B: key=2; break;
                    case 0x07: key=3; break;
                }
                P0 = seg_table[key];
                STH0 = freq_table[key] / 256;
                STL0 = freq_table[key] % 256;
                TR0 = 1;
                while((P3 & 0x0F) != 0x0F);
                TR0 = 0;
            }
        }
        // 第2-4行掃描邏輯同理 (P3.5-P3.7 對應 key 4-15)
        // ... 此處省略重複代碼 ...
    }
}

void t0_isr(void) interrupt 1 using 0 {
    TH0 = STH0; TL0 = STL0;
    P1_0 = ~P1_0;  // 翻轉輸出產生方波
}

中斷服務程序詳解

T0中斷以預載值重裝計數器,並翻轉P1.0輸出腳位,產生50%佔空比方波。頻率精度取決於晶振穩定性與計數值準確度。

擴展建議

  • 增加T1定時器實現自動播放樂曲(如《生日快樂》)
  • 添加PWM調節音量大小
  • 引入MIDI協議支援外部鍵盤輸入
  • 使用更高性能MCU(STM32)實現多音色合成

常見問題排查

  1. 無聲音:檢查P1.0輸出波形、蜂鳴器極性、放大電路供電
  2. 音準偏差:校準晶振頻率、重新計算計數值
  3. 按鍵無反應:確認矩陣鍵盤排線序列、檢查P3口上拉電阻
  4. 數碼管不亮:驗證段碼表、位選控制時序
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved