?🚀write in front🚀 ?
🔎大家好,我是黃桃罐頭,希望你看完之后,能對你有所幫助,不足請指正!共同學習交流
🎁歡迎各位→點贊👍 + 收藏?? + 留言📝??💬本系列嗶哩嗶哩江科大51單片機的視頻為主以及自己的總結梳理📚?
前言:
本文是根據嗶哩嗶哩網站上“江協科技51單片機”視頻的學習筆記,在這里會記錄下江協科技51單片機開發板的配套視頻教程所作的實驗和學習筆記內容。本文大量引用了江協科技51單片機教學視頻和鏈接中的內容。
引用:
51單片機入門教程-2020版 程序全程純手打 從零開始入門_嗶哩嗶哩_bilibili
??????c51語言變量語句意思,C51中循環語句-CSDN博客
音樂簡譜樂理:
【51單片機實驗筆記】聲學篇(一) 蜂鳴器與揚聲器的基本控制_交流蜂鳴器需要給蜂鳴器一個脈沖才會響。我們用單片機的p1.5口實現一種這樣高低電-CSDN博客
正文:
0. 🌿概述
在淘寶上購買了江協科技51單片機開發板套件(普中科技STC51單片機A2型號),就上在上一篇博文里說的自己計劃學習下江協科技51單片機開發教程,通過STC51單片機這種MCU這種貼近于裸機的開發來增加對于系統硬件層面知識的了解和掌握。
術語和縮略語:
縮寫 | 全稱 | 說明 |
RTC | Real Time Clock | 實時時鐘 |
1. 🚀蜂鳴器介紹
蜂鳴器分為有源蜂鳴器和無源蜂鳴器
🧃有源蜂鳴器:自帶震蕩電路,只要給蜂鳴器同上電,蜂鳴器就會按照固定的頻率發出鳴叫聲音。
🧃無源蜂鳴器:沒有震蕩電路,需要外部輸入震蕩信號才能發出輸入信號頻率的聲音,如果一直輸入信號則就在剛通電的時候線圈到達頂位置然后保持在頂部位置不能發出聲音。
主要區別就是有源蜂鳴器自帶震蕩電路只要輸入高電平或者低電平有源蜂鳴器就會按照固定的頻率鳴叫,而無源蜂鳴器需要外部輸入震蕩信號才會發出和輸入震蕩信號相同的頻率,如果無源蜂鳴器輸入直流信號無源蜂鳴器的線圈就一直卡在頂部位置不能發出聲音。
一般開發板上帶的都是有源蜂鳴器,有源蜂鳴器只能發出固定頻率的聲音。無源蜂鳴器的頻率和外部輸入信號的頻率相同,無源蜂鳴器才能作為演奏音樂的器件,因為無源蜂鳴器發出的聲音的頻率可以通過輸入信號的頻率調整。
蜂鳴器驅動電路:
單片機IO引腳輸出高電平或者輸入低電平時驅動能力有限,單片機IO引腳可以通過的電流有限,通過單片機IO引腳直接驅動蜂鳴器因為單片機IO引腳能夠通過電流比較小將無法驅動蜂鳴器發出聲音。所以需要將單片機的IO引腳輸出作為控制信號來控制驅動電路的開關來控制蜂鳴器的電路通斷,一般使用 三極管 作為驅動電路。
本實驗中因為開發板上又一個 ULN2003 驅動芯片的引腳沒有使用,所以本開發板使用了?LN2003的一個引腳作為了驅動蜂鳴器的驅動電路。
一般不會使用?ULN2003 驅動芯片單獨作為驅動蜂鳴器的驅動芯片,因為成本比較高,比使用三極管高,本開發板是使用了??ULN2003 驅動芯片 步進電機驅動芯片的一個剩余IO口,剛好利用起來作為蜂鳴器的驅動IO口。
UL2003 是達林頓兩級晶體管陣列電路,通過電流能力較強,單個引腳輸出可以達到 500mA電流,
🧃 當ULN2003 1B引腳輸入為1時,1C輸出為0,
🧃 當 ULN2003 1B引腳輸入為0時,1C輸出為高阻態
2. 樂譜樂理介紹
樂譜的樂理介紹,以鋼琴的按鍵區為例介紹鋼琴安檢區的不同按鍵的對應的音符頻率。
- ?🧃大字組
- 🧃小字組
- 🧃小字1組
- 🧃小字2組
從左往右是: 大字組、小字組、小字1組、小字2組
按照一組音調依次分成4組:大字組、小字組、小字1組、小字2組。組與組之間相差“8度”;相鄰的兩個鍵之間(包括白鍵與黑鍵)相差半音; 數字簡譜左上標“#”表示升高半音,“b”表示降低半音,升降號在本小節有效。 下圖8-6給出了“小字組、小字1組、小字2組”音符與頻率的對應關系。也就是說,每一個音符都對應了一個特定的頻率。
- 🧃數字簡譜左上標“#”表示升高半音,“b”表示降低半音,升降號在本小節有效
而為了按照正常的節奏演奏出整首音樂,還需要調整每個音符所占用的時間。下圖8-7給出了不同的音符的時值比,可以看出在音符的右側和下面加橫線可以實現2的冪次的調整,而在右側加點則表示乘以1.5倍。 一般設置四分音符的持續時間為500ms。
于是根據下面兩張圖,整體思路如下:鋼琴五線譜→數字簡譜→蜂鳴器頻率。 通過不斷改變定時器的復位值,進而控制蜂鳴器的頻率變化。
其中,以中央A鍵a1為基準,其標準頻率為440Hz,根據十二平均律,各音階之間以等比數列分配頻率,每12個音階頻率擴大一倍。
簡譜的音符是相對音高,它與絕對音高存在映射關系,一共有12個大調音階:C大調、bD大調、D大調、 bE大調、E大調、F大調、bG大調、 G大調、bA大調、 A大調、bB大調、 B大調。
? ? ? ? ? ? ? ? ? ? ? ??
全音符,2分音符,4分音符,
常用變音記號
- 降記號(b)表示將基本音級的音高降低半音,根據該記號所在的線或間而降音。
- 還原記號(#)表示把已經升高或降低的音還原。
- 升記號(#)表示將基本音級的音高升高半音,根據該記號所在的線或間而降音。
使用Excel計算處樂譜簡譜的不同音符對應的頻率:
以中央C作為基準頻率 440Hz,每往右12個音符升高1倍變為880Hz。
往右每個音符頻率 = 440 * 2^(1/12 *n)?
使用Excel表格計算出音符的頻率,周期時長(微秒),周期時長的一半,定時器裝載值。
C調
3. 單片機演奏音樂實驗
小星星簡譜
天空之城簡譜
實現音樂簡譜《小星星》演奏的代碼如下:
main.c?
#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"
#include "Nixie.h"
#include "Key.h"
#include "Beep.h"
#include "Timer0.h"sbit Beeper = P2^5;unsigned char KeyNum = 0;
unsigned char FreqSelect = 0;unsigned int code FreqTabble[] = {63776, 63877, 63967, 64058, 64139, 64218, 64293, 64362, 64427, 64490, 64548, 64604,64656, 64705, 64751, 64795, 64836, 64875, 64913, 64948, 64981, 65012, 65041, 65069,65095, 65119, 65143, 65165, 65186, 65205, 65223, 65241, 65258, 65273, 65288, 65302,0
};//C調//低音組
#define L1 0
#define L1_ 1
#define L2 2
#define L2_ 3
#define L3 4
#define L4 5
#define L4_ 6
#define L5 7
#define L5_ 8
#define L6 9
#define L6_ 10
#define L7 11中音組
#define M1 12
#define M1_ 13
#define M2 14
#define M2_ 15
#define M3 16
#define M4 17
#define M4_ 18
#define M5 19
#define M5_ 20
#define M6 21
#define M6_ 22
#define M7 23//高音組
#define H1 24
#define H1_ 25
#define H2 26
#define H2_ 27
#define H3 28
#define H4 29
#define H4_ 30
#define H5 31
#define H5_ 32
#define H6 33
#define H6_ 34
#define H7 35#define PERID 125unsigned char code Music[] = {//第1小節,4拍M1, 4,M1, 4,M5, 4,M5, 4,//第2小節,4拍M6, 4,M6, 4,M5, 4+4,//M5,//第3小節,4拍M4, 4,M4, 4,M3, 4,M3, 4,//第4小節,4拍M2, 4,M2, 4,M1, 4+4,//M1,//第5小節,4拍M5, 4,M5, 4,M4, 4,M4, 4,//第6小節,4拍M3, 4,M3, 4,M2, 4+4,//M2,//第7小節,4拍M5, 4,M5, 4,M4, 4,M4, 4,//第8小節,4拍M3, 4,M3, 4,M2, 4+4,//第9小節,4拍M1, 4,M1, 4,M5, 4,M5, 4,//第10小節,4拍M6, 4,M6, 4,M5, 4+4,//第11小節,4拍M6, 4,M6, 4,M3, 4,M3, 4,M2, 4,M2, 4,M1, 4+4,//結束0
};void main()
{P0 = 0x0;Beeper = 0;Timer0_Init();while(1){if(Music[FreqSelect]){TR0 = 1;Delay(PERID*Music[FreqSelect+1]);FreqSelect++;TR0 = 0;Delay(2);FreqSelect++;}else if(Music[FreqSelect] == 0){while(1);}}
}/*** @brief 定時器0中斷處理函數模版* @param 無* @retval 無*/
void Timer_Routine(void) interrupt 1
{Beeper = !Beeper;//定時器溢出之后需要重新裝載TH0 = FreqTabble[Music[FreqSelect]] / 256; //12MHz晶振,12分頻TL0 = FreqTabble[Music[FreqSelect]] % 256; //
}
Timer0.c
#include <REGX52.H>
#include "timer0.h"/*** @brief 定時器0初始化函數, 1ms 12MHz* @param 無* @retval 無*/
void Timer0_Init()
{//AUXR &= 0x7F; //定時器時鐘12T模式TMOD &= 0xF0; //設置定時器模式TMOD |= 0x01; //設置定時器模式TL0 = 0x66; //設置定時初值TH0 = 0xFC; //設置定時初值TF0 = 0; //清除TF0標志TR0 = 1; //定時器0開始計時//中斷部分寄存器ET0 = 1; //允許定時器T0中斷EA = 1; //允許中斷PT0 = 0; //定時器T0中斷優先級
}/*** @brief 定時器0中斷處理函數模版* @param 無* @retval 無*/
//void Timer_Routine(void) interrupt 1
//{
// static unsigned int count = 0;
//
// count++;
// //P2_0 = 0;
// if(count >= 500) //定時器T0每1ms中斷一次,進入1000次經過了1s
// {
// P2_0 = ~P2_0;
// count = 0;
// }
//
// //定時器溢出之后需要重新裝載
// TH0 = (65535 - 1000) / 256; //12MHz晶振,12分頻
// TL0 = (65535 - 1000) % 256 + 1; //
//}
Delay.c
#include <INTRINS.H>
#include "delay.h"void Delay(unsigned int xms) //@11.0592MHz
{unsigned char i, j;_nop_();if(xms == 0)return;while(xms--){i = 2;j = 199;do{while (--j);} while (--i);}
}
4. 音樂簡譜《小星星》通過蜂鳴器演奏
控制蜂鳴器按照音樂簡譜,通過在指定的節拍里讓無源蜂鳴器發出指定頻率的聲音發發出了《小星星》的音樂聲,控制蜂鳴器聲音頻率是通過C51單片機的定時器/計時器Timer0來控制的,通過在定時器中斷處理函數中控制定時器裝載值來控制定時器中斷進入的頻率,在定時中斷里翻蜂鳴器從而控制了蜂鳴器發出聲音的頻率。