标题:
分享一个51单片机电子琴代码和仿真
[打印本页]
作者:
1290153461
时间:
2021-3-12 15:41
标题:
分享一个51单片机电子琴代码和仿真
51电子琴,附带仿真
仿真.jpg
(121.03 KB, 下载次数: 64)
下载附件
2021-3-12 15:58 上传
单片机源程序如下:
//////////////////////////////////////////////////////////////////////////////////
// 功能描述 : OLED 4接口
// ----------------------------------------------------------------
// GND 电源地
// VCC 接5V或3.3v电源
// SCL P1^0
// SDA P1^1
// ----------------------------------------------------------------
// K9 P1^2;//音乐播放按键
// KD P1^3;//低音播放
// KG P1^4;//高音播放
// beep P1^5; //蜂鸣器定义
//******************************************************************************/
#include "REG52.h"
#include "oled.h"
#include "bmp.h"
#include <music.h>
#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
#define uint unsigned int //无符号整型 宏定义 变量范围0~65535
sbit K9=P1^2;//音乐播放按键2
sbit KD=P1^3;//低音播放
sbit KG=P1^4;//高音播放
sbit beep=P1^5; //蜂鸣器定义
sbit K10=P1^6;//录入指示
sbit K11=P1^7;//休止符
sbit K12=P3^2;//播放录入的
sbit K13=P3^3;//
unsigned char n=0,m=0,k=0; //定义取频率常数m和节拍常数n 数组元素编号k
unsigned char music_load[]={ 8,2,9,2,10,2,11,2,12,2,12,2,12,1,11,1,10,2,11,2,11,2,11,1,10,1,9,1,0xff,8,2,10,2,12,4,0};
void delay(uchar i)//用于OLED显示
{
uchar j,u,v;
for(j=i;j>0;j--)
for(u=125;u>0;u--)
for(v=125;v>0;v--);
}
void delayms(unsigned char j) //毫秒延时子程序 用于播放音乐
{
while(--j); //采用while(--j) 不要采用while(j--); 各位可编译一下看看汇编结果就知道了!
}
void TimerInit()
{
TMOD|=0X11;//选择为定时器0/1模式,工作方式1,仅用TR0/1打开启动。
TH1=0x0b; //节拍用
TL1=0xdc;
IE=0x8A;//1000,1010打开EA/ET1/ET0
}
/******************按键程序*************************/
void oled_menu()//4功能
{
OLED_ShowNum(0,0,1,1,16);//1234
OLED_ShowNum(0,2,2,1,16);
OLED_ShowNum(0,4,3,1,16);
OLED_ShowNum(0,6,4,1,16);
OLED_ShowCHinese(10,0,7);//单音播放
OLED_ShowCHinese(28,0,8);
OLED_ShowCHinese(46,0,9);
OLED_ShowCHinese(64,0,10);
OLED_ShowCHinese(10,2,9);//播放音乐
OLED_ShowCHinese(28,2,10);
OLED_ShowCHinese(46,2,11);
OLED_ShowCHinese(64,2,12);
OLED_ShowCHinese(10,4,13);//录入音乐
OLED_ShowCHinese(28,4,14);
OLED_ShowCHinese(46,4,11);
OLED_ShowCHinese(64,4,12);
OLED_ShowCHinese(10,6,9);//播放录入音乐
OLED_ShowCHinese(28,6,10);
OLED_ShowCHinese(46,6,13);
OLED_ShowCHinese(64,6,14);
OLED_ShowCHinese(82,6,11);
OLED_ShowCHinese(100,6,12);
}
void oled_start()//欢迎使用林天羽
{
OLED_ShowCHinese(26,0,0);//欢迎使用
OLED_ShowCHinese(46,0,1);//
OLED_ShowCHinese(66,0,2);//
OLED_ShowCHinese(86,0,3);//
OLED_ShowCHinese(36,4,4);//林天羽
OLED_ShowCHinese(56,4,5);//
OLED_ShowCHinese(76,4,6);//
OLED_ShowString(12,6,"2016330301081",16);
delay(150);
OLED_Clear();
oled_menu();
}
void load_music() //录入功能--对应28个音,1个休止符自动1/4拍,末尾自动添加停止符号
{
uint i,j,temp;
uchar ky=0,kj=0,kp=0; //定义数组元素编号ky,kj,kp,休止符次数kp
music_load[0]=0;//保存第一个元素为0,按键时复写,并要求下一个元素为0
while(K10==0)
{
start2:
temp = P2;
j=3;//C调
if(KD==0)j=4;//低音
else if(KG==0)j=2;//高音
if(KG==0&&KD==0)j=1;//更高音
if(K11==0)//休止符1/4
{
delayms(5);
if((ky+kj)%2==0)//如果此时需要输入音调,则直接用休止符代替
{
OLED_ShowCHinese(80,0,16);//休止符
OLED_ShowCHinese(96,0,17);
OLED_ShowCHinese(112,0,18);
music_load[ky+kj+kp]=0xff;//保存休止符为0xff
music_load[ky+kj+kp+1]=0;
kp++;
while(K11==0);P0=0;OLED_ShowCHinese(80,0,15);OLED_ShowCHinese(96,0,15);OLED_ShowCHinese(112,0,15);
}
else if((ky+kj)%2==1)//如果此时需要输入节拍,则节拍默认1/4,外加1/4休止
{
OLED_ShowCHinese(80,0,16);//休止符
OLED_ShowCHinese(96,0,17);
OLED_ShowCHinese(112,0,18);
music_load[ky+kj+kp]=1;
music_load[ky+kj+kp+1]=0xff;//保存休止符为0xff
music_load[ky+kj+kp+2]=0;
kj++;
kp++;
while(K11==0); P0=0;OLED_ShowCHinese(80,0,15);OLED_ShowCHinese(96,0,15);OLED_ShowCHinese(112,0,15);
}
goto start2;
}
for(i=0;i<8;i++)
{
if(temp==for_P2[i])
{
if((ky+kj)%2==0)//音调
{
OLED_ShowNum(100,0,1+i,1,16);
m=7*j-i-1;n=0xff; //取频率常数m=28-mk,mk=music[第一个元素] 和 节拍常数n=4*nk,nk=music[第二个元素]
music_load[ky+kj+kp]=28-m;//保存
music_load[ky+kj+kp+1]=4;//自动补齐节拍为一拍
music_load[ky+kj+kp+2]=0;//确保结束符号
TR1=1; //开定时器1
TH0=T_H0[m];
TL0=T_L0[m];
while(P2==for_P2[i]) TR0=1; //等待节拍完成, 通过P1口输出音频(可多声道哦!)
TR0=0;
TR1=0;
OLED_ShowCHinese(100,0,15);
ky++;
}
else if((ky+kj)%2==1)//节拍
{
/***********************/
P0=smg_du[1+i];//使数码管显示该音调的字符
music_load[ky+kj+kp]=i+1;//保存
music_load[ky+kj+kp+1]=0;
kj++;
while(P2==for_P2[i]);
}
}
}
}
}
void play_music_load() //按下按键播放单音--一个音阶7个音
{
unsigned char i=0,p=0;
while(1)
{
start:
p=music_load[i];
if(p==0) //音乐停止标志
{
i=0;
delayms(100);
goto ending;
}
else if(p==0xff) //若碰到休止符,停止1/4拍,用第八个按键输入休止符
{
i=i+1;
n=1;//暂停1/4拍
P0=smg_du[0];
OLED_ShowNum(100,0,0,1,16);
TR1=1;
while(n!=0);
TR0=0;
OLED_ShowCHinese(100,0,15);
goto start;
}
else //取频率常数m和节拍常数n
{
m=28-music_load[i++];
n=8*music_load[i++];
P0=smg_du[(28-m)%7];
OLED_ShowNum(100,0,(28-m)%7,1,16);
}
TR1=1; //开定时器1
TH0=T_H0[m];
TL0=T_L0[m];
while(n!=0) TR0=1;
TR0=0;
TR1=0;
OLED_ShowCHinese(100,0,15);
} ending: ;
}
int main(void)
{
TimerInit();
OLED_Init(); //初始化OLED
OLED_Clear();
oled_start();
//播放音乐部分
while(1)
{
// if(K13==0)key();//1
// if(K9==0)play_music();
if(K10==0)load_music();//1
if(K12==0)play_music_load();
//OLED_ShowNum(100,0,1+i,1,16);OLED_ShowCHinese(100,0,15);
}
}
void int0() interrupt 1 //采用中断0 控制音调
{
TH0=T_H0[m];
TL0=T_L0[m];
beep=~beep;
}
void int1() interrupt 3 //采用中断3 控制节拍 优先级低
{
TH1=0x0b;
TL1=0xdc;
n--;
}
复制代码
所有资料51hei提供下载:
51单片机电子琴.rar
(97.26 KB, 下载次数: 27)
2021-3-12 15:41 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1