单片机电子琴程序
51单片机电子琴程序

#include<reg51.h>#include<absacc.h>#include<stdio.h>#include<math.h>#define uchar unsigned char#define uint unsigned intuchar STH0; //定时器计数初值uchar STL0;bit FY=0; //放乐曲时FY=1,电子琴弹奏时FY=0uchar Song_Index=0,Tone_Index=0; //放音乐的参数uchar k,key;sbit SPK=P3^7;sbit LED1=P1^0;sbit LED2=P1^1;uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6f,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79 ,0x71};uchar code Song[][50]={{1,2,3,5,7,8,4,3,4,3,4,5,4,6,3,4,5},{5,5,3,5,4,2,4,5,7,4,2,10,10,10,2,1,2,1,2,10,10},{5,5,10,9,8,5,5,5,5,10,9,8,6,6,6,11,12,9,6,8-1},{13,14,13,12,12,10,12,13,14,15,14,14},{6,6,11,10,9,12,12,12,12,13,12,11,9,8,10,10,10,-1},{9,13,13,13,13,8,13,13,13,13,14,15,14,13,13,14,12,13},};uchar code Len[][50]={{1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,2,2,2,1,2,2,1,2,2},{1,1,1,1,1,1,2,1,1,1,2,2,1,1,1,1,-1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1},{1,1,2,0,1,1,2,0,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,2,0,1,2,1,2,1,2,1,2,1,2},{2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1},}; //音符与计数值对应表uint code tab[]={0,63628,63835,64021,64103,64260,64400,64524,64580,64684,64777,64820,64898,64968,65030,65058,65110,65157,65178,65217,65252,65283};void delay1(uint ms) //播放歌曲时实现节拍的延时函数{uchar t;while(ms--) for(t=0;t<120;t++);}//键消抖延时函数void delay(void){uchar i;for(i=300;i>0;i--);}//键扫描函数uchar getkey(void){uchar scancode,tmpcode;if((P0&0xf0)==0xf0)return(0);scancode=0xfe;while((scancode&0x10)!=0){P0=scancode; //输入行扫描码if((P0&0xf0)!=0xf0) //本行有键按下{tmpcode=(P0&0xf0)|0x0f;return((~scancode)+~(tmpcode));}else scancode=(scancode<<1)|0x01;}}//外部中断0void EX0_INT() interrupt 0{FY=0;LED1=1;LED2=0;}//外部中断1,这里是播放按键void EX1_INT() interrupt 2{FY=1;LED1=0;LED2=1;}//定时器0中断服务子程序void time0_int(void) interrupt 1 using 0{TH0=STH0;TL0=STL0;SPK=!SPK;P2=DSY_CODE[k];void main(void){LED1=1;LED2=0;P2=0x3f;IE=0x87;TMOD=0x01;IT0=1;IT1=1;while(1){P0=0xf0;if((P0&0xf0)!=0xf0){delay();if((P0=0xf0)!=0xf0){key=getkey();switch(key){case 0x11:k=0;break;case 0x21:k=1;break;case 0x41:k=2;break;case 0x81:k=3;break;case 0x12:k=4;break;case 0x22:k=5;break;case 0x42:k=6;break;case 0x82:k=7;break;case 0x14:k=8;break;case 0x24:k=9;break;case 0x44:k=10;break;case 0x84:k=11;break;case 0x18:k=12;break;case 0x28:k=13;break;case 0x48:k=14;break;case 0x88:k=15;break;default:break;}if(FY==0){STH0=tab[k]/256;STL0=tab[k]%256;TR0=1;while((P0&0xf0)!=0xf0);TR0=0;}else{while(FY==1){if(Song[k][Tone_Index]==-1)Tone_Index=0;STH0=(tab[Song[k][Tone_Index]])/256;STL0=(tab[Song[k][Tone_Index]])%256;P2=DSY_CODE[Song[k][Tone_Index]];TR0=1;delay1(300*Len[k][Tone_Index]);Tone_Index++;TR0=0;}}}}}}关于“世上只有妈妈好”的单片机音乐演奏程序2009-11-22 21:45单片机演奏一个音符,是通过引脚,周期性的输出一个特定频率的方波。
单片机入门汇编程序 程序14-8:电子琴程序

