Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
0.png (31.08 KB, 下載次數: 48)
下載附件
2019-10-23 17:11 上傳
0.png (58.96 KB, 下載次數: 43)
下載附件
2019-10-23 17:10 上傳
0.png (6.24 KB, 下載次數: 41)
下載附件
2019-10-23 17:11 上傳
單片機源程序如下:
- /**************************************************************
- 程序名稱:模擬電子琴
- **************************************************************/
- #include<reg52.h> //定義頭文件
- #define uchar unsigned char //宏定義
- #define led P0 //定義LED等位P0口
- #define sw_port P1 //中間變量。。。使按鍵和led對應
- sbit buzzer=P2^7; //揚聲器管腳
- sbit key1=P3^2; //播放音樂與彈奏歌曲轉換
- sbit key3=P3^4; //掉電存儲按鍵
- sbit key4=P3^5; //播放掉電存儲的歌曲
- sbit keybofang=P3^3; //播放剛才彈奏的歌曲
- sbit key7=P3^0; //音調鍵。。。 和 歌曲鍵
- sbit key8=P3^1; //音調鍵。。。 和 歌曲鍵
- sbit key6=P1^7;
- sbit key5=P1^6;
- sbit sda=P1^1; //24c02數據線
- sbit scl=P1^0; //24c02時鐘線
- uchar keyd,i,keys,b; //定義變量
- uchar tone_H; //定義變量
- uchar tone_L; //定義變量
- void beat_125(unsigned char); //聲明函數
- uchar code beat1[]={16,8,8,8,8,4,4,16,8,4,4,8,4,4,4, //歌曲1節拍
- 4,4,4,16,16,8,8,4,4,12,8,16,16,8,4,4,4,4,16};
- uchar code song1[]={6,5,3,5,7,6,5,6,3,5,6,5,3, //歌曲1簡譜
- 2,1,6,5,3,2,2,3,5,5,6,3,2,1,5,3,2,1,6,1,1,15};
- uchar code beat2[]={7,7,7, 7,8,9, 1,2,3, 6,2,4, 4,4,4, 12, //歌曲二節拍
- 8,2,2, 4,4,4, 8,2,2, 4,4,4, 2,2,4,4, 12,};
- uchar code song2[]={1,2,8, 8,5,1, 3,3,3, 5,4,3, //歌曲二簡譜
- 5,4,3, 2, 2,1,0, 1,2,3, 4,3,2, 3,4,5, 5,4,3, 2,1,15};
- uchar code beat4[]={4,4,4, 6,2,4, 4,4,4, 6,2,4, 4,4,4, 12,
- 8,2,2, 4,4,4, 8,2,2, 4,4,4, 2,2,4,4, 12,};
- uchar code song4[]={1,1,1, 3,2,1, 3,3,3, 5,4,3,
- 5,4,3, 2, 2,1,0, 1,2,3, 4,3,2, 3,4,5, 5,4,3, 2,1, 15};
- uchar code tone[]={115,102,91,86,77,68,61,57}; //歌曲音調
- unsigned int code tone1[]={1012,956,852,759,716,638,568,506,478,426,379,531,10}; //歌曲音調
- uchar song3[43]; //定義空數組
- void play(uchar*,uchar*); //演奏歌曲函數
- void delay8um(uchar); //第一8um延時函數
- void sound(uchar); //彈奏發聲函數
- /*******************************************
- 函數功能:節拍的延時的基本單位,用于24c08簡單延時
- ******************************************/
- void delay() //簡單延時函數
- {;;}
- /*******************************************
- 函數功能:節拍的延時的基本單位,延時1ms
- ******************************************/
- void delay1ms(uchar x) //1um延時函數
- {
- uchar j;
- while(x--)
- for(j=120;j>0;j--);
- }
- /**************************************************************
- 函數功能:24c02驅動程序 用IIC總線進行傳輸
- **************************************************************/
- void init_c02() //24c02初始化
- {
- sda=1;
- delay();
- scl=1;
- delay();
- }
- void start_c02() //24c02的啟動信號
- {
- scl=1;
- delay();
- sda=1;
- delay();
- sda=0;
- delay();
- }
- void stop_c02() //24c02停止信號
- {
- sda=0;
- delay();
- scl=1;
- delay();
- sda=1;
- delay();
- }
- void response_c02() //24c02的應答信號
- {
- uchar i;
- scl=1;
- delay();
- while((sda==1)&&(i<250))i++;
- scl=0;
- delay();
- }
- void write_c02byte(uchar date) //對24c02寫一個字節
- {
- uchar i,temp;
- temp=date;
- for(i=0;i<8;i++)
- {
- temp=temp<<1;
- scl=0;
- delay();
- sda=CY;
- delay();
- scl=1;
- delay();
- }
- scl=0;
- delay();
- sda=1;
- delay();
- }
- uchar read_c02byte() //對24c02讀一個字節
- {
- uchar i,k;
- scl=0;
- delay();
- sda=1;
- delay();
- for(i=0;i<8;i++)
- {
- scl=1;
- delay();
- k=(k<<1)|sda;
- scl=0;
- delay();
- }
- return k;
- }
- void write_addc02(uchar address,uchar date) //對24c02寫一個數據
- {
- start_c02();
- write_c02byte(0xa0);
- response_c02();
- write_c02byte(address);
- response_c02();
- write_c02byte(date);
- response_c02();
- stop_c02();
- }
- uchar read_addc02(uchar address) //從24c02讀一個數據
- {
- uchar date;
- start_c02();
- write_c02byte(0xa0);
- response_c02();
- write_c02byte(address);
- response_c02();
- start_c02();
- write_c02byte(0xa1);
- response_c02();
- date=read_c02byte();
- // response_c02;
- stop_c02();
- return date;
- }
- /**************************************************************
- 函數功能:主函數。。。。。。。。。。。。
- **************************************************************/
- void main() //主函數
- {
- uchar yd,temp,jj,tt; //定義變量
- uchar t1,i; //定義變量
- t1=0; //初始化 t1
- yd=0; //初始化t2
- buzzer=1; //初始化蜂鳴器
- EA=1; //打開定時總中斷
- TMOD=0x01; //設置定時器模式 定時器0工作在方式1
- ET0=1; //打開定時器0中斷
- while(1) //主循環
- {
- led=0x3c;
- sw_port=0xff;
- keys=~sw_port; //將led與按鍵結合起來
- switch(keys) //進入鍵盤選擇
- {
- case 0x04:sound(0);temp=1;yd=0;break; //如果鍵盤1被按下發音do,同時設置標志temp,將數字計入yd
- case 0x08:sound(1);temp=1;yd=1;break; //如果鍵盤2被按下發音ruai,同時設置標志temp,將數字計入yd
- case 0x10:sound(2);temp=1;yd=2;break; //如果鍵盤3被按下發音mi,同時設置標志temp,將數字計入yd
- case 0x20:sound(3);temp=1;yd=3;break; //如果鍵盤4被按下發音fa,同時設置標志temp,將數字計入yd
- }
- if(key5==0) //如果鍵盤5被按下發音la,同時設置標志temp,將數字計入yd
- {
- while(!key5) // 松手檢測
- sound(4);
- temp=1;yd=4;
- }
- if(key6==0) //如果鍵盤6被按下發音xi,同時設置標志temp,將數字計入yd
- {
- while(!key6) // 松手檢測
- sound(5);
- temp=1;yd=5;
- }
- if(key7==0) //如果鍵盤7被按下發音xi,同時設置標志temp,將數字計入yd
- {
- while(!key7) // 松手檢測
- sound(6);
- temp=1;yd=6;
- }
- if(key8==0) //如果鍵盤8被按下發音高音do,同時設置標志temp,將數字計入yd
- {
- while(!key8) //松手檢測
- sound(7); //播放高音do。。
- temp=1;yd=7;
- }
- if(temp==1) //標志位,如果標志位為1,則說明有按鍵被按下
- {
-
- temp=0; //將標識位歸零
- song3[t1++]=yd; //將數據存入song3[]數組
- }
- if(key3==0) //將數據存入24c02 ,掉電存儲按鍵
- {
- delay1ms(10);
- if(key3==0) //檢測是否key3被按下
- {
- P0=0; //如果被按下,將led打開
- while(!key3); //松手檢測
- song3[t1++]=30;
- init_c02(); //初始化24c02
- for(i=0;i<40;) //進入循環
- {
- write_addc02(i,song3[i++]); //將數據依次寫入24c02
- delay1ms(10); //延時
- }
- P0=1; //led關閉
- }
- }
- if(key4==0) //讀取24c02中的數據,掉電播放
- {
- delay1ms(10);
- if(key4==0)
- { //檢測是否有鍵被按下
-
- while(!key4); //松手檢測
- init_c02(); //初始化
- P0=0; //將led打開
- tt=1; //將tt初值設為0
- while(read_addc02(tt)!=30) //進入while循環
- {
- jj=read_addc02(tt++);
- tone_H=(65536-tone1[jj])/256; //設定初值
- tone_L=(65536-tone1[jj])%256; //設定初值
- TH0=tone_H; //賦值TH0高八位
- TL0=tone_L; //賦值TL0低八位
- TR0=1; //打開定時器
- beat_125(3); //延時
- TR0=0;
- beat_125(4); //關閉定時器
- }
- P0=1; //關閉led
- }
- }
- if(keybofang==0)
- {
- while(!keybofang); //檢測回放鍵是否被按下
- song3[t1++]=30;
- // t1=0;
- while(song3[i]!=30) //進入while循環。
- {
- tone_H=(65536-tone1[song3[i]])/256;
- tone_L=(65536-tone1[song3[i]])%256;
- TH0=tone_H;
- TL0=tone_L;
- TR0=1; //開啟定時器
- beat_125(3);
- TR0=0; //關閉定時器
- i++;
- beat_125(4); //將i值加一
- }
- }
- if(key1==0)
- {
- delay1ms(10);
- if(key1==0) //檢測key1是否被按下
- {
- while(!key1);
- P0=0; //關閉led
- while(key1) //進入循環
- {
- if(key7==0) //檢測key7是否被按下
- {
- delay1ms(10);
- if(key7==0)
- {
- P0=0xaa; //設置led燈亮個數
- while(!key7); //等待釋放
- play(song1,beat1); //演奏歌曲1
- P0=0xff; //關閉led
- }
- }
- if(key8==0) //檢測是否key8鍵被按下
- {
- delay1ms(10);
- if(key8==0)
- {
- P0=0xaa; //設置led燈亮
- while(!key8); //松手檢測
- play(song2,beat2); //播放歌曲2
- P0=0xff; //關閉led
- }
- }
- if(key6==0) //檢測是否key6鍵被按下
- {
- delay1ms(10);
- if(key6==0)
- {
- P0=0xaa; //設置led燈亮
- while(!key6); //松手檢測
- play(song4,beat4); //播放歌曲4
- P0=0xff; //關閉led
- }
- }
- }
- while(!key1); //檢測key1是否被按下
- P0=1; //如果被按下。退出該函數。。并關閉led
-
- }
- }
-
- }
- }
- /**************************************************************
- 函數功能:從數組中播放歌曲
- **************************************************************/
- void play(uchar*song,uchar*beat) //播放歌曲函數
- {
- i=0; //設置初始值
- while(song[i]!=15) // 進入循環函數
- {
- tone_H=(65536-tone1[song[i]])/256; //定義初值
- tone_L=(65536-tone1[song[i]])%256; //定義初值
- TH0=tone_H; //賦值
- TL0=tone_L; //賦值
- TR0=1; //打開定時器0
- beat_125(beat[i]); //讀取節拍函數
- i++; //自加
- TR0=0; //關閉led
- }
- }
- /**************************************************************
- 函數功能:定時器T0的中斷服務子程序,使P2.7引腳輸出音頻方波
- **************************************************************/
- void tone_timer() interrupt 1 //中斷子程序
- {
- TH0=tone_H;
- TL0=tone_L;
- buzzer=~buzzer; //揚聲器開關控制
- }
- /**************************************************************
- 函數功能:產生節拍的函數
- **************************************************************/
- void beat_125(uchar x) //節拍。。
- {
- uchar i,j,k; //125ms延時函數。。
- for(i=0;i<x;i++)
- for(j=0;j<125;j++)
- for(k=0;k<120;k++);
- }
- /**************************************************************
- 函數功能:8um簡易延時
- **************************************************************/
- void delay8um(uchar x) //8ms延時函數
- {
- uchar i,j;
- for(i=0;i<x;i++)
- for(j=0;j<1;j++);
- }
- /**************************************************************
- 函數功能:產生音調
- **************************************************************/
- void sound(uchar x) //音調函數
- {
- uchar i;
- led=sw_port; //定義led
- for(i=0;i<60;i++)
- {
- buzzer=0;delay8um(tone[x]); //開關頻率。。從而產生節拍
- buzzer=1;delay8um(tone[x]);
- }
- led=0xff;
- }
復制代碼
所有資料51hei提供下載:
基于51單片機8音鍵電子琴DIY制作(完整設計項目開源).rar
(49.4 KB, 下載次數: 126)
2019-10-23 13:56 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|