如何在按下按钮后延迟输出约15分钟?

时间:2015-12-01 08:29:36

标签: c++ atmega winavr

我正在学习微控制器编程。我需要帮助才能在WinAVR上使用Atmega8L-8PU完成我的程序。 当按下按钮时,我添加了3个按钮:第一个按钮将提供15分钟输出,第二个按钮将提供30分钟,最后一个按钮将提供45分钟。每次应该在下次按下后自动重置时。

这是我写的代码,但我不能添加持续时间。如果有人能做到这对我来说会非常有帮助。提前谢谢:)。

#define numberofButtons 3

#include <avr/io.h>
#include"buttonpress.h"

int main(void)
{

    DDRB = 0b00000000;
    DDRD = 0b00000111;
    PORTB = (1<<PINB0)|(1<<PINB1)|(1<<PINB2);

    while(1)
    {
        if (buttonpressed(0, PINB, 0, 100))
        {
            PORTD ^= (1<<PIND0);
        }

        if (buttonpressed(1, PINB, 1, 100))
        {
            PORTD ^= (1<<PIND1);
        }
        if (buttonpressed(2, PINB, 2, 100))
        {
            PORTD ^= (1<<PIND2);
        }
    }
}

我试过这种方式,但它也没有工作........ :(

#define numberofButtons 3

#include"buttonpress.h"
#include <avr/io.h>
#include <avr/interrupt.h>

unsigned char seconds =0;
int minutes;

int main () 
{ 
    DDRB = 0b00000000;
    DDRD = 0b00000111; 
    PORTB = (1<<PINB0)|(1<<PINB1)|(1<<PINB2);

    volatile int seconds;
    DDRD |= (1<<PIND0)|(1<<PIND1)|(1<<PIND2);
    TCCR1B |= (1 << WGM12);                     // Configure timer 1 for CTC mode 
    TIMSK |= (1 << OCIE1A);                     // Enable CTC interrupt

    sei();                                      // Enable global interrupts
    OCR1A = 15624;                              // Set CTC compare value to   1Hz at 8MHz AVR clock, with a prescaler of 64 
    TCCR1B |= ((1 << CS10) | (1 << CS11));  // Start timer at Fcpu/64

    while (1) 
    { 

        if(seconds==60) 
        { 
            minutes++;
            seconds=0;
        }
        {
            if (buttonpressed(0, PINB, 0, 100))
            { 
                 PORTD ^= (1<<PIND0);
                 int total_seconds=900;

                 while(total_seconds-seconds!=0) 
                 { 
                     //Delay of 15 min 
                 } 
             }

          } return 0; 
      }
   }

 ISR (TIMER1_COMPA_vect)
 {
    seconds++;
 }

4 个答案:

答案 0 :(得分:1)

例如,您可以将Timer0设置为每秒调用一次中断。在每次中断期间,您必须递增内部计数器。经过所需的时间(15,30,45分钟)后,实现自己的逻辑(如关闭所需的端口)。

答案 1 :(得分:1)

如果您有从CPU获取计数器的功能,这是一个非常简单的计数器,计数器会随着可以计算的特定间隔而增加。

然后按下该按钮时,将变量设置为计数器的当前值加上对应于15分钟的量。在循环中,您将计数器的当前值检查到您在按键上设置的变量。当前计数器等于或大于变量时,则经过15分钟。

一些伪代码

int main(void)
{
    int eventHapening = 0;

    while (1)
    {
        if (keypress)
        {
            eventHappening = currentCounter + 15 minutes;
        }

        // Check that eventHappening is non-zero to prevent false positives
        if (eventHappening != 0 && currentCounter >= eventHappening)
        {
            // Do something
            eventHappening = 0; // Reset, and disable event
        }
    }
}

答案 2 :(得分:0)

如果您有权访问头文件time.h,那么以下内容可能是一个解决方案:

#define numberofButtons 3

#include <avr/io.h>
#include<time.h>
#include"buttonpress.h"

void wait(double x)
{
    clock_t begin, end;
    double time_spent, limit=1000*60*x;
    begin = clock();
    while(time_spent<= limit)
    {
        end = clock();
        time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    }
}


int main(void)
{
    DDRB = 0b00000000;
    DDRD = 0b00000111;
    PORTB = (1<<PINB0)|(1<<PINB1)|(1<<PINB2);

    while(1)
    {
        if (buttonpressed(0, PINB, 0, 100))
        {
            PORTD ^= (1<<PIND0);
            wait(15);
        }

        if (buttonpressed(1, PINB, 1, 100))
        {
            PORTD ^= (1<<PIND1);
            wait(15);
        }
        if (buttonpressed(2, PINB, 2, 100))
        {
            PORTD ^= (1<<PIND2);
            wait(15);
        }
    }
}

最有可能上面的代码不会出现任何错误。由于代码有一些依赖关系,我可以成功编译一个类似的程序,如下所示。

#define numberofButtons 3

#include <stdio.h>
#include<time.h>

void wait(double x)
{
    clock_t begin, end;
    double time_spent, limit=1000*60*x;
    begin = clock();
    while(time_spent<= limit)
    {
        end = clock();
        time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    }
}


int main(void)
{
    char c;
    while((c = getchar())!='e')
    {
        if (c == 'a')
        {
            printf("I am in a! Come after 15 min!\n");
            wait(15);
            printf("WOW! How could you pass 15 min!!\n");
        }
        if (c == 'b')
        {
            printf("I am in b! Come after 15 min!\n");
            wait(15);
            printf("WOW! How could you pass 15 min!!\n");
        }
        if (c == 'c')
        {
            printf("I am in c! Come after 15 min!\n");
            wait(15);
            printf("WOW! How could you pass 15 min!!\n");
        }
    }
}

使用c。

编译时,您可以看到here没有编译错误

答案 3 :(得分:0)

您没有将您的问题标记为AVR,这就是现有答案忽略了您拥有实际AVR计时器这一事实的原因。

更准确地说,那些定时器是CPU周期计数器。 TIMER1特别是16位计数器。如果将TCCR1时钟选择位设置为101,则每1024个CPU周期计数一个时钟。让我们假设一个16 Mhz的时钟,这意味着每秒16000000个CPU周期=每秒15625个滴答。

由于TIMER1是16位值,因此每4.2秒溢出一次。您可以将此溢出用于generate an interrupt。 900秒仅有214.6次中断 - 你能在898秒内逃脱吗?当然,您也可以计算TIMER0的溢出数。由于只有8位,所以溢出次数是256次:900秒内54931次。