【Proteus仿真】多路非阻塞延时流水灯演示

【Proteus仿真】多路非阻塞延时流水灯演示


  • 🌻Proteus仿真演示
    在这里插入图片描述

🌼功能说明

📜51单片机利用定时器轮询设置2路不同长度的延时时间,跑流水灯。

📓实现方法

📑利用定时器中断,创建一个以1毫秒为时基的定时器中断函数。在需要不同时间的定时长度时,就设置一个定时的标量,当使能这个被定义的标量后,定时器每隔1毫秒就进入中断服务函数里面查询并累加计数,当累计计数达到标量值时就将对应的标量标志位置1,然后只要在主循环中查询该标量标志位是否值1从而实现非阻塞定时的功能。
  • ✅定时器中断服务函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void time0\_isr() interrupt  1 using  0
{
TR0 = 0 ;
if(time_enable)//计数器使能
{
cnt --;
if(!cnt)time_flag = 1;//计数时间到
}
if(time_enable2)//计数器使能
{
cnt2 --;
if(!cnt2)time_flag2 = 1;//计数时间到
}
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TR0 = 1;

}

✨当然也可以直接在定时器中断服务函数里面直接进行标志位查询,以减少定义的变量多,但是这样的运算会降低精度。
1
2
3
4
5
6
7
8
9
10
11
12
void time0\_isr() interrupt  1 using  0
{
TR0 = 0 ;
cnt++;
if(cnt%20000==0) flag1=1;
if(cnt%500==0) flag2=1;
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TR0 = 1;

}

📝主函数代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "time.h"

#define led\_shine\_time 2000
#define led\_shine\_time2 500

void main()
{
unsigned char temp = 0x80;
unsigned char temp2 = 0x01;
unsigned char i,j;
cnt = led_shine_time;
cnt2 = led_shine_time2;
time_enable = 1;//使能1路定时器
time_enable2 = 1;//使能2路定时器
Timer0Init();
while(1)
{
if(time_flag)//查询定时器计数是否达到设定值
{
time_flag = 0;
P1 = ~(temp>>i);
cnt = led_shine_time;//重新装载
i++;
i %=8;
}
if(time_flag2)//查询定时器计数是否达到设定值
{
time_flag2 = 0;
P2 = ~(temp>>j);
cnt2 = led_shine_time2;//重新装载
j++;
j %=8;
}
}
}


📚程序源码和仿真资源

1
2
3
链接:https://pan.baidu.com/s/19mcG9hdqiuo3FciJAMgnCg 
提取码:it5g