; 判断第 2 列
; 判断第 3 列
பைடு நூலகம்
; 判断第 4 列
; 计算按键号
; 装表
; 把表中计数初始值装入累加器 A
; 使能 Timer 0 中断 ; 启动 Timer ; 等待按键释放
; TRO 清 0
;Timer 0 中断服务程序,输出某一频率的方波
INT_T0: MOV MOV MOV MUL MOV MOVC MOV INC MOV MOVC MOV CPL RETI DELAY: MOV D1: MOV DJNZ DJNZ RET TABLE: DW DW DW DW END ; 16 个琴键发音频率的计数初始值 64021,64103,64260,64400 64524,64580,64684,64777 64820,64898,64968,65030 65058,65110,65157,65178 R7,#250 R7,$ R6,D1 R6,#10 DPTR,#TABLE A,VAL B,#2 AB R1,A A,@A+DPTR TH0,A R1 A,R1 A,@A+DPTR TL0,A P1.0 ; 清 P1.0 口
C2: JNB MOV JMP C3: JNB MOV JMP C4: JNB MOV CALCU: MOV MOV MUL ADD MOV MOV MOV MUL MOV MOVC MOV INC MOV MOVC MOV MOV SETB W0: MOV CJNE CLR JMP W1: MOV CJNE MOV CLR JMP W2: JMP W0 A,P2 A,#0F0H,W2 P0,#00H TR0 LSCAN A,P2 A,#0FH,W1 TR0 LSCAN A,KEYL B,#04H AB A,KEYR VAL,A DPTR,#TABLE B,#2 AB R1,A A,@A+DPTR TH0,A R1 A,R1 A,@A+DPTR TL0,A IE,#82H TR0 P2.7,C1 KEYR,#03H P2.6,C4 KEYR,#02H CALCU P2.5,C3 KEYR,#01H CALCU
单片机实验报告_电子琴

随着科技的飞速发展,单片机技术已成为现代电子技术的重要分支。
为了更好地学习和掌握单片机编程及应用,我们设计并实现了一款基于单片机的简易电子琴。
本实验旨在通过设计一个简易电子琴,让学生深入了解单片机的原理和应用,提高动手实践能力。
二、实验目的1. 掌握单片机的基本原理和编程方法。
2. 学会使用定时器、中断、键盘扫描等技术。
3. 了解电子琴的工作原理和制作方法。
4. 培养学生的创新意识和团队协作能力。
三、实验原理本实验采用STC12C5A32S2单片机作为核心控制单元,通过定时器产生方波信号,驱动蜂鸣器发出不同频率的声音,实现电子琴的演奏功能。
具体原理如下:1. 单片机原理:STC12C5A32S2单片机是一款高性能、低功耗的单片机,具有丰富的片上资源,如定时器、中断、串口等。
2. 定时器:定时器用于产生固定频率的方波信号,驱动蜂鸣器发出不同频率的声音。
通过调整定时器的计数值,可以改变方波信号的频率,从而改变音调。
3. 中断:中断技术用于实现按键扫描功能。
当按键被按下时,单片机响应中断,读取按键状态,并产生相应的音调。
4. 键盘扫描:键盘扫描技术用于检测按键状态。
通过扫描键盘矩阵,可以判断哪个按键被按下,并产生相应的音调。
四、实验内容1. 硬件设计:主要包括单片机、蜂鸣器、键盘、电阻、电容等元器件。
将元器件按照电路图连接,形成电子琴的硬件电路。
2. 软件设计:主要包括主程序、定时器中断服务程序、按键扫描程序等。
通过Keil C编程,实现电子琴的演奏功能。
3. 调试与测试:对电子琴进行调试和测试,确保其能够正常工作。
1. 搭建电路:按照电路图连接元器件,形成电子琴的硬件电路。
2. 编写程序:使用Keil C编写主程序、定时器中断服务程序、按键扫描程序等。
3. 编译程序:将编写好的程序编译成HEX文件。
4. 烧录程序:将编译好的HEX文件烧录到单片机中。
5. 调试与测试:使用万用表测试电路是否正常工作,并对程序进行调试,确保电子琴能够正常演奏。
单片机制作电子琴源程序

