从单片机基础到程序框架(全集 2019pdf版) - 第404页
} void Perip heralInit ial(void) { vGu8Beep TimerFlag=0 ; vGu16Bee pTimerCnt=B EEP_TIME; // “应用层”只需 赋值,一上电 ,蜂鸣 器发出 10 00ms 长度的声音 。 vGu8Beep TimerFlag=1 ; } //蜂鸣器发声 void BeepO pen(void) { P3_4=0; // 0 代表发声 } //蜂鸣器关闭 void …

void PeripheralInitial(void) ;
void BeepOpen(void); //蜂鸣器发声
void BeepClose(void); //蜂鸣器关闭
void VoiceScan(void); //蜂鸣器的驱动函数,放在定时中断里
sbit P3_4=P3^4; //控制蜂鸣器的 IO 口。0 代表发声,1 代表关闭。
volatile unsigned char vGu8BeepTimerFlag=0;
volatile unsigned int vGu16BeepTimerCnt=0; //控制蜂鸣器发声长度的计时器
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial(); //此函数内部有“应用层”的赋值操作,控制上电的声音长度。
while(1)
{
;
}
}
void T0_time() interrupt 1
{
VoiceScan(); //蜂鸣器的驱动函数
TH0=0xfc;
TL0=0x66;
}
void SystemInitial(void)
{
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
EA=1;
ET0=1;
TR0=1;
}
void Delay(unsigned long u32DelayTime)
{
for(;u32DelayTime>0;u32DelayTime--);

}
void PeripheralInitial(void)
{
vGu8BeepTimerFlag=0;
vGu16BeepTimerCnt=BEEP_TIME; //“应用层”只需赋值,一上电,蜂鸣器发出 1000ms 长度的声音。
vGu8BeepTimerFlag=1;
}
//蜂鸣器发声
void BeepOpen(void)
{
P3_4=0; //0 代表发声
}
//蜂鸣器关闭
void BeepClose(void)
{
P3_4=1; //1 代表关闭
}
//蜂鸣器的驱动函数,放在定时中断函数里每定时 1ms 扫描一次。
void VoiceScan(void)
{
//Su8Lock 的作用是避免 BeepOpen()被重复扫描影响效率,发声时只执行一次此函数即可。
//同时,也巧妙借用 else 结构,实现逻辑顺序分解成“先发声,下一次再开始定时”的两个步骤。
static unsigned char Su8Lock=0;
if(1==vGu8BeepTimerFlag&&vGu16BeepTimerCnt>0)
{
if(0==Su8Lock)
{
Su8Lock=1; //进入触发声音后就自锁起来
BeepOpen(); //发声,此处封装成函数,为了今后代码的移植性。
}
else //巧妙借用 else 结构,实现先发声,下一次中断再开始计时的逻辑顺序。比如,
{ //如果赋值 1,就能确保有 1ms 的计时发声。
vGu16BeepTimerCnt--; //定时器自减,控制蜂鸣器发声的时间长度
if(0==vGu16BeepTimerCnt)

{
Su8Lock=0; //关闭声音后,及时解锁,为下一次触发做准备
BeepClose(); //关闭声音,此处封装成函数,为了今后代码的移植性。
}
}
}
}