/*说明:此程序是用矩阵按键和音乐实验组合而成的,先是写出矩阵键盘程序,得出键值。然后通过判断键值而分配各种音符,从而得到电子琴效果!硬件连接!
硬键连接:P1口接矩阵键盘,P3.5接蜂鸣器引脚*/
#include <reg52.h>//头文件
#define uint unsigned int//宏定义
#define uchar unsigned char//宏定义
void delay(uchar);//延时子函数声明
void bbtt (uchar);//声音处理子函数声明
void pan();//按键子函数声明
uint code table[]={
0xfd,0x12,0xfd,0x80, 0xfd,0xc6, 0xfe,0x07,0xfe,0x25,0xfe,0x57,
0xfe,0x84,0xfe,0x98,0xfe,0xc0,0xfe,0xe3,0xff,0x01, 0xff,0x10, 0xff,0x29,0xff,0x42
};/*音符代码 低音3,低音5,低音6,低音7,中音1,中音2,中音3,中音4,中音5,中音6,
中音7,高音1,高音2,高音3,基中一个音用两个数表示。*/
sbit bbt=P3^5;//定义蜂鸣器引脚为P3.5脚。
uchar num,lui,a,temp,num1,num2,numm,aa,bb;//定义行变量
void main()//主程序开始
{
TMOD=01;//设置定时器工作在方式0下
IE=0X82;//开总中断与中断允许
num=17;//定义初值,开机使它不亮
while(1)
{
pan();//按键识别子函数
TR0=0;//将定时器关掉
/
bbt=1;//将蜂鸣器关掉
//
/*将各按键得出键值码,也就是让每个键得到相应的音符*/
if(num!=17)//判断num是否不等于17,不等就执行以下语句,否则跳过
{
switch(num)//执行开关语句
{
case 0://0x00与num值是否相等?
{
TR0=1;//打开定时器
bbtt (0);//调用声音处理子函数,并赋值0
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回开关语句
/////////////////////////////////////////////////////////////////
case 1://0x01与num值是否相等?
{
TR0=1;//打开定时器
bbtt (2);//调用声音处理子函数,并赋值2
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回
//////////////////////////////////////////////////////////////////
case 2://0x08与num值是否相等?
{
TR0=1;//打开定时器
bbtt (4); //调用声音处理子函数,并赋值4
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回
//////////////////////////////////////////////////////////////////
case 3://0x00与num值是否相等?
{
TR0=1;//打开定时器
bbtt (6);//调用声音处理子函数,并赋值6
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回继续判断是否有键按下
/////////////////////////////////////////////////////////////////
case 4://0x04与num值是否相等?
{
TR0=1;//打开定时器
bbtt (8);//调用声音处理子函数,并赋值8
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回
//////////////////////////////////////////////////////////////////
case 5://0x08与num值是否相等?
{
TR0=1;//打开定时器
bbtt (10);//调用声音处理子函数,并赋值10
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回
case 6://0x00与num值是否相等?
{
TR0=1;//打开定时器
bbtt (12);//调用声音处理子函数,并赋值12
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回继续判断是否有键按下
/////////////////////////////////////////////////////////////////
case 7://0x04与num值是否相等?
{
TR0=1;//打开定时器
bbtt (14);//调用声音处理子函数,并赋值14
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回
case 8://0x08与num值是否相等?
{
TR0=1;//打开定时器
bbtt (16);//调用声音处理子函数,并赋值16
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回
//////////////////////////////////////////////////////////////////
case 9://0x00与num值是否相等?
{
TR0=1;//打开定时器
bbtt (18);//调用声音处理子函数,并赋值18
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回继续判断是否有键按下
/////////////////////////////////////////////////////////////////
case 10://0x04与num值是否相等?
{
TR0=1;//打开定时器
bbtt (20);//调用声音处理子函数,并赋值20
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回
//////////////////////////////////////////////////////////////////
case 11://0x08与num值是否相等?
{
TR0=1;//打开定时器
bbtt (22);//调用声音处理子函数,并赋值22
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回
case 12://0x00与num值是否相等?
{
TR0=1;//打开定时器
bbtt (24);//调用声音处理子函数,并赋值24
num=17;// 将num值装回,使按键按下时只响一声
}
break;//返回继续判断是否有键按下
/////////////////////////////////////////////////////////////////
case 13://0x04与num值是否相等?
{
TR0=1;//打开定时器
bbtt (26); //调用声音处理子函数,并赋值26
num=17; // 将num值装回,使按键按下时只响一声
}
break;//返回
}
}
}
}
/*矩阵键盘扫描程序*/
void pan()
{
///////////////////////////////////扫第一行
P1=0xfe;//先扫第一行
temp=P1;//将它值给temp
temp=temp&0xf0;//与门比较
if(temp!=0xf0)//如果它不等于0xf0,就执行括号语句
{
delay(100);//延时
temp=P1;//再赋值
temp=temp&0xf0;//再与门比较
if(temp!=0xf0)//再判断是否为不等于0xf0?如果确实不等则说明有键按下
{
temp=P1;//将值重新给temp,以便下次再判断!否则找不到合适值
switch(temp)//判断出了第一行有键按下了,还要判断具体哪个键
{
case 0xee:num=0;//0xee和temp比较,如果相等就将它编码定义为0
break;//确定了就跳出switch语句
case 0xde:num=1;//0xde和temp比较,如果相等就将它编码定义为1
break;//确定了就跳出switch语句
case 0xbe:num=2;//0xbe和temp比较,如果相等就将它编码定义为2
break;//确定了就跳出switch语句
case 0x7e:num=3;//0x7e和temp比较,如果相等就将它编码定义为3
break;//确定了就跳出switch语句
}
if(temp!=0xf0)//按键识放判断,如果不等于0xf0就一直执行括号语句
{
temp=P1;//重新赋值
temp=temp&0xf0;//重新与门
}
}
}
///////////////////////////////////扫第二行
P1=0xfd;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(100);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:num=4;
break;
case 0xdd:num=5;
break;
case 0xbd:num=6;
break;
case 0x7d:num=7;
break;
}
if(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
/////////////////////////////////////扫第三行
P1=0xfb;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(100);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:num=8;
break;
case 0xdb:num=9;
break;
case 0xbb:num=10;
break;
case 0x7b:num=11;
break;
}
if(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
////////////////////////////////////////扫第四行
P1=0xf7;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(100);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num=12;
break;
case 0xd7:num=13;
break;
case 0xb7:num=14;
break;
case 0x77:num=15;
break;
}
if(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
}
void delay(uchar z)//延时函数
{
uchar x,y;
for(x=100;x>0;x--)
for(y=z;y>0;y--);
}
/*扫描得到音乐代码,赋值给定时器*/
void bbtt (uchar aa)
{
numm=table[aa];//得到音乐码高位
aa++;//将计数器加1,以便取下一个代码
num1=table[aa];//得到音乐码低位
TH0=numm;//将高位赋值
TL0=num1;//将低位赋值
}
/*中断服务子程序*/
void zhong() interrupt 1
{
TH0=numm;//将高位赋值
TL0=num1;//将低位赋值
bbt=~bbt;//将蜂鸣器取反发声
}
|