#include "ht66f018.h"//同一首歌unsigned char const Music_Same[]={ 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x66, 0x18,0x03,0x17,0x02, 0x15,0x02, 0x16,0x01, 0x15,0x02, 0x10,0x02,0x15,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x02,0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x02, 0x18,0x66,0x17,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x16,0x00,0x17,0x01, 0x19,0x02, 0x1B,0x02, 0x1B,0x70, 0x1A,0x03,0x1A,0x01, 0x19,0x02, 0x19,0x03, 0x1A,0x03, 0x1B,0x02,0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x18,0x66, 0x18,0x03,0x19,0x02, 0x1A,0x02, 0x19,0x0C, 0x18,0x0D, 0x17,0x03,0x16,0x01, 0x11,0x02, 0x11,0x03, 0x10,0x03, 0x0F,0x0C,0x10,0x02, 0x15,0x00, 0x1F,0x01, 0x1A,0x01, 0x18,0x66,0x19,0x03, 0x1A,0x01, 0x1B,0x02, 0x1B,0x03, 0x1B,0x03,0x1B,0x0C, 0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x1F,0x01,0x1A,0x01, 0x18,0x66, 0x19,0x03, 0x1A,0x01, 0x10,0x02,0x10,0x03, 0x10,0x03, 0x1A,0x0C, 0x18,0x0D, 0x17,0x03,0x16,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x70,0x18,0x03, 0x17,0x02, 0x15,0x03, 0x15,0x03, 0x16,0x66,0x16,0x03, 0x16,0x02, 0x16,0x03, 0x15,0x03, 0x10,0x02,0x10,0x01, 0x11,0x01, 0x11,0x66, 0x10,0x03, 0x0F,0x0C,0x1A,0x02, 0x19,0x02, 0x16,0x03, 0x16,0x03, 0x18,0x66,0x18,0x03, 0x18,0x02, 0x17,0x03, 0x16,0x03, 0x19,0x00,0x00,0x00 };//两只蝴蝶unsigned char const Music_Two[] ={ 0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x16,0x03,0x17,0x01, 0x16,0x03, 0x17,0x03, 0x16,0x03, 0x15,0x01,0x10,0x03, 0x15,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x16,0x01,0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x19,0x03,0x19,0x01, 0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x17,0x01,0x16,0x03, 0x16,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,0x16,0x03, 0x15,0x03, 0x10,0x03, 0x10,0x0D, 0x15,0x00,0x19,0x03, 0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03,0x1B,0x03, 0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03,0x16,0x0D, 0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03,0x1A,0x02, 0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03,0x16,0x01, 0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03,0x19,0x02, 0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E,0x1B,0x04, 0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E,0x1B,0x04, 0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03,0x19,0x03,0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03, 0x1B,0x03,0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03, 0x16,0x03,0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03, 0x1A,0x02,0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x01,0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03, 0x19,0x03,0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,0x17,0x16, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03, 0x0F,0x02,0x10,0x03, 0x15,0x00, 0x00,0x00 };//挥着翅膀的女孩unsigned char const Music_Girl[]={ 0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x03,0x16,0x03, 0x17,0x03, 0x17,0x03, 0x17,0x03, 0x18,0x03,0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x02, 0x18,0x03,0x17,0x03, 0x15,0x02, 0x18,0x03, 0x17,0x03, 0x18,0x02,0x10,0x03, 0x15,0x03, 0x16,0x02, 0x15,0x03, 0x16,0x03,0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x1A,0x03,0x1B,0x03, 0x1F,0x03, 0x1F,0x03, 0x17,0x03, 0x18,0x03,0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x03, 0x17,0x03,0x18,0x03, 0x1F,0x03, 0x1F,0x02, 0x16,0x03, 0x17,0x03,0x18,0x03, 0x17,0x03, 0x18,0x03, 0x20,0x03, 0x20,0x02,0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,0x1F,0x03,0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,0x1A,0x03, 0x19,0x03, 0x15,0x03, 0x15,0x03, 0x17,0x03,0x16,0x66, 0x17,0x04, 0x18,0x04, 0x18,0x03, 0x19,0x03,0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,0x1A,0x03, 0x19,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,0x1F,0x00, 0x1A,0x03, 0x1A,0x03, 0x1A,0x03, 0x1B,0x03,0x1B,0x03, 0x1A,0x03, 0x19,0x03, 0x19,0x02, 0x17,0x03,0x15,0x17, 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x18,0x03,0x17,0x04, 0x18,0x0E, 0x18,0x03, 0x17,0x04, 0x18,0x0E,0x18,0x66, 0x17,0x03, 0x18,0x03, 0x17,0x03, 0x18,0x03,0x20,0x03, 0x20,0x02, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66,0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03, 0x1B,0x03,0x1F,0x66, 0x1F,0x04, 0x1B,0x0E, 0x1B,0x03, 0x19,0x03,0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,0x15,0x03, 0x15,0x03, 0x17,0x03, 0x16,0x66, 0x17,0x04,0x18,0x04, 0x18,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,0x1F,0x66, 0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03,0x1B,0x03, 0x1F,0x66, 0x1F,0x03, 0x1B,0x03, 0x19,0x03,0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,0x18,0x02,0x18,0x03, 0x1A,0x03, 0x19,0x0D, 0x15,0x03, 0x15,0x02,0x18,0x66, 0x16,0x02, 0x17,0x02, 0x15,0x00, 0x00,0x00};unsigned char const Music_sd[]={ 0x0F,0x03, 0x0F,0x03, 0x17,0x03, 0x16,0x03, 0x15,0x03,0x0F,0x02, 0x0F,0x03, 0x0F,0x03, 0x0F,0x03, 0x17,0x03,0x16,0x03, 0x15,0x03, 0x10,0x02, 0x10,0x03, 0x10,0x03,0x18,0x03, 0x17,0x03, 0x16,0x03, 0x10,0x02, 0x10,0x03,0x19,0x03, 0x19,0x03, 0x18,0x03, 0x16,0x03, 0x17,0x02,0x15,0x03, 0x0F,0x03, 0x0F,0x03, 0x17,0x03, 0x16,0x03,0x15,0x03, 0x0F,0x02, 0x0F,0x03, 0x0F,0x03, 0x17,0x03,0x16,0x03, 0x15,0x03, 0x10,0x02, 0x10,0x03, 0x10,0x03,0x18,0x03, 0x17,0x03, 0x16,0x03, 0x19,0x03, 0x19,0x03,0x19,0x03, 0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x18,0x03,0x16,0x03, 0x15,0x16, 0x17,0x03, 0x17,0x03, 0x17,0x02,0x17,0x03, 0x17,0x03, 0x17,0x02, 0x17,0x03, 0x19,0x03,0x15,0x03, 0x16,0x04, 0x17,0x01, 0x18,0x03, 0x18,0x03,0x18,0x03, 0x18,0x04, 0x18,0x03, 0x17,0x03, 0x17,0x03,0x17,0x04, 0x17,0x04, 0x17,0x03, 0x16,0x03, 0x16,0x03,0x15,0x03, 0x16,0x03, 0x19,0x02, 0x19,0x03, 0x19,0x03,0x18,0x03, 0x16,0x03, 0x15,0x02, 0x00,0x00 }; unsigned char const Music_lzlh[]={ 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x15,0x03, 0x15,0x03,0x18,0x03,0x19,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x19,0x03,0x1A,0x03, 0x19,0x03, 0x18,0x03, 0x17,0x02, 0x15,0x02,0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x18,0x03, 0x17,0x02,0x15,0x02, 0x16,0x02, 0x0F,0x02, 0x15,0x16, 0x16,0x02,0x0F,0x02, 0x15,0x16, 0x00,0x00 };unsigned char const Music_fk[]={ 0x15,0x03, 0x10,0x03, 0x11,0x03, 0x15,0x66, 0x15,0x03,0x11,0x03, 0x15,0x03, 0x17,0x03, 0x17,0x03, 0x15,0x03,0x11,0x03, 0x10,0x03, 0x10,0x03, 0x10,0x66, 0x10,0x7A,0x15,0x03, 0x10,0x03, 0x11,0x03, 0x15,0x03, 0x10,0x03,0x11,0x03, 0x15,0x03, 0x11,0x03, 0x15,0x03, 0x17,0x03,0x17,0x03, 0x11,0x03, 0x11,0x03, 0x10,0x03, 0x15,0x03,0x10,0x66, 0x10,0x7A, 0x15,0x03, 0x16,0x03, 0x17,0x03,0x15,0x03, 0x16,0x03, 0x17,0x03, 0x19,0x03, 0x18,0x03,0x17,0x03, 0x15,0x03, 0x16,0x03, 0x17,0x66, 0x17,0x03,0x16,0x03, 0x15,0x03, 0x11,0x03, 0x15,0x03, 0x16,0x03,0x10,0x66, 0x10,0x02, 0x15,0x03, 0x16,0x03, 0x17,0x03,0x15,0x03, 0x16,0x03, 0x17,0x03, 0x19,0x03, 0x1A,0x03,0x17,0x03, 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x17,0x03,0x1A,0x03, 0x16,0x03, 0x16,0x03, 0x15,0x03, 0x16,0x03,0x16,0x03, 0x15,0x03, 0x10,0x17, 0x17,0x03, 0x17,0x03,0x16,0x03, 0x17,0x03, 0x1F,0x66, 0x1F,0x66, 0x1B,0x66,0x17,0x03, 0x16,0x03, 0x17,0x03, 0x1A,0x03,0x19,0x03,0x17,0x03, 0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x15,0x03,0x15,0x03, 0x15,0x03, 0x15,0x03, 0x16,0x03, 0x17,0x03,0x17,0x03, 0x17,0x03, 0x17,0x03, 0x17,0x03, 0x18,0x03,0x17,0x03, 0x15,0x66, 0x15,0x03, 0x11,0x03, 0x15,0x03,0x1A,0x03, 0x1A,0x03, 0x1A,0x03, 0x1A,0x03, 0x19,0x03,0x1A,0x03, 0x1B,0x7A, 0x00,0x00 };void KeyScan();void play_while();void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed);#define u8 unsigned char#define u16 unsigned int#define u32 unsigned long#define WaitStatus 0 //按键过程的状态#define PressStatus 1#define ReleaseStatus 2#define BeepIO _pb4#define KEY1 _pb3#define KEY2 _pa7#define KEY3 _pa6#define KEY4 _pa5#define KEY5 _pa4#define KEY6 _pb2#define KEY7 _pb1#define KEY8 _pb0#define LED1 _pb5#define LED2 _pb6#define LED3 _pa3#define LED4 _pa1#define LED5 _pa0#define LED6 _pc2#define LED7 _pc1#define LED8 _pc0typedef struct{u16 count ;u8 name;u8 enable;}Timer;u8 KeyStatus=0,KeyPress=0,keyval=0;u8 mu_st=0;u8 music_en=0xff;Timer mytimer;#define true 1#define false 0const u16 fout[3][7]={{15289,13621,12135,11454,10204,9091,8099},{7645,6811,6068,5727,5102,4545,4050},{3822,3405,3034,2864,2551,2273,2025},};#define SOUND_SPACE 4/5 //定义普通音符演奏的长度分率,//每4分音符间隔unsigned int const FreTab[12] = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表unsigned char const SignTab[7] = { 0,2,4,5,7,9,11 };//1~7在频率表中的位置unsigned char const LengthTab[7]= { 1,2,4,8,16,32,64 };unsigned int NewFreTab[12]; //新的频率表unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,SoundLength;unsigned char Tone,Length;unsigned char *Sound_bak;unsigned char start=0;void LED(u8 data){_pc0=data;_pc1=data>>1;_pc2=data>>2;_pa0=data>>3;_pa1=data>>4;_pa3=data>>5;_pb6=data>>6;_pb5=data>>7;}void LED3_8(u8 data){switch(data){case 0:LED(~0x01);break;case 1:LED(~0x02);break;case 2:LED(~0x04);break;case 3:LED(~0x08);break;case 4:LED(~0x10);break;case 5:LED(~0x20);break;case 6:LED(~0x40);break;case 7:LED(~0x80);break;}}void delayms(u16 i){u16 j;while(i--){for(j=0;j<220;j++){asm("nop");asm("nop");asm("nop");}}}void fchange(u16 f){_tm2al=f&0xff;_tm2ah=f>>8;}void main(){u8 worksta=1;_wdtc=0xa8;_acerl=0x00;_pcc=0x00;_pbc5=0;_pbc6=0;_csel=0;_cos=1;_acerl=0x00;_pbc|=0x0f;_pbc4=0;_pac=0xf0;_pac2=1;_papu2=1;_pbc|=0x0f;_pbpu|=0x0f;_pac|=0xf0;_papu|=0xf0;//ctm_tm2c0=0x10;_tm2c1=0xc1;_tm2al=0;_tm2ah=0>>8;_t2on=1;_mf1e=1;_t2ae=1;//stm_tm0c0=0x00;_tm0c1=0xc1;_tm0al=20000;_tm0ah=20000>>8;_mf0e=1;_t0ae=1;_t0on=1;_pawu2=1;_emi=1;while(1){KeyScan();if(KeyPress){KeyPress=0;if(keyval==1){start=1;worksta=2;music_en=0xff;switch(mu_st){case 0:Play(Music_sd,0,3,50);break;case 1:Play(Music_Two,0,3,50);break;case 2:Play(Music_Girl,0,3,50);break;case 3:Play(Music_Same,0,3,50);break;case 4:Play(Music_lzlh,0,3,50);break;case 5:Play(Music_fk,0,3,50);break;case 6:Point=SoundLength;worksta=2;break;}if(++mu_st==7)mu_st=0;}}switch(worksta){case 1:if(KEY1){LED1=1;}else{LED1=0;fchange(fout[0][1]);}if(KEY2){LED2=1;}else{LED2=0;fchange(fout[0][2]);}if(KEY3){LED3=1;}else{LED3=0;fchange(fout[0][3]);}if(KEY4){LED4=1;}else{LED4=0;fchange(fout[0][4]);}if(KEY5){LED5=1;}else{LED5=0;fchange(fout[0][5]);}if(KEY6){LED6=1;}else{LED6=0;fchange(fout[0][6]);}if(KEY7){LED7=1;}else{LED7=0;fchange(fout[0][7]);}if(KEY1 && KEY2 && KEY3 && KEY4 && KEY5 && KEY6 &&KEY7 )fchange(0);break;case 2: play_while();if(music_en==0)worksta=1;break;}}}DEFINE_ISR(tbase0,0x0c){_t0af=0;if(mytimer.enable==true){mytimer.count--;if(mytimer.count==0)mytimer.enable=false;}}DEFINE_ISR(t2,0x10){_t2af=0;BeepIO=~BeepIO;}void KeyScan(){switch(KeyStatus){case WaitStatus: //等待状态if(_pa2==0 )KeyStatus=PressStatus;break;case PressStatus: //按下状态if(_pa2==0 ){if(_pa2==0)keyval=1;KeyPress=1;KeyStatus=ReleaseStatus;}else{KeyStatus=WaitStatus;}break;case ReleaseStatus: //等待释放状态if(_pa2==0 ){}else{KeyStatus=WaitStatus;}break;}}//************************************************************************** void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed) {unsigned char i,j;Sound_bak=Sound;for(i=0;i<12;i++) // 根据调号及升降八度来生成新的频率表{j = i + Signature;if(j > 11){j = j-12;NewFreTab[i] = FreTab[j]*2;}elseNewFreTab[i] = FreTab[j];if(Octachord == 1)NewFreTab[i]>>=2;else if(Octachord == 3)NewFreTab[i]<<=2;}SoundLength = 0;while(Sound[SoundLength] != 0x00) //计算歌曲长度{SoundLength+=2;}Point = 0;Tone = Sound[Point];Length = Sound[Point+1]; // 读出第一个音符和它时时值LDiv0 = 12000/Speed; // 算出1分音符的长度(几个10ms)LDiv4 = LDiv0/4; // 算出4分音符的长度LDiv4 = LDiv4-LDiv4*SOUND_SPACE; // 普通音最长间隔标准}void play_while(){u8 SL,SH,SM,SLen,XG,FD;if(start==1 &&(Point < SoundLength)){SL=Tone%10; //计算出音符LED3_8(SL);SM=Tone/10%10; //计算出高低音SH=Tone/100; //计算出是否升半CurrentFre = NewFreTab[SignTab[SL-1]+SH]; //查出对应音符的频率if(SL!=0){if (SM==1) CurrentFre >>= 2; //低音if (SM==3) CurrentFre <<= 2; //高音fchange(4000000/CurrentFre);}SLen=LengthTab[Length%10]; //算出是几分音符XG=Length/10%10; //算出音符类型(0普通1连音2顿音)FD=Length/100;LDiv=LDiv0/SLen; //算出连音音符演奏的长度(多少个10ms)if (FD==1)LDiv=LDiv+LDiv/2;if(XG!=1)if(XG==0) //算出普通音符的演奏长度if (SLen<=4)LDiv1=LDiv-LDiv4;elseLDiv1=LDiv*SOUND_SPACE;elseLDiv1=LDiv/2; //算出顿音的演奏长度elseLDiv1=LDiv;if(SL==0) LDiv1=0;LDiv2=LDiv-LDiv1; //算出不发音的长度=1;if (SL!=0)//c{mytimer.count=LDiv1;mytimer.enable=true;}start=0;}if(==1 && mytimer.enable==false){=2;//zif(LDiv2!=0){fchange(0);BeepIO=1;mytimer.count=LDiv2;mytimer.enable=true;}}if(==2 && mytimer.enable==false){Point+=2; //cTone=Sound_bak[Point];Length=Sound_bak[Point+1];start=1;}if(Point >=SoundLength){fchange(0);BeepIO = 1;start=0;music_en=0;}}。
基于51单片机的电子琴完整版

