• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

【讨论】定时器的一个程序设计问题探讨

在做一项关于定时器的设计,要求:门口有人(红外探测输出高电平),LCD点亮显示欢迎词;若门口人站那超过2分钟,LCD显示请离开,并蜂鸣器报警。人离开后,LCD待机,待检测到有人,如此循环。大家有什么好方法可以说一说。

 

全部回复(5)
正序查看
倒序查看
001a
LV.3
2
2014-02-08 10:54

下面是本人写的程序,但功能不能实现。

sw1为红外传感器,高电平说明有人;

lcd()为欢迎词程序;

lcd1()为警告词程序;

lcd_init()为LCD初始化程序;

问题:

1.sw1==1时(有人),显示欢迎词,同时定时器开启;此时我把sw1==0(没人),这时定时器应该停止,LCD待机。但我写的这个程序,一直亮欢迎词,按 下sw1==0后不会立即初始化,直到定时器2分钟定完过后才初始化。正确的应该是定时中若sw1==0,LCD立即就能初始化的效果。

2.2分钟结束后,警告词只亮一次,然后又就跳到欢迎词。正确的应该是警告词一直显示,直到人走后(sw1==0),才待机,检测到人,显示欢迎词再如 此循环。

以下为自己写的程序(一些程序省篇幅就不贴出来了)

void Time0_init()

{

TMOD = 0x01;//定时器T0工作在方式1,定时时间60ms=0.06s

TH0 = 0x15;//高8位初值

TL0 = 0xA0;//低8位初值

EA = 1;//开总中断

ET0 = 1;//开定时器T0中断

TR0=1;//启动定时器

}

void main()

{

while(1)

{

a=0;//变量a清零

if(sw1==1)

{

Time0_init();

lcd();

if(sw1==0)

{

lcd_init();

}

}

while(2000-a !=0);//等待延时2000x0.06=120s=2min

TR0=0;//关闭定时器

while(sw1==1)

{

lcd1();

}

}

}

void Time0() interrupt 1//中断服务程序

{

TH0 = 0x15;//重装定时器高8位初值

TL0 = 0xA0;//重装定时器低8位初值

a++;//变量a加1

}

