从单片机基础到程序框架(全集 2019pdf版).pdf - 第370页

#include " REG52.H" #define BLIN K_TIME 500 //时间是 500ms sbit P0_0= P0^0; volatile u nsigned c har vGu8Time Flag=0; //互斥 量变量标志 volatile u nsigned i nt vGu16TimeCn t=0; //计时 器变量 unsigned c har Gu8St ep=0; //switc…

100%1 / 836
vGu8TimeFlag=1; //互斥 vGu8TimeFlag 的“解锁”。同时也起到“启动计时器”的开关作用
while(1) //主循环
{
if(0==vGu16TimeCnt) //时间变量为 0 则表示时间到了
{
...在这里执行具体的功能代码
}
}
}
void T0_time() interrupt 1 //每 1ms 中断一次的定时中断函数
{
if(1==vGu8TimeFlag&&vGu16TimeCnt>0) //判断 vGu8TimeFlag 是否等于 1,就是互斥量的判断。
{
vGu16TimeCnt--; //“自减一”的操
}
}
分析:上述代码中,vGu8TimeFlag 是一箭双雕,既起到互斥量的作用,也起到了计数器 vGu16TimeCnt
开始计时的启动开关作用
【86.3 练习例程。
现在根据上述程序框架,编写一个 LED 灯闪烁的程序。
86.3.1 灌入式驱动 8 LED
#include "REG52.H"
#define BLINK_TIME 500 //时间是 500ms
sbit P0_0=P0^0;
volatile unsigned char vGu8TimeFlag=0; //互斥量变量标志
volatile unsigned int vGu16TimeCnt=0; //计时器变量
unsigned char Gu8Step=0; //switch 的切换步骤
void main()
{
TMOD=0x01; //设置定时器 0 为工作方式 1
TH0=0xfc; //产生 1ms 中断的 TH0 初始
TL0=0x66; //产生 1ms 中断的 TL0 初始
EA=1; //开总中断
ET0=1; //允许定时 0 的中断
TR0=1; //启动定时 0 的中断
while(1) //主循环
{
switch(Gu8Step)
{
case 0:
if(0==vGu16TimeCnt) //时间
{
P0_0=0; //LED 灯亮
vGu8TimeFlag=0; //互斥量“加锁”
vGu16TimeCnt=BLINK_TIME; //计时器的写操作。设定计时的长
vGu8TimeFlag=1; //互斥量“解锁”,同时蕴含了计时器“启动”的动作
Gu8Step=1; //切换到 case 1 个步骤
}
break;
case 1:
if(0==vGu16TimeCnt) //时间
{
P0_0=1; //LED 灯灭。
vGu8TimeFlag=0; //互斥量“加锁”
vGu16TimeCnt=BLINK_TIME; //计时器的写操作。设定计时的长
vGu8TimeFlag=1; //互斥量“解锁”,同时蕴含了计时器“启动”的动作
Gu8Step=0; //切换到 case 0 个步骤,依次循环
}
break;
}
}
}
void T0_time() interrupt 1 //定时器 0 的中断函数,每 1ms 单片机自动执行一次此函数
{
if(1==vGu8TimeFlag&&vGu16TimeCnt>0) //判断 vGu8TimeFlag 是否等于 1,就是互斥量的判断
{
vGu16TimeCnt--; //“自减一”的操作
}
TH0=0xfc; //重装初值,不能忘
TL0=0x66; //重装初值,不能忘
}
【86.4 解决闪烁出现不规则“非对称感”现象的方法。
上述例子,实验现象应该 LED 烁很有规则的每 1s 闪烁一次,但是也有一部分初学者可能会遇到闪
烁出现不规“非对称感”的现象,这个问题的解决办法如下: keil2 project 下拉菜单下选择 Options
for Target 选项,弹出的窗口中,切换 Target 选项, Memory Model 选项中选 small:variables in Data。
86.4.1 设置窗口