#include <reg52.h>
#define FOSC 12000000
#define T0FENPING 12
unsigned int code JINJIEFREQ[] =
{
262,294,330,349,392,440,494,
523,587,659,699,784,880,988,
1046,1175,1319,1391,1568,1760,1976
};
bit RunFlag = 0;
sbit Beep = P3^0;
unsigned char STH0,STL0,num1,num,temp,m,jishu;
unsigned char keyscan();
void Delay10ms(unsigned int c) ;
void delay(unsigned int c);
void T0_ISR(void) interrupt 1
{
if(1 == RunFlag) //--- 在音阶播放标志为1情况下 ---
{
TH0 = STH0; //--- 重新装初值 ---
TL0 = STL0;
Beep = ~Beep; //--- P5.5引脚上的电平翻转 ---
}
}
void main(void)
{
unsigned int i;
unsigned char j;
// AUXR |= 0x80; //--- 使能T0的计数器时钟分频值为1 ---
TMOD = 0x01; //--- 配置T0为定时模式,工作于方式2 ---
ET0 = 1; //--- 使能T0中断 ---
TR0 = 1;
EA = 1; //--- CPU开中断 ---
while(1)
{
num1 = keyscan();
Beep = 1;
while(m)
{
m = 0;
STH0 = (65536 - FOSC / T0FENPING / 2 / JINJIEFREQ[num1]) / 256;
STL0 = (65536 - FOSC / T0FENPING / 2 / JINJIEFREQ[num1]) % 256;
TH0 = STH0; //--- 装入TH0,TL0的计数寄存器 ---
TL0 = STL0;
RunFlag = 1;
delay(500);
}
TH0 = 0;
}
}
unsigned char keyscan() //定义子函数 键盘扫描
{
P0=0xfe; //第一行按键 1111 1110
temp=P0;//读取P2口
temp=temp&0xf0; //1111 0000 即 1111 1110 & 1111 0000 =1111 0000
while(temp!=0xf0) // 如果不等于 说明有键按下
{
Delay10ms(1);
temp=P0;//再次读一下P2口的值 1110 1110
temp=temp&0xf0; // 1110 1110 &1111 0000= 1110 0000
while(temp!=0xf0) //确认是否按下
{
temp=P0; //P2口的值读回来 1110 1110
switch(temp) //可以看出是哪一列 temp和case后的 0xee 相比 如果相等 执行 num
{
case 0xee:num=0,m=1;//按下第一行 第一个键 是 1110 1110 即ee
break;//跳出这个语句
case 0xde:num=1,m=1; //1101 1110 de
break;
case 0xbe:num=2,m=1; //1011 1110 be
break;
case 0x7e:num=3,m=1; //0111 1110 7e
break;
}
while(temp!=0xf0)//松手检测 按键 不松手 不等于0成立
{
temp=P0;
temp=temp&0xf0; //1110 1110& 1111 0000= 1110 0000
}
// P0=table[num1-1];
}
}
P0=0xfd; //第二行按键 1111 1101
temp=P0;//读取P2口
temp=temp&0xf0;
while(temp!=0xf0) //看是否有键按下
{
Delay10ms(1);
temp=P0;//再次读一下P2口的值
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P0; //P2口的值读回来 1111 1101
switch(temp) //temp和case后的 0xed 相比 如果相等 执行 num
{
case 0xed:num=4,m=1;
break;//跳出这个语句
case 0xdd:num=5,m=1;
break;
case 0xbd:num=6,m=1;
break;
case 0x7d:num=7,m=1;
break;
}
while(temp!=0xf0)//松手检测 按键 不松手 不等于0成立
{
temp=P0;
temp=temp&0xf0;
} // P0=table[num1-1];
}
}
P0=0xfb; //第三行按键 1111 1011
temp=P0;//读取P2口
temp=temp&0xf0;
while(temp!=0xf0) //看是否有键按下
{
Delay10ms(1);
temp=P0;//再次读一下P2口的值
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P0; //P2口的值读回来 1111 1011
switch(temp) //temp和case后的 0xeb 相比 如果相等 执行 num
{
case 0xeb:num=8,m=1;
break;//跳出这个语句
case 0xdb:num=9,m=1;
break;
case 0xbb:num=10,m=1;
break;
case 0x7b:num=11,m=1;
break;
}
while(temp!=0xf0)//松手检测 按键 不松手 不等于0成立
{
temp=P0;
temp=temp&0xf0;
} // P0=table[num1-1];
}
}
P0=0xf7; //第四行按键 1111 0111
temp=P0;//读取P2口
temp=temp&0xf0;
while(temp!=0xf0) //看是否有键按下
{
Delay10ms(1);
temp=P0;//再次读一下P2口的值
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P0; //P2口的值读回来 1111 0111
switch(temp) //temp和case后的 0xe7 相比 如果相等 执行 num
{
case 0xe7:num=12,m=1;
break;
case 0xd7:num=13,m=1;
break;
case 0xb7:num=14,m=1;
break;
case 0x77:num=15,m=1;
break;
}
while(temp!=0xf0)//松手检测 按键 不松手 不等于0成立
{
temp=P0;
temp=temp&0xf0;
} // P0=table[num1-1];
}
}
return num;
}
void Delay10ms(unsigned int c) //延时 定义
{
unsigned char a,b;
//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--);
}
}
}
void delay (unsigned int c)
{
unsigned int i,j;
for(i=c;i>0;i--)
for (j=110;j>0;j--);
}
|