0
回复
一木01
LV.3
3
2014-02-08 11:03
@001a
下面是本人写的程序,但功能不能实现。sw1为红外传感器,高电平说明有人;lcd()为欢迎词程序;lcd1()为警告词程序;lcd_init()为LCD初始化程序;问题:1.sw1==1时(有人),显示欢迎词,同时定时器开启;此时我把sw1==0(没人),这时定时器应该停止,LCD待机。但我写的这个程序,一直亮欢迎词,按下sw1==0后不会立即初始化,直到定时器2分钟定完过后才初始化。正确的应该是定时中若sw1==0,LCD立即就能初始化的效果。2.2分钟结束后,警告词只亮一次,然后又就跳到欢迎词。正确的应该是警告词一直显示,直到人走后(sw1==0),才待机,检测到人,显示欢迎词再如此循环。以下为自己写的程序(一些程序省篇幅就不贴出来了)voidTime0_init(){TMOD=0x01;//定时器T0工作在方式1,定时时间60ms=0.06sTH0=0x15;//高8位初值TL0=0xA0;//低8位初值EA=1;//开总中断ET0=1;//开定时器T0中断TR0=1;//启动定时器}voidmain(){while(1){a=0;//变量a清零if(sw1==1){Time0_init();lcd();if(sw1==0){lcd_init();}}while(2000-a!=0);//等待延时2000x0.06=120s=2minTR0=0;//关闭定时器while(sw1==1){lcd1();}}}voidTime0()interrupt1//中断服务程序{TH0=0x15;//重装定时器高8位初值TL0=0xA0;//重装定时器低8位初值a++;//变量a加1}

你这没有响应的地方啊

你直接放到定时器中断服务函数里面。那个 a变量,不做其他用的话,可以在服务函数里定义,并修饰成static类型的。用if判断a的值是不是到2000了。

if(2000 == a)

{

a = 0;

//到这里就表示已经2min了。可以定义个全局变量标识比如g_2min_flag,在这更改它的值。或者直接用这个a变量,定时到了就把最高位置1. a |= 0x8000; 然后main程序判断a的最高位是不是1就行了。

}

不能把等待的循环放在main里呐

 

0
回复
2014-02-08 14:47
@001a
下面是本人写的程序,但功能不能实现。sw1为红外传感器,高电平说明有人;lcd()为欢迎词程序;lcd1()为警告词程序;lcd_init()为LCD初始化程序;问题:1.sw1==1时(有人),显示欢迎词,同时定时器开启;此时我把sw1==0(没人),这时定时器应该停止,LCD待机。但我写的这个程序,一直亮欢迎词,按下sw1==0后不会立即初始化,直到定时器2分钟定完过后才初始化。正确的应该是定时中若sw1==0,LCD立即就能初始化的效果。2.2分钟结束后,警告词只亮一次,然后又就跳到欢迎词。正确的应该是警告词一直显示,直到人走后(sw1==0),才待机,检测到人,显示欢迎词再如此循环。以下为自己写的程序(一些程序省篇幅就不贴出来了)voidTime0_init(){TMOD=0x01;//定时器T0工作在方式1,定时时间60ms=0.06sTH0=0x15;//高8位初值TL0=0xA0;//低8位初值EA=1;//开总中断ET0=1;//开定时器T0中断TR0=1;//启动定时器}voidmain(){while(1){a=0;//变量a清零if(sw1==1){Time0_init();lcd();if(sw1==0){lcd_init();}}while(2000-a!=0);//等待延时2000x0.06=120s=2minTR0=0;//关闭定时器while(sw1==1){lcd1();}}}voidTime0()interrupt1//中断服务程序{TH0=0x15;//重装定时器高8位初值TL0=0xA0;//重装定时器低8位初值a++;//变量a加1}

你看看是不是这里的问题

关于sw==1变化到sw==0时,为啥不会立即初始化,问题在下面这段程序上

if(sw1==1)

{

Time0_init();

lcd();

if(sw1==0)

{

lcd_init();

}

}

while(2000-a !=0);//等待延时2000x0.06=120s=2min

当if(sw==1)成立的时候,仅仅经过了两个函数运行的时间(我们暂且把这段时间叫做 s 吧,它可能只需要几十微秒),就来判断sw是否为0。这显然不合理,因为人从站到门口,到离开门口,怎么可能只要几十微秒呢,也就是说,当人还没有来得及离开时,你就要求sw==0了

0
回复
001a
LV.3
5
2014-02-10 11:05
@soap泡泡
你看看是不是这里的问题关于sw==1变化到sw==0时,为啥不会立即初始化,问题在下面这段程序上if(sw1==1){Time0_init();lcd();if(sw1==0){lcd_init();}}while(2000-a!=0);//等待延时2000x0.06=120s=2min当if(sw==1)成立的时候,仅仅经过了两个函数运行的时间(我们暂且把这段时间叫做s吧,它可能只需要几十微秒),就来判断sw是否为0。这显然不合理,因为人从站到门口,到离开门口,怎么可能只要几十微秒呢,也就是说,当人还没有来得及离开时,你就要求sw==0了
谢谢各位的指导啊,偶尔挑战一下自己也不错
0
回复
cltwolf
LV.5
6
2014-02-13 18:03
@001a
谢谢各位的指导啊,偶尔挑战一下自己也不错

逻辑上的问题。

第一、当开启系统时,要初始化一下,包括LCD,初始化完成之后,要归于待机状态,等待开启。(这个状态你肯定没设置,所以一开机和人走后,两个状态下就一直显示的不是你要的内容。)

在第一个的待机状态正常后,进入下一个。

第二、当有人来的时候,出现高电平,这时候:1、定时计数器启动;2、LCD打出欢迎词;3、持续检测人的位置状态。PS:从你程序看来,人员状态你只是问一下就不理了。按设计要求,应该把对时间的检测和对人的检测同步进行的。按照你程序里面的内容对应的,可以是这样:

while(2000-a)

    {

         if(sw1==0)

        { 

            a=2000;

            lcd_int('空白');

        }

         if(a==1999)

        {

            lcd1('喂,门前那谁谁谁,赶紧滚蛋!');

        }    

    }

while(sw1); 

lcd_int('空白'); 

0
回复