基于51单片机的电子琴完整版#include<reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned charsbit feng = P0^7; // 蜂鸣器uint FTemp;uint code tab[] = { //定时半周期的初始值64021,64103,64260,64400, //低音3 4 5 664524,64580,64684,64777, //低音7,中音1 2 364820,64898,64968,65030, //中音4 5 6 765058,65110,65157,65178}; //高音1 2 3 4//用扫描法读P1 外接4×4 键盘uchar Keyscan(void){uchar i, j, temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7};for(j = 0; j < 4; j++) //循环四次,扫描四行{P1 = Buffer[j]; //在低四位分别输出一个低电平_nop_();temp = 0x80; //计划先读出P1.7位for(i = 0; i < 4; i++) //循环四次,检查四列{if(!(P1& temp)) //从高四位,截取1位{return (i + j * 4); //返回取得的按键值}temp >>= 1; //换右边一位}}return 16; //没有键按下就返回16}void Main(void){uchar Key_Value = 16, Key_Temp1, Key_Temp2;//读出的键值 TMOD = 0x01; //T0定时方式1ET0 = 1; //允许T0中断EX0 = 1; //允许INT0中断EA = 1;//开总中断while(1){TR0 = 0; //T0工作停,暂不发音Key_Temp1 = Keyscan(); //第一次读入按键if(Key_Temp1 != 16){ //有键按下Key_Temp2 = Keyscan(); //再读一次if (Key_Temp1 == Key_Temp2) //两次相等{Key_Value = Key_Temp1; //就确认下来FTemp = tab[Key_Value]; //根据键值,取出定时半周期的初始值TR0 = 1; //启动定时器T0,发音while (Keyscan() < 16); //等待释放feng = 1; //停止发音}}}}//========================================================= =====void T0_INT(void) interrupt 1{TL0 = FTemp; //载入定时半周期的初始值TH0 = FTemp >> 8;feng = ~feng; //发音。
基于单片机的电子琴设计

