从单片机基础到程序框架(全集 2019pdf版).pdf - 第384页
{ Su8Cnt=0; Su8Data=0x 01; //重新赋初值 ,继续下一次 循环移 动 } } 分析 总结: 这是 第 1 种 境界 的跑马 灯, 这种思 路虽 然实 现了跑 马灯 的效 果,但 是因 为“阻 塞延 时” ,整 个程序显得 僵硬机械,缺 乏多任务并行 的框架 。 【89.3 移位非阻塞。 】 移位非阻塞 , “移位 ” 用的是 C 语言的左移 或者右移语 句, “非阻 塞” 用的是定时 中断衍生 出来的软 件定 …

{
LedTask();
}
}
void T0_time() interrupt 1
{
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)
{
}
//跑马灯的任务程序
void LedTask(void)
{
static unsigned char Su8Data=0x01; //加 static 修饰的局部变量,每次进来都会保留上一次值。
static unsigned char Su8Cnt=0; //加 static 修饰的局部变量,每次进来都会保留上一次值。
P0=Su8Data; //Su8Data 的 8 个位代表 8 个 LED 的状态,0 为点亮,1 为熄灭。
Delay(10000) ; //阻塞延时
Su8Data=Su8Data<<1; //左移一位
Su8Cnt++; //计数器累加 1
if(Su8Cnt>=8) //移位大于等于 8 次后,重新赋初值

{
Su8Cnt=0;
Su8Data=0x01; //重新赋初值,继续下一次循环移动
}
}
分析总结:这是第 1 种境界的跑马灯,这种思路虽然实现了跑马灯的效果,但是因为“阻塞延时”,整
个程序显得僵硬机械,缺乏多任务并行的框架。
【89.3 移位非阻塞。】
移位非阻塞,“移位”用的是 C 语言的左移或者右移语句,“非阻塞”用的是定时中断衍生出来的软件定
时器。代码如下:
#include "REG52.H"
void T0_time();
void SystemInitial(void) ;
void Delay(unsigned long u32DelayTime) ;
void PeripheralInitial(void) ;
void LedTask(void);
#define BLINK_TIME_1 1000
volatile unsigned char vGu8TimeFlag_1=0;
volatile unsigned int vGu16TimeCnt_1=0;
void main()
{
SystemInitial();
Delay(10000);
PeripheralInitial();
while(1)
{
LedTask();
}
}
void T0_time() interrupt 1
{
if(1==vGu8TimeFlag_1&&vGu16TimeCnt_1>0) //软件定时器
{
vGu16TimeCnt_1--;

}
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)
{
}
//跑马灯的任务程序
void LedTask(void)
{
static unsigned char Su8Data=0x01; //加 static 修饰的局部变量,每次进来都会保留上一次值。
static unsigned char Su8Cnt=0; //加 static 修饰的局部变量,每次进来都会保留上一次值。
if(0==vGu16TimeCnt_1) //时间到
{
vGu8TimeFlag_1=0;
vGu16TimeCnt_1=BLINK_TIME_1; //重装定时的时间
vGu8TimeFlag_1=1;
P0=Su8Data; //Su8Data 的 8 个位代表 8 个 LED 的状态,0 为点亮,1 为熄灭。
Su8Data=Su8Data<<1; //左移一位
Su8Cnt++; //计数器累加 1
if(Su8Cnt>=8) //移位大于等于 8 次后,重新赋初值
{