|
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int
sbit P30=P3^0;
uint t;
uint code tab1[]={ 0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71}; //顯示0-F
uint code tab2[] = { 64103,64260,64400,64524, //低音 4 5 6 7
64580,64684,64777,64820, //中音1 2 3 4
64898,64968,65030,65058, //中音 5 6 7 高音 1
65110,65157,65178,65217 }; //高音 2 3 4
void delay(int x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
/*************************************************************
* 函數(shù)功能 : 用掃描法讀 P1 外接 4×4 鍵盤
* 函數(shù)返回 : 按下鍵:返回0~15、如無(wú)鍵按下:返回0
**************************************************************/
uint Keyscan()
{
uint i,j,col,scancode;
scancode=0xfe;
for(i =0;i<4 ;i++)
{ P1=scancode; //循環(huán)四次,掃描四行
j=P1&0xf0;
if(j!=0xf0) //判斷列值高四位是否為1111,不為1111,說(shuō)明有鍵按下
{
if(j==0xe0)col=3; //如果列值高四位為1110,第3列有鍵按下
else if(j==0xd0)col=2; //如果列值高四位為1101,第2列有鍵按下
else if(j==0xb0)col=1; //如果列值高四位為1011,第1列有鍵按下
else if(j==0x70)col=0; //如果列值高四位為0111,第0列有鍵按下
return(4*i+col); //掃描次數(shù)即為行號(hào),通過(guò)計(jì)算得出鍵碼值
while(j!=0xf0) //判斷按鍵是否釋放
{
P1=scancode;
j=P1&0xf0;
}
P0=0x00; //按鍵釋放,數(shù)碼管不顯示
}
scancode=(scancode<<1)|0x01 ; //掃描碼左移1位,準(zhǔn)備下一行掃描
}
return 16; //沒(méi)有鍵按下就返回16 作為誤判動(dòng)作
}
void main()
{
uint key;
TMOD =0x01;
EA =1; //T0定時(shí)方式1
ET0 =1; //允許T0中斷
EX0 =1; //允許X0中斷
while(1)
{
TR0=0; //暫不發(fā)音
key=Keyscan(); //讀入按鍵
if(key!=16) //有鍵按下
{
tab1[0];
P2=0x01;
delay(10); //顯示鍵值、延時(shí)消抖
t=tab2[key]; //根據(jù)鍵值,取出定時(shí)半周期的初始值
P0 = tab1[key];
P2=0x01;
delay(10);
TR0=1; //啟動(dòng)定時(shí)器,發(fā)音
while(Keyscan()<16); //等待釋放
P30=1; //停止發(fā)音
}
else
{;}
}
}
void intx0() interrupt 1
{
TL0=t%256; //載入定時(shí)半周期的初始值
TH0=t/256;
P30=~P30; //發(fā)音
}
|
-
評(píng)分
-
查看全部評(píng)分
|