久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2382|回復: 0
收起左側

單片機八音盒例程分享-基于stc32g12k128的硬件spwm樂音產生應用實例

[復制鏈接]
ID:1039438 發表于 2023-5-12 16:18 | 顯示全部樓層 |閱讀模式
   在調試裝置時需要一個穩定的聲音源,想到之前買的有不少stc的MCU芯片,可以用它來產生幾個聲音信號。于是寫了這個程序。
   八音盒能產生七個不同的樂音,而音樂就是由這些基本樂音組合構成(有點臉紅)。所以本例程就是個基于MCU的樂音產生程序。
   用MCU產生一個樂音本身很簡單,比如要產生一個110HZ的樂音,只要用MCU生成一個頻率為110HZ的PWM方波,然后輸出電路上加個一階低通濾波器,驅動喇叭就聽到聲音了。
   但當我們需要產生多個樂音時,就遇到一個問題,不同樂音的頻率不同,需要的濾波器的參數就不一樣,只用一個濾波器時,頻率高的樂音會受到較大的衰減。結果低音很強,高音聽不見了。
   當然可以用七個不同的低通濾波器,應對七個頻率,用一個cd4051進行選擇,mcu輸出不同頻度時,控制cd4051接通不同的濾波器。不過這樣硬件就多了幾樣。而且無法適應更多的頻率。
   常用解決辦法是采用一個高頻率的載波,然后把需要產生的聲音頻率信號調制到載波上。這樣就節省了濾波器。這就是spwm波。它是一個脈沖寬度按正弦規律變化的PWM波。下面給出一個實現方法。
        stc32g12k128具有硬件pwm功能。只要做好設置,它能自動產生符合設置頻率和脈寬的PWM波,不需要占用MCU時間。我們只要合理控制它的脈寬變化,就能得到需要的SPWM波了。所以程序簡單穩定。精度也很高。
   我選擇系統主頻用24MHZ,載波頻率為55*512=28160HZ。55為參考頻率,512為對應該頻率時正弦波表的點數。因為人耳可聞聲頻率上限20KHZ,所以這個頻率不會對樂音產生干擾,同時它又能保證每個周期對應一個波點數據。最大限度的保證產生的聲音的精度。對其它頻率的樂音,載波頻率不變,只改變正弦波表的點數。始終保證系統在最大精度上運行。該載波頻率對應的周期設置值為:24000000/28161=852=0x0354
         STC官方技術手冊上有現成的產生spwm波的例程。就直接套用了,包括pwm設置和pwm中斷服務。本例程主要是解決正統波表的生成,管理,使用。樂譜表的建立和使用。樂曲的播放管理。
   對spwm波來講,每個頻率的正弦波都需要一組正統波表數據,建立正統波表時,我使用了軟件
          Spwm_calc.exe
   它的界面如圖所示。中值采用420,幅值415,調制度0.98,在55HZ時的點數512.其它頻率的點數值通過計算獲得。產生了七組數據存放在頭文件sin_table1.h里,每組數據的第一個數放的是本組數據的個數(也就是使用的點數)。第二個開始才是正弦波表的數據。也就是說。讀波表數據要從第二個開始讀。這是為了編程序簡單方便。
   系統設置了三個數組,一個是正弦波表,放在頭文件里。第二個是波表索引數組u16 *sin_table_index[],存放正弦波表的數據的地址,它是樂譜與正弦波表的過渡。第三個是樂譜
u8 music_score[33][3]。
   樂譜表中一組數據有三個,第一個是音符名,程序根據它通過索引數組讀取對應正弦波表。第二個是音組名。1是最低音,2是低音,3是中音4是高音,5是最高音。這個數據決定從波表中讀取數據的數量,數據越少音頻越高。比如讀512個是最低音的6la),那么讀256個就是低音的6la,高了八度。頻率高一倍。以此類推。這樣七組波表數據可用以播放幾十個樂音。第三個是音長(樂音的持續時間)。本例程只設置了三個數值,1是全音,2是半音,4 4分音。僅用來展示一下音長管理的方法。想多加幾個音長設置很容易。
   例程使用了四個中斷服務:
         PWMA中斷,基本照抄官方例程,用來產生spwm波。不同的是這里輸出的正弦波頻率不是固定的。所以讀波表時不能用固定首地址。而是用了一個變量*p存放正弦波表首地址值,方便切換頻率。
   外中斷int0控制程序運行,主要是把等待切換為運行。如果不用這個中斷。可以讓程序開機后就自動循環播放。在中斷服務程序中。控制變量CC的值,從而影響主程序里語句
While(cc);的運行。
   在調試時發現中斷服務里改變cc值后,主程序里的while語句沒有響應。接上stc-link1d仿真器后觀察到,中斷發生后cc值確實發生了變化,但while語句不理會,沒有如預期的那樣跳出死循環。把這個現象放到群里咨詢時,有高人指出。這是由于keil編譯不合理所致,解決的辦法是聲名變量CC時加一個限制符volatile。試了一下,果然解決了問題。
   中斷T1是避免按鍵振動產生干擾的延時。這兩個都不重要,可以不用。
   中斷T0是核心,它控制一個樂音的播放時間,同時設定播放所需要的所有參數。各語句的作用在程序里做了注明。
