从单片机基础到程序框架(全集 2019pdf版).pdf - 第401页
if(0==vGu1 6TimeCnt_ 2) //时间到 { vGu8Time Flag_2=0; vGu16Tim eCnt_2=BLIN K_TIME_2; //重装 定时的时间 vGu8Time Flag_2=1; P1_4=0; P1_5=0; P1_6=1; //第 2 个灯 熄灭 P3_3=0; Su8Step= 3; //切换到下一 个步骤,精髓 语句! } break; case 3: if(0==vGu1 6Time…

疑点讲解(1):
这里第 2 路跑马灯的“Su8Step”与第 1 路跑马灯的“Su8Step”虽然同名,但是,因为它们是静态的局
部变量,在两个不同的函数内部,是两个不同的变量,这两个变量所分配的 RAM 内存地址是不一样的,因此,
它们虽然同名,但是不矛盾不冲突。
*/
static unsigned char Su8Step=0; //加 static 修饰的局部变量,每次进来都会保留上一次值。
switch(Su8Step)
{
case 0:
if(0==vGu16TimeCnt_2) //时间到
{
vGu8TimeFlag_2=0;
vGu16TimeCnt_2=BLINK_TIME_2; //重装定时的时间
vGu8TimeFlag_2=1;
P1_4=1; //第 0 个灯熄灭
P1_5=0;
P1_6=0;
P3_3=0;
Su8Step=1; //切换到下一个步骤,精髓语句!
}
break;
case 1:
if(0==vGu16TimeCnt_2) //时间到
{
vGu8TimeFlag_2=0;
vGu16TimeCnt_2=BLINK_TIME_2; //重装定时的时间
vGu8TimeFlag_2=1;
P1_4=0;
P1_5=1; //第 1 个灯熄灭
P1_6=0;
P3_3=0;
Su8Step=2; //切换到下一个步骤,精髓语句!
}
break;
case 2:

if(0==vGu16TimeCnt_2) //时间到
{
vGu8TimeFlag_2=0;
vGu16TimeCnt_2=BLINK_TIME_2; //重装定时的时间
vGu8TimeFlag_2=1;
P1_4=0;
P1_5=0;
P1_6=1; //第 2 个灯熄灭
P3_3=0;
Su8Step=3; //切换到下一个步骤,精髓语句!
}
break;
case 3:
if(0==vGu16TimeCnt_2) //时间到
{
vGu8TimeFlag_2=0;
vGu16TimeCnt_2=BLINK_TIME_2; //重装定时的时间
vGu8TimeFlag_2=1;
P1_4=0;
P1_5=0;
P1_6=0;
P3_3=1; //第 3 个灯熄灭
Su8Step=0; //返回到第 0 个步骤重新开始往下走,精髓语句!
}
break;
}
}

第九十一节: 蜂鸣器的“非阻塞”驱动。
【91.1 蜂鸣器的硬件电路简介。】
上图 91.1.1 PNP 三极管驱动有源蜂鸣器
蜂鸣器有两种,一种是有源蜂鸣器,一种是无源蜂鸣器。有源蜂鸣器的驱动最简单,只要通电就一直响,
断电就停,跟驱动 LED 灯一样。无源蜂鸣器则不一样,无源蜂鸣器一直断电不响,奇怪的是一直通电也不响,
只有“通,关,通,关...”反复通电关电的状态,才会持续发生稳定的声音,此方式称为脉冲驱动方式,
或者 PWM 驱动方式。本教程用的是有源蜂鸣器。
蜂鸣器的驱动电路也有两种常用的方式,一种是 NPN 三极管驱动,一种是 PNP 三极管驱动。NPN 三极管
驱动电路,单片机输出“1”(高电平)蜂鸣器导通,输出“0”(低电平)蜂鸣器关闭。而 PNP 三极管驱动电
路恰恰相反,单片机输出“0”(低电平)蜂鸣器导通,输出“1”(高电平)蜂鸣器关闭。本教程所用的是 PNP
三极管驱动电路,如上图。
【91.2 “非阻塞”驱动程序。】
“驱动层”是相对“应用层”而言。“应用层”发号施令,“驱动层”负责执行。一个好的“驱动层”必
须给“应用层”提供快捷便利的调用接口,此接口可以是函数或者全局变量。本节驱动蜂鸣器所用的是全局
变 量 vGu16BeepTimerCnt 和 vGu8BeepTimerFlag 。“ 应 用 层 ” 只 需 给 vGu16BeepTimerCnt 赋 值 , 给
vGu8BeepTimerFlag 置 1,就可以控制蜂鸣器发声,赋值越大,发声越长,500 代表发声 500ms,1000 代表发
声 1000ms,具体细节实现,则由“驱动层”的驱动函数负责执行,驱动函数放在定时中断函数里定时扫描。
为什么不把驱动函数放到 main 函数的循环里去?因为放在定时中断里,能保证蜂鸣器的声音长度是一致的,
如果放在 main 循环里,声音的长度有可能在某些项目中受到某些必须一气呵成的任务干扰,得不到及时响
应,影响声音长度的一致性。下面代码实现的功能是,单片机只要一上电,蜂鸣器就发出一次 1000ms 长度
的“嘀”声音。
#include "REG52.H"
#define BEEP_TIME 1000 //控制蜂鸣器发声的长度,此处是 1000ms
void T0_time();
void SystemInitial(void) ;
void Delay(unsigned long u32DelayTime) ;