基于单片机的电子琴设计一、引言二、总体设计方案(一)设计目标设计一款基于单片机的电子琴,能够实现基本的音符演奏、音色切换、节奏控制等功能,并且具有良好的音质和稳定性。
(二)系统组成本电子琴系统主要由单片机控制模块、键盘输入模块、音频输出模块、显示模块和电源模块等部分组成。
1、单片机控制模块选用 STM32 系列单片机作为控制核心,负责处理键盘输入信号、生成音频信号、控制显示等功能。
2、键盘输入模块采用矩阵键盘,通过扫描键盘获取用户的按键操作,将其转换为对应的音符编码发送给单片机。
3、音频输出模块使用DAC 芯片将单片机生成的数字音频信号转换为模拟音频信号,再通过放大器和扬声器输出声音。
4、显示模块采用液晶显示屏,用于显示当前的演奏状态、音色选择、节奏模式等信息。
5、电源模块为整个系统提供稳定的电源供应,可采用电池供电或外接电源适配器。
三、硬件设计(一)单片机最小系统STM32 单片机的最小系统包括时钟电路、复位电路和电源电路。
时钟电路为单片机提供工作时钟,复位电路用于系统初始化,电源电路为单片机提供稳定的电源。
(二)键盘电路矩阵键盘由行线和列线组成,通过逐行扫描的方式检测按键状态。
将键盘的行线和列线分别连接到单片机的 GPIO 引脚,通过编程实现键盘扫描和按键识别。
(三)音频输出电路选用高性能的 DAC 芯片,如 PCM1794,将单片机输出的数字音频信号转换为模拟音频信号。
为了提高音频输出的质量,还需要添加放大器和滤波电路,以增强信号的功率和去除噪声。
(四)显示电路液晶显示屏通过 SPI 接口或 I2C 接口与单片机连接,单片机通过发送指令和数据来控制显示屏的显示内容。
(五)电源电路根据系统的工作电压和电流需求,选择合适的电源芯片,如LM7805 等,将输入电源转换为所需的电压,并通过滤波电容等元件提高电源的稳定性。
四、软件设计(一)主程序流程主程序首先进行系统初始化,包括单片机初始化、键盘初始化、音频输出初始化、显示初始化等。
单片机实现电子琴并可播放歌曲

