}
}
TR0=0; p=0;
39 演奏音阶
/* 名称:演奏音阶
说明:本例使用定时器演奏一段音阶,播放由K1控制。 */
#include
#define uchar unsigned char #define uint unsigned int sbit K1=P1^0; sbit SPK=P3^4; uint i=0;
//音符索引
//14个音符放在方式2下的定时寄存器(TH0,TL0)
uchar code HI_LIST[]={0,226,229,232,233,236,238,240,241,242,244,245,246,247,248}; uchar code LO_LIST[]={0,4,13,10,20,3,8,6,2,23,5,26,1,4,3}; //定时器0中断函数 void T0_INT() interrupt 1 {
TL0=LO_LIST[i]; TH0=HI_LIST[i]; SPK=~SPK; }
//延时
void DelayMS(uint ms) { uchar t; while(ms--) for(t=0;t<120;t++); }
//主程序
void main() { TMOD=0x00;
//T0方式0
IE=0x82; SPK=0;
while(1) { while(K1==1); while(K1==0);
for(i=1;i<15;i++)
//未按键等待 //等待释放
41
}
}
{ }
TR0=1; TR0=0;
//播放一个音符 //播放延时
DelayMS(500); DelayMS(50);
40 按键控制定时器选播多段音乐
/* 名称:按键控制定时器选播多段音乐 */
#include
#define uchar unsigned char #define uint unsigned int sbit K1=P1^0; //播放和停止键
sbit SPK=P3^7; //蜂鸣器
uchar Song_Index=0,Tone_Index=0; //当前音乐段索引,音符索引 //数码管段码表
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //标准音符频率对应的延时表
uchar code HI_LIST[]={0,226,229,232,233,236,238,240,241,242,244,245,246,247,248}; uchar code LO_LIST[]={0,4,13,10,20,3,8,6,2,23,5,26,1,4,3}; //三段音乐的音符 uchar code Song[][50]= {
{1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,3,5,6,5,3,5,3,2,1,2,1,-1}, {3,3,3,4,5,5,5,5,6,5,3,5,3,2,1,5,6,53,3,2,1,1,-1},
{3,2,1,3,2,1,1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,3,5,3,2,1,3,2,1,1,-1} 说明:本例内置3段音乐,K1可启动停止音乐播放,K2用于选择音乐段。
};
//三段音乐的节拍 uchar code Len[][50]= {
{1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,-1}, {1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,2,2,-1},
{1,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,1,2,1,1,1,1,1,1,1,2,1,1,2,2,-1}
};
//外部中断0
void EX0_INT() interrupt 0 { TR0=0; //播放结束或者播放中途切换歌曲时停止播放
42
Song_Index=(Song_Index+1)%3; //跳到下一首的开头 Tone_Index=0;
P2=DSY_CODE[Song_Index];
//数码管显示当前音乐段号
}
//定时器0中断函数 void T0_INT() interrupt 1 { TL0=LO_LIST[Song[Song_Index][Tone_Index]]; TH0=HI_LIST[Song[Song_Index][Tone_Index]];
SPK=~SPK;
}
//延时
void DelayMS(uint ms) {
uchar t;
while(ms--) for(t=0;t<120;t++); }
//主程序 void main() { P2=0xc0; SPK=0;
TMOD=0x00; //T0方式0
IE=0x83;
IT0=1; IP=0x02; while(1) { while(K1==1); //未按键等待
while(K1==0); //等待释放 TR0=1; //开始播放 Tone_Index=0; //从第0个音符开始 //播放过程中按下K1可提前停止播放(K1=0)。
//若切换音乐段会触发外部中断,导致TR0=0,播放也会停止 while(Song[Song_Index][Tone_Index]!=-1&&K1==1&&TR0==1) { DelayMS(300*Len[Song_Index][Tone_Index]); //播放延时(节拍)
Tone_Index++;
//当前音乐段的下一音符索引
}
TR0=0;
//停止播放
while(K1==0);
//若提前停止播放,按键未释放时等待
}
}
41 定时器控制交通指示灯
43
/* 名称:定时器控制交通指示灯
说明:东西向绿灯亮5s后,黄灯闪烁,闪烁5次亮红灯, 红灯亮后,南北向由红灯变成绿灯,5s后南北向黄灯闪烁,
闪烁5次后亮红灯,东西向绿灯亮,如此往复。
*/
#include
sbit RED_A=P0^0; //东西向指示灯 sbit YELLOW_A=P0^1; sbit GREEN_A=P0^2;
sbit RED_B=P0^3; //南北向指示灯 sbit YELLOW_B=P0^4; sbit GREEN_B=P0^5;
//延时倍数,闪烁次数,操作类型变量
uchar Time_Count=0,Flash_Count=0,Operation_Type=1; //定时器0中断函数 void T0_INT() interrupt 1 {
TL0=-50000/256; TH0=-50000%6; switch(Operation_Type) {
case 1:
//东西向绿灯与南北向红灯亮5s
RED_A=0;YELLOW_A=0;GREEN_A=1; RED_B=1;YELLOW_B=0;GREEN_B=0;
if(++Time_Count!=100) return; //5s(100*50ms)切换 Time_Count=0; Operation_Type=2; break;
//东西向黄灯开始闪烁,绿灯关闭 if(++Time_Count!=8) return; Time_Count=0;
YELLOW_A=~YELLOW_A;GREEN_A=0; if(++Flash_Count!=10) return; //闪烁 Flash_Count=0;
Operation_Type=3; break;
//东西向红灯与南北向绿灯亮5s RED_A=1;YELLOW_A=0;GREEN_A=0;
RED_B=0;YELLOW_B=0;GREEN_B=1;
if(++Time_Count!=100) return; //5s(100*50ms)切换 Time_Count=0;
44
case 2:
case 3:
case 4:
Operation_Type=4; break;
//南北向黄灯开始闪烁,绿灯关闭 if(++Time_Count!=8) return;
Time_Count=0;
YELLOW_B=~YELLOW_B;GREEN_A=0; if(++Flash_Count!=10) return; //闪烁 Flash_Count=0; Operation_Type=1; break;
} }
//主程序
void main() { TMOD=0x01; IE=0x82; }
42 报警与旋转灯
TR0=1; while(1);
//T0方式1
/* 名称:报警与旋转灯 说明:定时器控制报警灯旋转显示,并发出仿真警报声。 */
#include
void DelayMS(uint ms) {
uchar i;
while(ms--) for(i=0;i<120;i++);
}
//INT0中断函数
void EX0_INT() interrupt 0 {
TR0=~TR0; //开启或停止两定时器,分别控制报警器的声音和LED旋转 TR1=~TR1;
45