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

C++ 如何在按下按钮后将输出延迟约15分钟?,c++,atmega,winavr,C++,Atmega,Winavr,我正在学习微控制器编程。我需要帮助才能用Atmega8L-8PU完成我在WinAVR的程序。 我添加了3个按钮,当按下按钮时:第一个按钮将提供15分钟的输出,第二个按钮将提供30分钟,最后一个按钮将提供45分钟的输出。每次按下后,应自动复位 这是我写的代码,但我不能添加时间长度。如果有人能做到,那将对我很有帮助。提前感谢: #define numberofButtons 3 #include <avr/io.h> #include"buttonpress.h" int main(

我正在学习微控制器编程。我需要帮助才能用Atmega8L-8PU完成我在WinAVR的程序。 我添加了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++;
 }

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

如果您可以访问头文件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进行编译时,它没有编译错误。

如果您有从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
        }
    }
}

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

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


由于计时器1是一个16位值,因此它每4.2秒溢出一次。您可以使用此溢出来删除。900秒就是214.6次中断-你能用898秒逃脱吗?当然,您也可以计算TIMER0的溢出量。因为只有8位,所以溢出量是原来的256倍:900秒内54931。

有没有功能可以获取当前时间(以秒为单位)或其他类似单位?我不明白,先生,因为我是编程新手,但我认为在900秒内可以计算15分钟,如果您有延迟代码,请提供给我。这是默认时钟。这里没有外部时钟。先生,你能给我time.h文件吗???@Sohel你可以检查一下。/time.h:73:错误:应该是“=”,“,”,“;”,”“clock”之前的asm或“attribute”@Sohel我不知道你在用什么编译器。但它是与C编译器一起工作的。在更新的答案中查看我的工作代码。@Sohel您能提供一些关于您的设备的更多信息吗?我可以如何在代码中使用指令??你能给我分配我想在15、30和40分钟后停止的代码吗?例如代码,请参阅我答案中的链接。当然,它使用50毫秒而不是90000毫秒,但是考虑这部分练习。您不是从复制代码中学习,而是从编写代码中学习。谢谢您宝贵的指导,先生,我已经尝试过了,但我无法关闭它。如果你能帮助我在哪里输入这些数据,我会更容易学习。如果你有几分钟的时间……在我的帖子中,我添加了3个按钮,它们正在工作。当我按下按钮时,LED亮起,我想在一段时间后将其关闭。我尝试了很多方法,但我做不到。请帮帮我。@Sohel:我只是想澄清一下,你能不能创建一个立即关灯的按钮?学习编程就是把繁重的任务分解成简单的部分。