通過蜂鳴器實現播放三首音樂,三個按鍵分別控制上一首,下一首,暫停與播放,lcd顯示播放音樂名稱,同時led點陣根據音樂閃爍(愛心形狀)
制作出來的實物圖如下:
51hei圖片20250521233906.jpg (1.35 MB, 下載次數: 0)
下載附件
2025-5-21 23:39 上傳
51hei圖片20250521233856.jpg (1.39 MB, 下載次數: 0)
下載附件
2025-5-21 23:39 上傳
單片機源程序如下:
- #include <REGX52.H>
- #include "LCD1602.h"
- #include <intrins.h>
- sbit Buzzer = P2^5;
- sbit KEY_PREV = P3^0; // 上一曲
- sbit KEY_NEXT = P3^1; // 下一曲
- sbit KEY_PAUSE = P3^2; // 暫停/繼續
- sbit SCK=P3^6;
- sbit RCK=P3^5;
- sbit SER=P3^4;
- unsigned char Index = 1;
- bit updateLED=0;
- bit pause = 0; // 初始開始狀態
- unsigned int FreqSelect;
- //--定義要使用的IO口--//
- #define Led_Port P0
- //--列選通控制--//
- unsigned char code TAB[8] = {0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
- void Delay(unsigned int xms) {
- while(xms--) {
- unsigned char i = 2, j = 239;
- do { while (--j); } while (--i);
- }
- }
- void _74HC595_WriteByte(unsigned char Byte)
- {
- unsigned char i;
- for(i=0;i<8;i++)
- {
- SER=Byte&(0x80>>i); // 取出每一位數據
- SCK=1; // 下移一位
- SCK=0;
- }
- RCK=1; //傳輸數據
- RCK=0;
- }
- void MatrixLED_ShowColumn(unsigned char Column,Data)
- {
- _74HC595_WriteByte(Data);
- Led_Port=~(0x80>>Column); // 將數據顯示在相應的列上
- Delay(1); // 消隱操作
- Led_Port=0xFF;
- }
- void love_display()
- {
- SCK=0;
- RCK=0;
- MatrixLED_ShowColumn(0,0x30);
- MatrixLED_ShowColumn(1,0x78);
- MatrixLED_ShowColumn(2,0x7C);
- MatrixLED_ShowColumn(3,0x3E);
- MatrixLED_ShowColumn(4,0x7C);
- MatrixLED_ShowColumn(5,0x78);
- MatrixLED_ShowColumn(6,0x30);
- MatrixLED_ShowColumn(7,0x00);
-
- }
- #define P0 0 //休止符
- #define L1 1 //低音L
- #define L1_ 2 //'_'表示升半音
- #define L2 3
- #define L2_ 4
- #define L3 5
- #define L4 6
- #define L4_ 7
- #define L5 8
- #define L5_ 9
- #define L6 10
- #define L6_ 11
- #define L7 12
- #define M1 13 //中音M
- #define M1_ 14
- #define M2 15
- #define M2_ 16
- #define M3 17
- #define M4 18
- #define M4_ 19
- #define M5 20
- #define M5_ 21
- #define M6 22
- #define M6_ 23
- #define M7 24
- #define H1 25 //高音H
- #define H1_ 26
- #define H2 27
- #define H2_ 28
- #define H3 29
- #define H4 30
- #define H4_ 31
- #define H5 32
- #define H5_ 33
- #define H6 34
- #define H6_ 35
- #define H7 36
- #define SPEED 500 //宏定義四分音符時常為500ms
- unsigned int code AutoFreq[]={//基于C大調
- 0,//休止符
- 63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,//低音
- 64582,64633,64686,64732,64778,64820,64860,64898,64934,64968,65000,65032,//中音
- 65059,65085,65111,65134,65157,65178,65198,65217,65235,65252,65268,65284 //高音
- };
- //小星星樂譜
- unsigned char code Music1[] = {
- //S1
- M1, 4,
- M1, 4,
- M5, 4,
- M5, 4,
- //S2
- M6, 4,
- M6, 4,
- M5, 4+4,
- //S3
- M4, 4,
- M4, 4,
- M3, 4,
- M3, 4,
- //S4
- M2, 4,
- M2, 4,
- M1, 4+4,
- //S5
- M5, 4,
- M5, 4,
- M4, 4,
- M4, 4,
- //S6
- M3, 4,
- M3, 4,
- M2, 4+4,
- //S7
- M5, 4,
- M5, 4,
- M4, 4,
- M4, 4,
- //S8
- M3, 4,
- M3, 4,
- M2, 4+4,
- //S9
- M1, 4,
- M1, 4,
- M5, 4,
- M5, 4,
- //S10
- M6, 4,
- M6, 4,
- M5, 4+4,
- //S11
- M4, 4,
- M4, 4,
- M3, 4,
- M3, 4,
- //S12
- M2, 4,
- M2, 4,
- M1, 4+4,
- //終止符
- 0xFF
- };
- //Music1《天空之城》
- unsigned char code Music2[]={ //(音高,時長)
- //1
- P0,4,P0,4,P0,4,M6,2,M7,2, //每一行為一小節,
- H1,4+2,M7,2,H1,4,H3,4,
- M7,4+4+4,M3,2,M3,2,
- //2
- M6,4+2,M5,2,M6,4,H1,4,
- M5,4+4+4,M3,4,
- M4,4+2,M3,2,M4,4,H1,4,
- //3
- M3,4+4,P0,2,H1,2,H1,2,H1,2,
- M7,4+2,M4_,2,M4_,4,M7,4,
- M7,4+4,P0,4,M6,2,M7,2,
- //4
- H1,4+2,M7,2,H1,4,H3,4,
- M7,4+4+4,M3,2,M3,2,
- M6,4+2,M5,2,M6,4,H1,6,
- //5
- M5,4+4+4,M2,2,M3,2,
- M4,4,H1,2,M7,2+2,H1,2+4,
- H2,2,H2,2,H3,2,H1,2+4+4,
- //6
- H1,2,M7,2,M6,2,M6,2,M7,4,M5_,4,
- M6,4+4+4,H1,2,H2,2,
- H3,4+2,H2,2,H3,4,H5,4,
- //7
- H2,4+4+4,M5,2,M5,2,
- H1,4+2,M7,2,H1,4,H3,4,
- H3,4+4+4,
- //8
- M6,2,M7,2,H1,4,M7,4,H2,2,H2,2,
- H1,4+2,M5,2+4+4,
- H4,4,H3,4,H2,4,H1,4,
- //9
- H3,4+4+4,H3,4,
- H6,4+4,H5,4,H5,4,
- H3,2,H2,2,H1,4+4,P0,2,H1,2,
- //10
- H2,4,H1,2,H2,2,H2,4,H5,4,
- H3,4+4+4,H3,4,
- H6,4+4,H5,4+4,
- //11
- H3,2,H2,2,H1,4+4,P0,2,H1,2,
- H2,4,H1,2,H2,2+4,M7,4,
- M6,4+4+4,M6,2,M7,2,
-
- 0xff //結束
- };
- //Music2
- unsigned char code Music3[]={ //(音高,時長)
- //1
- M1,2,M2,2,L6,2,L5,2,M5,6,M6,2,//每一行為一小節,
- M3,2,M5,2,H1,2,M6,2,M5,8,
- M5,4,M6,2,M5,2,M3,2,M2,2,M3,4,
- M5,2,M3,2,L6,2,M1,2,M2,8,
- //2
- M2,2,M5,2,M3,2,M1,2,L6,4,L5,2,L6,2,
- M2,2,M6,2,M5,2,M6,2,M3,6,M2,2,
- M1,2,M2,1,M2,1,M3,2,M5,1,M5,1,H1,2,M6,2,M5,4,
- //3
- M5,2,L6,2,M1,2,M2,2,M4,6,M6,1,M6,1,
- M5,3,M6,1,M3,2,M2,2,M1,8,
- M1,8,P0,4,M5,2,M5,2,
- H1,8,H2,6,H1,2,
- M6,2,H1,2,M5,2,M7,2,M6,8,
- //4
- M5,4,M3,4,H1,4,M6,3,M6,1,
- M5,2,M6,2,M1,2,M2,2,M3,8,
- M3,4,M3,2,M5,2,M6,4,M6,2,H1,2,
- H2,4,H3,2,H1,2,H2,4+2,H1,2,
- //5
- H2,2,M3,2,M5,2,M6,2,M7,2,H2,1,H2,1,M6,2,M7,2,
- M5,16,
- H2,2,M7,2,M6,2,M5,2,M3,2,M5,1,M5,1,M6,2,H2,2,
- H1,16,
-
- 0xff //結束
- };
- void Key_Proc() {
- static bit key_flag = 0;
- static unsigned char MusicSelect = 0;
- // 下一曲檢測
- if (!KEY_NEXT) {
- Delay(10); // 消抖
- if (!KEY_NEXT && !key_flag) {
- key_flag = 1;
- if (++Index > 3) Index = 1;
- MusicSelect = 0;
- }
- } else if (KEY_NEXT) {
- key_flag = 0;
- }
- // 上一曲檢測
- if (!KEY_PREV) {
- Delay(10); // 消抖
- if (!KEY_PREV && !key_flag) {
- key_flag = 1;
- if (--Index < 1) Index = 3;
- MusicSelect = 0;
- }
- } else if (KEY_PREV) {
- key_flag = 0;
- }
- // 暫停/繼續檢測
- if (!KEY_PAUSE) {
- Delay(10); // 消抖
- if (!KEY_PAUSE) {
- pause = !pause;
- if (pause) {
- TR0 = 0;
- Buzzer = 0; // 關閉蜂鳴器
- } else {
- TR0 = 1;
- }
- }
- while (!KEY_PAUSE); // 等待按鍵釋放
- }
- }
- void Autoplay() {
- static unsigned char MusicSelect = 0;
- static unsigned char lastIndex = 0; // 新增索引跟蹤
- const unsigned char *currentMusic=0;
- // 歌曲切換時重置播放位置
- if(Index != lastIndex) {
- MusicSelect = 0;
- lastIndex = Index;
- }
- // 選擇當前歌曲
- switch(Index) {
- case 1: currentMusic = Music1; break;
- case 2: currentMusic = Music2; break;
- case 3: currentMusic = Music3; break;
- default: return;
- }
- if(!pause) {
- if(currentMusic[MusicSelect] != 0xff) {
- FreqSelect = currentMusic[MusicSelect];
- MusicSelect++;
- Delay(SPEED/4 * currentMusic[MusicSelect]);
- MusicSelect++;
-
- // 音符間隔處理
- TR0 = 0;
- Delay(5);
- TR0 = 1;
- } else {
- MusicSelect = 0; // 循環播放
- }
- } else
- {
- TR0 = 0;
- Buzzer = 0;
- }
- }
- void Display() {
- static unsigned char lastIndex = 0;
- static bit lastPause = 0;
- static unsigned int refreshCnt = 0;
- if (++refreshCnt >= 1000||pause != lastPause || Index != lastIndex) {
- refreshCnt = 0;
- EA=0;
- LCD1602_Clear(); // 清屏(已優化延時)
- Delay(5);
- if (pause) {
- LCD1602_DispString(1, 1, "Paused "); // 填充至16字符
- } else {
- switch(Index) {
- case 1:
- // 第1行:"Twinkle Twinkle"(16字符)
- LCD1602_DispString(1, 1, "Twinkle Twinkle");
- // 第2行:"Little Star "(16字符,2個空格)
- LCD1602_DispString(2, 1, "Little Star ");
- break;
- case 2:
- // 第1行:"Castle in the Sky"(16字符,修正空格)
- LCD1602_DispString(1, 1, "Castle in theSky");
- // 第2行留空
- LCD1602_DispString(2, 1, " ");
- break;
- case 3:
- // 第1行:"My Motherland "(16字符,2個空格)
- LCD1602_DispString(1, 1, "My Motherland ");
- // 第2行留空
- LCD1602_DispString(2, 1, " ");
- break;
- }
- }
- EA=1;
- lastIndex = Index;
- lastPause = pause;
- }
- }
- void Timer0Init(void)
- {
- TMOD &= 0xF0;
- TMOD |= 0x01;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
Keil5程序51hei附件下載:
大實驗.rar
(62.76 KB, 下載次數: 0)
2025-5-21 23:34 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|