
跪求单片机电子琴C程序,3*3的矩阵键盘,设计八个音就好
2个回答
展开全部
#include<reg51.h>
#include<absacc.h>
#include<stdio.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
uchar STH0; //定时器计数初值
uchar STL0;
uchar k,key;
sbit SPK=P3^7;
sbit LED=P3^6;
//音符与计数值对应表
void delay1(uint ms) //播放歌曲时实现节拍的延时函数
{
uchar t;
while(ms--) for(t=0;t<120;t++);
}
uint code tab[]={64580,64684,64777,
64898,64968,65030,
65110, 65058};
uchar code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,
212,212,106,126,159,169,190,119,119,126,159,142,159,0};
// 生日快乐歌节拍表,节拍决定每个音符的演奏长短
uchar code SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,
9,3,12,12,12,12,12,9,3,12,12,12,24,0};
void PlayMusic()
{
uint i=0,j,k;
while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
{ //播放各个音符,SONG_LONG 为拍子长度
for(j=0;j<SONG_LONG[i]*20;j++)
{
SPK=~SPK;
//SONG_TONE延时表决定了每个音符的频率
for(k=0;k<SONG_TONE[i]/3;k++);
}
delay1(10);
i++;
}
}
//键消抖延时函数
void delay(void)
{
uchar i;
for(i=300;i>0;i--);
}
//键扫描函数
uchar getkey(void)
{
uchar scancode,tmpcode;
if((P2&0x07)==0x07)
return(0);
else scancode=0xdf;
while((scancode&0x04)!=0)
{
P2=scancode; //输入行扫描码
if((P2&0x07)!=0x07) //本行有键按下
{
tmpcode=(P2&0x07)|0xf8;
return((~scancode)+(~tmpcode));
}
else scancode=(scancode>>1)|0x80;
}
}
//定时器0中断服务子程序
void time0_int(void) interrupt 1 using 0
{
TH0=STH0;
TL0=STL0;
SPK=~SPK;
}
void main(void)
{
IE=0X87;
TMOD=0x01;
ET0=1;
EA=1;
IT0=1;
while(1)
{
P2=0x07;
if((P2&0x07)!=0x07)
{
delay();
if((P2&0x07)!=0x07)
{
key=getkey();
switch(key)
{ case 0x09: k=0;LED=0;delay1(300);LED=1;break;
case 0x0a: k=1;LED=0;delay1(300);LED=1;break;
case 0x0c: k=2;LED=0;delay1(300);LED=1;break;
case 0x11: k=3;LED=0;delay1(300);LED=1;break;
case 0x12: k=4;LED=0;delay1(300);LED=1;break;
case 0x14: k=5;LED=0;delay1(300);LED=1;break;
case 0x22: k=6;LED=0;delay1(300);LED=1;break;
case 0x21:PlayMusic(); break;
default:
break;
}
STH0=tab[k]/256;
STL0=tab[k]%256;
TR0=1;
P2=0x07;
while((P2&0x07)!=0x07)
P2=0x07;
TR0=0;
}
}
}
}
#include<absacc.h>
#include<stdio.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
uchar STH0; //定时器计数初值
uchar STL0;
uchar k,key;
sbit SPK=P3^7;
sbit LED=P3^6;
//音符与计数值对应表
void delay1(uint ms) //播放歌曲时实现节拍的延时函数
{
uchar t;
while(ms--) for(t=0;t<120;t++);
}
uint code tab[]={64580,64684,64777,
64898,64968,65030,
65110, 65058};
uchar code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,
212,212,106,126,159,169,190,119,119,126,159,142,159,0};
// 生日快乐歌节拍表,节拍决定每个音符的演奏长短
uchar code SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,
9,3,12,12,12,12,12,9,3,12,12,12,24,0};
void PlayMusic()
{
uint i=0,j,k;
while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
{ //播放各个音符,SONG_LONG 为拍子长度
for(j=0;j<SONG_LONG[i]*20;j++)
{
SPK=~SPK;
//SONG_TONE延时表决定了每个音符的频率
for(k=0;k<SONG_TONE[i]/3;k++);
}
delay1(10);
i++;
}
}
//键消抖延时函数
void delay(void)
{
uchar i;
for(i=300;i>0;i--);
}
//键扫描函数
uchar getkey(void)
{
uchar scancode,tmpcode;
if((P2&0x07)==0x07)
return(0);
else scancode=0xdf;
while((scancode&0x04)!=0)
{
P2=scancode; //输入行扫描码
if((P2&0x07)!=0x07) //本行有键按下
{
tmpcode=(P2&0x07)|0xf8;
return((~scancode)+(~tmpcode));
}
else scancode=(scancode>>1)|0x80;
}
}
//定时器0中断服务子程序
void time0_int(void) interrupt 1 using 0
{
TH0=STH0;
TL0=STL0;
SPK=~SPK;
}
void main(void)
{
IE=0X87;
TMOD=0x01;
ET0=1;
EA=1;
IT0=1;
while(1)
{
P2=0x07;
if((P2&0x07)!=0x07)
{
delay();
if((P2&0x07)!=0x07)
{
key=getkey();
switch(key)
{ case 0x09: k=0;LED=0;delay1(300);LED=1;break;
case 0x0a: k=1;LED=0;delay1(300);LED=1;break;
case 0x0c: k=2;LED=0;delay1(300);LED=1;break;
case 0x11: k=3;LED=0;delay1(300);LED=1;break;
case 0x12: k=4;LED=0;delay1(300);LED=1;break;
case 0x14: k=5;LED=0;delay1(300);LED=1;break;
case 0x22: k=6;LED=0;delay1(300);LED=1;break;
case 0x21:PlayMusic(); break;
default:
break;
}
STH0=tab[k]/256;
STL0=tab[k]%256;
TR0=1;
P2=0x07;
while((P2&0x07)!=0x07)
P2=0x07;
TR0=0;
}
}
}
}
展开全部
1、单片机可以产生方波,其基波频率与方波频率相同。谐波分量暂不考虑,可以近似这个效果。用无源蜂鸣片效果会好些。直接产生正弦波当然更好,需要高速MCU和DA、运放支持。
2、八个音的音高固定,把频率确定,如C大调12345671。得到8个周期值,考虑到方波取反,溢出周期减半,计算定时器的方波溢出8个初值数组。
3、通过按键读取输入键值,给定时器赋初值数组元素。定时器产生周期方波。
4、定时器中断后,取反P2^0。
2、八个音的音高固定,把频率确定,如C大调12345671。得到8个周期值,考虑到方波取反,溢出周期减半,计算定时器的方波溢出8个初值数组。
3、通过按键读取输入键值,给定时器赋初值数组元素。定时器产生周期方波。
4、定时器中断后,取反P2^0。
追问
原理我知道,但是不会编程啊?求程序
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询