void t0_sever() interrupt 1//確定一個音符的輸出參數,包括樂音的持續時間,音高數據的地址,數據量,讀取參數
{
read_music_long(cnt);//讀當前音符的播放時間,并設定對應的延時
        pp2=music_score[cnt][1];//讀取本音符的音組值,以確定讀波表數據時的偏移量
        pp3=pow(2,pp2);//計算本音符數據偏移量,在式中給pp2加整數能成倍提高輸出頻率
pp0=*sin_table_index[music_score[cnt][0]-1];///pp2;//讀取本音符的數據量
pp1=(sin_table_index[music_score[cnt][0]-1]+1);//取本音符數據指針初值
        p=pp1;//賦正弦數據指針初值
        cnt++;//準備讀下一個數據
        if(cnt>33)//樂譜播放完成,這里的33是根據樂譜數據的參數設定的。如果改變樂譜數據量,這里要做對應變化,用小了不能完整播放,用大了會出錯
        {
        cc=0;//播放結束
        ET0=0;//關中斷
        PWMA_IER = 0x00; //關中斷
            PWMA_ENO = 0x00;//關閉PWM輸出

        }
}
   音長子程序里有三個軟件定時程序,是直接使用stc官方的軟件延時工具產生的。全音用了一秒,半音0.5秒,四分音用0.25秒。
樂音播放所需要的控制參數都是在這個中斷服務里確定的。PWM中斷服務則負責按參數進行輸出。
   本例程的主程序很簡單,包括系統設置和播放管理兩項。直接列出來吧:
void main(void)
{
        mcu_initial();//mcu設置程序
        //打開播放程序,播放完成后重新進入等待
    while(1)//這個是重入語句
    {

                cc=1;//等待狀態,由中斷int0改變,如果屏蔽這個語句則程序自動重復播放樂曲
                while(cc);
                                //初始化播放指針并開始播放
                                cnt=0;//把播放計數復位到開始位置
                                ET0=1;
                TR0 = 1;                                //定時器0開始計時
PWMA_IER = 0x01; //使能中斷
    PWMA_ENO |= 0x01; //使能輸出
    PWMA_ENO |= 0x02; //使能輸出

                        cc=1;
                                while(cc);//等待播放完成,由T0中斷服務程序控制這里的CC值
    }
}
  為聽到產生的聲音,我使用了唯創的PWM功率放大模塊WT1312,它能把spwm信號變成推動喇叭的正弦信號并直接推動喇叭發聲。其電路如圖所示:把mcu的spwm輸出端直接連上功放芯片的PWM輸入端就行了。因電流較大。芯片電源單獨接了一個4.2/3.7V鋰電池。二者不需要共地。功放的輸入阻抗是100K,對MCU輸出要求很低。它的體積很小,又只用了一個電容,所以我直接用sop23-10/dip10轉接板當功放板了。接好的板子如圖。MCU部分電路沒有特殊要求,使用最小系統板就行,我在實驗中用了stc32g12k128的降龍棍系統板。音頻測試視頻體積太大沒法傳上來。因為測試電路和這個八音盒程序都沒使用晶振,所以會有些誤差。效果整體還是很不錯的。完整的程序見附件,歡迎大家批評指正。

正弦波表軟件界面

正弦波表軟件界面

功放電路圖

功放電路圖

超大功放板

超大功放板



spwm_1.zip

98.54 KB, 下載次數: 24, 下載積分: 黑幣 -5

Keil代碼下載

評分

參與人數 2黑幣 +65 收起 理由
lkc8210 + 15 絕世好帖!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

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

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 波多野结衣中文字幕一区二区三区 | 午夜一级大片 | 日本不卡高字幕在线2019 | 一区欧美 | 一区二区三区在线免费观看 | 国产91丝袜 | 亚洲福利 | 国产在线精品一区二区三区 | 国产乱码精品一区二区三区中文 | 国产精品亚洲精品日韩已方 | 自拍视频一区二区三区 | 欧美日韩在线视频一区二区 | 九九综合 | 黄色片网此 | 69视频在线播放 | 色综合天天天天做夜夜夜夜做 | 亚洲国产精品一区二区久久 | 国产精品一区一区三区 | 四虎免费视频 | 精品成人免费一区二区在线播放 | 天堂影院av | av在线影院 | 影音av| 国产福利在线 | 免费观看成人鲁鲁鲁鲁鲁视频 | 91精品久久久 | 在线观看视频91 | 午夜在线精品 | 久久国产免费 | 伊人久久免费 | 密室大逃脱第六季大神版在线观看 | 羞羞视频一区二区 | 国精产品一区一区三区免费完 | 免费不卡视频 | 91在线免费观看网站 | 91中文视频| 欧美中文字幕在线观看 | 在线观看亚洲专区 | 亚洲成人av在线 | 国产综合在线视频 | 欧美日韩国产高清 |