小白有地方不懂求大佬幫忙
#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++);
}
/*************************************************************
* 函數功能 : 用掃描法讀 P1 外接 4×4 鍵盤
* 函數返回 : 按下鍵:返回0~15、如無鍵按下:返回0
**************************************************************/
uint Keyscan()
{
uint i,j,col,scancode;
scancode=0xfe;
for(i =0;i<4 ;i++)
{ P1=scancode; //循環四次,掃描四行
j=P1&0xf0;
if(j!=0xf0) //判斷列值高四位是否為1111,不為1111,說明有鍵按下
{
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); //掃描次數即為行號,通過計算得出鍵碼值
while(j!=0xf0) //判斷按鍵是否釋放
{
P1=scancode;
j=P1&0xf0;
}
P0=0x00; //按鍵釋放,數碼管不顯示
}
scancode=(scancode<<1)|0x01 ; //掃描碼左移1位,準備下一行掃描
}
return 16; //沒有鍵按下就返回16 作為誤判動作
}
void main()
{
uint key;
TMOD =0x01;
EA =1; //T0定時方式1
ET0 =1; //允許T0中斷
EX0 =1; //允許X0中斷
while(1)
{
TR0=0; //暫不發音
key=Keyscan(); //讀入按鍵
if(key!=16) //有鍵按下
{
tab1[0];
P2=0x01;
delay(10); //顯示鍵值、延時消抖
t=tab2[key]; //根據鍵值,取出定時半周期的初始值
P0 = tab1[key];
P2=0x01;
delay(10);
TR0=1; //啟動定時器,發音
while(Keyscan()<16); //等待釋放
P30=1; //停止發音
}
else
{;}
}
}
void intx0() interrupt 1
{
TL0=t%256; //載入定時半周期的初始值
TH0=t/256;
P30=~P30; //發音
}
就是這里的這些代碼都是干什么用的啊(為什么要載入定時半周期的初始值?)(中斷的作用是什么啊)
{
tab1[0];
P2=0x01;
delay(10); //顯示鍵值、延時消抖
t=tab2[key]; //根據鍵值,取出定時半周期的初始值
P0 = tab1[key];
P2=0x01;
delay(10);
TR0=1; //啟動定時器,發音
while(Keyscan()<16); //等待釋放
P30=1; //停止發音
}
else
{;}
}
}
void intx0() interrupt 1
{
TL0=t%256; //載入定時半周期的初始值
TH0=t/256;
P30=~P30; //發音
}
|