相关代码:
P0 = 0xff;
Line = 1; Mask = 0x01; for(i=0;i<4;i++) { Col = 0; P0 = ~Mask;
ScanCode = P0 & 0xf0;
if(ScanCode!=0xf0) delay(); ScanCode = P0 & 0xf0; switch(ScanCode) {
case 0xe0:Col = 1;break; case 0xd0:Col = 2;break; case 0xb0:Col = 3;break; case 0x70:Col = 4;break; default:Col = 0;break; } if(Col>0) { num = (Line-1)*4+Col; if(SAVE==0) //保存 ,灯亮 {
save[a]=num; a++; } if(num==0) {
TR0=0;
SPK=1; //在未按键时,防止长期高电平损坏喇叭 } else {
P1 = CharCode[num-1]; High=tab[num-1][0]; Low =tab[num-1][1]; TR0=1; while(1) {
ScanCode = P0 & 0xf0; if(ScanCode == 0xf0) {
}
} } }
Mask <<=1; Line ++;
TR0 = 0; SPK=1; break; }
5.2键盘接口必须具有的4个基本功能
(1)去抖动:每个按键在按下或松开时,都会产生短时间的抖动。抖动的持续时间与键的质量相关,一般为5—20mm。所谓抖动是指在识别被按键是必须避开抖动状态,只有处在稳定接通或稳定断开状态才能保证识别正确无误。
(2)被按键识别:如何识别被按键是接口解决的主要问题,一般可通过软硬结合的方法完成。
(3)键码产生:为了从键的行列坐标编码得到反映键功能的键码,一般在内存区中建立一个键盘编码表,通过查表获得被按键的键码。
如下为键盘编码表:
unsigned char code tab[][2]= {
0x00,0x00, 0xf8,0x8c, 0xf9,0x5b, 0xfa,0x15, 0xfa,0x67, 0xfb,0x04, 0xfb,0x90, 0xfc,0x0c, 0xfc,0x44, 0xfc,0xac, 0xfd,0x09, 0xfd,0x34, 0xfd,0x82, 0xfd,0xc8, 0xfe,0x06, 0xfe,0x22, 0xfe,0x56, 0xfe,0x85,
0xfe,0x9a, 0xfe,0xc1, 0xfe,0xe4, 0xff,0x03 };
这是个二维数组,第一列是高位(THx),第二列是地位(TLx),一共有16行,第一行对应休止符。
用AT89C51的并行口P0接4×4矩阵键盘,以P0.0-P0.3作输入线,以P0.4-P0.7作输出线;
(4)在数码管上显示每个按键的“0-F”序号。 5.3数码管的相关代码
unsigned char code CharCode[]= {
0xc0, 0xf9, 0xa4,0xb0,0x99, 0x92,0x82,0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6,0xa1,0x86,0x8e };
5.4 C调各音符频率的相关代码
将数值转换为16进制的数,分成高八位和低八位,我们要为这个音符建立一个表格,单片机通过查表的方式来获得相应的数据。
unsigned char code tab[][2]= {
0x00,0x00, 0xf8,0x8c, 0xf9,0x5b, 0xfa,0x15, 0xfa,0x67, 0xfb,0x04, 0xfb,0x90, 0xfc,0x0c, 0xfc,0x44, 0xfc,0xac, 0xfd,0x09, 0xfd,0x34, 0xfd,0x82, 0xfd,0xc8, 0xfe,0x06, 0xfe,0x22,
0xfe,0x56, 0xfe,0x85, 0xfe,0x9a, 0xfe,0xc1, 0xfe,0xe4, 0xff,0x03 };
5.5 放歌子程序
放歌子程序设计类似于音乐播放,将每个音调循环播放出来。 if(MODE==1) //播放模式 ,灯不亮 {
if(SAVE==1) //保存灯不亮,播放内置音乐 {
SPK = 1;
//P1 = CharCode[Song[Tone_Index]]; dis = Song[Tone_Index];
High = tab[Song[Tone_Index]][0]; Low = tab[Song[Tone_Index]][1]; TR1 = 1;
delay1((6000*Pai[Tone_Index]));//取音节 TR1 = 0; SPK=1;
//if(((Tone_Index+1)%7)==0) delay1(1000); //else delay1(400); Tone_Index++;
if(Tone_Index==sizeof(Song)) Tone_Index =0; }
if(SAVE==0) //保存灯亮,播放录制的音乐 {