0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,
0xC6,0xA1,0x86,0x8e};
//中音1-7和高音1-7对应频率列表
uint16 code NoteFrequ[] = {
523,587,659,698,784,880,988, //中音1-7
for(i=0;i<4;i++)
{
P2=buff[i];
temp=P2;
temp&=0xf0;//取P2的高四位;
while(temp!=0xf0)
{
delay5ms(5);//延时5ms去除抖动;
temp=P2;
temp&=0xf0;
while(temp!=0xf0)
{
switch(temp)
{
case 0xe0:num=i*4+0;break;//获取键值;
}
if(num==8)
{
T0LoadH = 0xff;
T0LoadL = 0x00;
TR0 = 1;
flag = 0;
ADDR0 = 0;
ADDR1 = 1;
ADDR2 = 1;
P0 = 0x00;
for(i=0;i<10000;i++);//闪烁灯全亮
PlayTwoTiger();
}
}
void PlayTwoTiger()
//计算发生时间,为总时间的0.75
/***********去除抖动********************/
while(temp!=0xf0)
{
temp=P2;
单片机电子琴程序

单片机电子琴程序(共3页) -本页仅作为预览文档封面,使用时请删除本页-;*******************************************************; 简易电子琴实验说明;实验目的: 1.掌握蜂鸣器的使用; 2.掌握蜂鸣器的不同发音的方法;实验内容: 1.通过单片机,令1-7号键由低到高发出1-7的音阶K1 BIT ;按键1K2 BIT ;按键2K3 BIT ;按键3K4 BIT ;按键4K5 BIT ;按键5K6 BIT ;按键6K7 BIT ;按键7Buzzer BIT ;蜂鸣器M1 EQU 17M2 EQU 16M3 EQU 15M4 EQU 14M5 EQU 13M6 EQU 12M7 EQU 11ORG 0000HLJMP STARTORG 0100HSTART: MOV SP,#60HMAIN: MOV P1,#0FFH ;P1口初始化LCALL Demo ;播放一段演示音乐MAIN_1: JB K1,MAIN_2 ;判断1号键是否按下,否则检测2号键LCALL Sound1 ;发音子程序MAIN_2: JB K2,MAIN_3 ;判断2号键是否按下,否则检测3号键LCALL Sound2 ;发音子程序MAIN_3: JB K3,MAIN_4 ;判断2号键是否按下,否则检测4号键LCALL Sound3 ;发音子程序MAIN_4: JB K4,MAIN_5 ;判断4号键是否按下,否则检测5号键LCALL Sound4 ;发音子程序MAIN_5: JB K5,MAIN_6 ;判断5号键是否按下,否则检测6号键LCALL Sound5 ;发音子程序MAIN_6: JB K6,MAIN_7 ;判断6号键是否按下,否则检测7号键LCALL Sound6 ;发音子程序MAIN_7: JB K7,MAIN_73 ;判断7号键是否按下,否则跳回检测1号键LCALL Sound7 ;发音子程序MAIN_73: SJMP MAIN_1 ;返回从1号键开始扫描;播放演示音乐Demo: MOV DPTR,#MusicDemo_1: CLR AMOVC A,@A+DPTRINC DPTRJZ Demo_RetLCALL SoundMCU ;放音子程序JMP Demo_1Demo_Ret: RET;乐曲:),0-结果标志Music: DB M1,M2,M3,M4,M5,M6,M7,M7,M7,M6,M5,M4,M3,M2,M1 DB M1,M2,M1,M2,M3,M2,M3,M4,M3,M4,M5,M4,M5,M6,M5DB M6,M7,M6,M7,M7,M6,M6,M6,0;程序控制发音SoundMCU: MOV R5,#40H ;控制放音时间MOV R7,AACALL TimeMOV R6,ASoundMCU_0: PUSH 06HSoundMCU_1: ACALL MusicalScaleDJNZ R6,SoundMCU_1POP 06HDJNZ R5,SoundMCU_0RET;计算时长Time: MOV B,#0FFHXCH A,BDIV ABXCH A,BCJNE A,#8,$+3JC Time_1INC BTime_1: XCH A,BRETMusicalScale: MOV A,R7MusicalScale1: CLR Buzzer ;1号键发音LCALL Delay ;延时DJNZ ACC,MusicalScale1MOV A,R7MusicalScale2: SETB BuzzerLCALL Delay ;延时DJNZ ACC,MusicalScale2RET;1号键发音Sound1: MOV R7,#M1 ;发音频率,越大频率越低Sound1_1: ACALL MusicalScaleJNB K1,Sound1_1RET;2号键发音Sound2: MOV R7,#M2 ;发音频率,越大频率越低Sound2_1: ACALL MusicalScaleJNB K2,Sound2_1RET;3号键发音Sound3: MOV R7,#M3Sound3_1: ACALL MusicalScaleJNB K3,Sound3_1RET;4号键发音Sound4: MOV R7,#M4Sound4_1: ACALL MusicalScaleJNB K4,Sound4_1RET;5号键发音Sound5: MOV R7,#M5Sound5_1: ACALL MusicalScaleJNB K5,Sound5_1RET;6号键发音Sound6: MOV R7,#M6Sound6_1: ACALL MusicalScaleJNB K6,Sound6_1RET;7号键发音Sound7: MOV R7,#M7 ;发音频率,越大频率越低Sound7_1: ACALL MusicalScaleJNB K7,Sound7_1RET;延时Delay: NOPRETEND。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
;******************************************************* ; 简易电子琴实验说明
;实验目的: 1.掌握蜂鸣器的使用
; 2.掌握蜂鸣器的不同发音的方法
;实验内容: 1.通过单片机,令1-7号键由低到高发出1-7的音阶K1 BIT ;按键1
K2 BIT ;按键2
K3 BIT ;按键3
K4 BIT ;按键4
K5 BIT ;按键5
K6 BIT ;按键6
K7 BIT ;按键7
Buzzer BIT ;蜂鸣器
M1 EQU 17
M2 EQU 16
M3 EQU 15
M4 EQU 14
M5 EQU 13
M6 EQU 12
M7 EQU 11
ORG 0000H
LJMP START
ORG 0100H
START: MOV SP,#60H
MAIN: MOV P1,#0FFH ;P1口初始化
LCALL Demo ;播放一段演示音乐
MAIN_1: JB K1,MAIN_2 ;判断1号键是否按下,否则检测2号键LCALL Sound1 ;发音子程序
MAIN_2: JB K2,MAIN_3 ;判断2号键是否按下,否则检测3号键LCALL Sound2 ;发音子程序
MAIN_3: JB K3,MAIN_4 ;判断2号键是否按下,否则检测4号键LCALL Sound3 ;发音子程序
MAIN_4: JB K4,MAIN_5 ;判断4号键是否按下,否则检测5号键LCALL Sound4 ;发音子程序
MAIN_5: JB K5,MAIN_6 ;判断5号键是否按下,否则检测6号键LCALL Sound5 ;发音子程序
MAIN_6: JB K6,MAIN_7 ;判断6号键是否按下,否则检测7号键LCALL Sound6 ;发音子程序
MAIN_7: JB K7,MAIN_73 ;判断7号键是否按下,否则跳回检测1号键LCALL Sound7 ;发音子程序
MAIN_73: SJMP MAIN_1 ;返回从1号键开始扫描
;播放演示音乐
Demo: MOV DPTR,#Music
Demo_1: CLR A
MOVC A,@A+DPTR
INC DPTR
JZ Demo_Ret
LCALL SoundMCU ;放音子程序
JMP Demo_1
Demo_Ret: RET
;乐曲:),0-结果标志
Music: DB M1,M2,M3,M4,M5,M6,M7,M7,M7,M6,M5,M4,M3,M2,M1 DB M1,M2,M1,M2,M3,M2,M3,M4,M3,M4,M5,M4,M5,M6,M5
DB M6,M7,M6,M7,M7,M6,M6,M6,0
;程序控制发音
SoundMCU: MOV R5,#40H ;控制放音时间
MOV R7,A
ACALL Time
MOV R6,A
SoundMCU_0: PUSH 06H
SoundMCU_1: ACALL MusicalScale
DJNZ R6,SoundMCU_1
POP 06H
DJNZ R5,SoundMCU_0
RET
;计算时长
Time: MOV B,#0FFH
XCH A,B
DIV AB
XCH A,B
CJNE A,#8,$+3
JC Time_1
INC B
Time_1: XCH A,B
RET
MusicalScale: MOV A,R7
MusicalScale1: CLR Buzzer ;1号键发音
LCALL Delay ;延时
DJNZ ACC,MusicalScale1
MOV A,R7
MusicalScale2: SETB Buzzer
LCALL Delay ;延时
DJNZ ACC,MusicalScale2
RET
;1号键发音
Sound1: MOV R7,#M1 ;发音频率,越大频率越低Sound1_1: ACALL MusicalScale
JNB K1,Sound1_1
RET
;2号键发音
Sound2: MOV R7,#M2 ;发音频率,越大频率越低Sound2_1: ACALL MusicalScale
JNB K2,Sound2_1
RET
;3号键发音
Sound3: MOV R7,#M3
Sound3_1: ACALL MusicalScale
JNB K3,Sound3_1
RET
;4号键发音
Sound4: MOV R7,#M4
Sound4_1: ACALL MusicalScale
JNB K4,Sound4_1
RET
;5号键发音
Sound5: MOV R7,#M5
Sound5_1: ACALL MusicalScale
JNB K5,Sound5_1
RET
;6号键发音
Sound6: MOV R7,#M6
Sound6_1: ACALL MusicalScale
JNB K6,Sound6_1
RET
;7号键发音
Sound7: MOV R7,#M7 ;发音频率,越大频率越低Sound7_1: ACALL MusicalScale
JNB K7,Sound7_1
RET
;延时
Delay: NOP
RET
END。