3

我正在学习微控制器编程。我需要帮助才能使用 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++;
 }
4

4 回答 4

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
        }
    }
}
于 2015-12-01T08:53:18.417 回答
1

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

于 2015-12-01T08:47:19.580 回答
0

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

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

作为TIMER1一个 16 位值,它每 4.2 秒溢出一次。您可以使用此溢出来产生中断。900 秒只是 214.6 次中断——你能逃脱 898 秒吗?当然,您也可以计算TIMER0. 由于这只有 8 位,因此您有 256 倍的溢出:900 秒内有 54931 次。

于 2015-12-01T13:32:57.047 回答
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编译时没有编译错误。

于 2015-12-01T08:51:36.247 回答