Как отложить вывод на 15 минут после нажатия кнопки?

Я изучаю программирование микроконтроллера. Мне нужна помощь для завершения моей программы в 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++;
}

3

Решение

Вы можете настроить Timer0 для вызова прерывания каждую секунду, например. Во время каждого прерывания вы должны увеличивать внутренний счетчик. По истечении требуемого времени (15, 30, 45 мин) реализуйте свою собственную логику (например, отключение нужного порта).

1

Другие решения

Это очень просто, если у вас есть функции для получения счетчика от ЦП, счетчик, который увеличивается с определенным интервалом, который можно вычислить.

Затем, когда кнопка нажата, вы устанавливаете переменную на текущее значение счетчика плюс значение, соответствующее 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
}
}
}
1

Если у вас есть доступ к файлу заголовка 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");
}
}
}

Ты можешь видеть Вот что он не имеет ошибки компиляции при компиляции с.

0

Вы не пометили свой вопрос как AVR, поэтому в существующих ответах игнорируется тот факт, что у вас есть реальные таймеры AVR.

Точнее, эти таймеры являются счетчиками циклов ЦП. TIMER1 в частности это 16-битный счетчик. Если вы установите TCCR1 часы выбирают биты 101, это будет считать один тик каждые 1024 тактов процессора. Давайте предположим, что частота 16 МГц равна 16000000 тактов процессора в секунду = 15625 тактов в секунду.

Как TIMER1 16-битное значение, оно переполняется каждые 4,2 секунды. Вы можете использовать это переполнение для генерировать прерывание. 900 секунд — это всего лишь 214,6 прерывания. Можете ли вы уйти с 898 секундами? Конечно, вы также можете рассчитывать переполнения TIMER0, Поскольку это всего 8 бит, вы переполнены в 256 раз: 54931 за 900 секунд.

0
По вопросам рекламы [email protected]