• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Jak mogę wykryć czy klawisz jest wciśnięty dłużej niż 3 sekundy Atmega8A?

VPS Starter Arubacloud
0 głosów
356 wizyt
pytanie zadane 3 stycznia 2021 w C i C++ przez tonn204 Mądrala (7,470 p.)
zamknięte 25 stycznia 2021 przez tonn204

Cześć, piszę program, który obsługuje zegar zabudowany z wyświetlacza LCD (2x16), 4 przycisków tact switch i mikrokontrolera Atmega8A. Chcę aby bo przytrzymaniu przycisku dłużej niż 3 sekundy wartość godzin/minut/sekund zaczęła nie pojedynczo się zwiększać, ale szybko leciały w górę. Jak to zrobić ?

/*
     Digital clock
*/

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

#include <hd44780.c>

#include <stdio.h>
#include <stdlib.h>

#define KEY1_UP (PIND & (1 << PD2))
#define KEY2_UP (PIND & (1 << PD3))
#define KEY3_UP (PINB & (1 << PB6))
#define KEY4_UP (PINB & (1 << PB7))

#define timer_start 196

uint8_t modeFlag = 1;
uint8_t ableToEdit = 1;
volatile uint8_t seconds = 0;
volatile uint8_t minutes = 0;
volatile uint8_t hours = 0;
char secondsBuffer[3];
char minutesBuffer[3];
char hoursBuffer[3];
volatile uint8_t key1_Status;

ISR(TIMER0_OVF_vect)
{
    TCNT0 = timer_start;
    static uint8_t lkey1 = 0;
    static uint8_t lkey2 = 0;
    static uint8_t lkey3 = 0;
    static uint8_t lkey4 = 0;

    if(!KEY1_UP)
    {
        if(!lkey1)
        {
            lkey1 = 1;
            key1_Status = lkey1;
            if(ableToEdit == 1)
            {
                if(modeFlag > 3)
                {
                    modeFlag = 1;
                }
                modeFlag++;
            }
        }
    }
    else
    {
        if(lkey1)
        {
            lkey1 = 0;
            key1_Status = lkey1;
        }
    }

    if(!KEY2_UP)
    {
        if(!lkey2)
        {
            lkey2 = 1;
            if(ableToEdit == 1)
            {
                switch(modeFlag)
                {
                case 1:
                    hours ++;
                    if(hours >= 24)
                    {
                        hours = 0;
                    }
                    break;
                case 2:
                    minutes ++;
                    if(minutes >= 60)
                    {
                        minutes = 0;
                    }
                    break;
                case 3:
                    seconds ++;
                    if(seconds >= 60)
                    {
                        seconds == 0;
                    }
                    break;
                /*default:
                    hours ++;
                    break;*/
                }
            }
        }
    }
    else
    {
        if(lkey2)
        {
            lkey2 = 0;
        }
    }

    if(!KEY3_UP)
    {
        if(!lkey3)
        {
            lkey3 = 1;
            ableToEdit = 1;
            modeFlag = 1;
            TCCR1B &= ~(1 << CS12);
            TCCR1B &= ~(1 << CS10);
        }
    }
    else
    {
        if(lkey3)
        {
            lkey3 = 0;
        }
    }

    if(!KEY4_UP)
    {
        if(!lkey4)
        {
            lkey4 = 1;
            ableToEdit = 0;
            modeFlag = 1;
            TCCR1B |= (1 << CS12) | (1 << CS10);
        }
    }
    else
    {
        if(lkey4)
        {
            lkey4 = 0;
        }

    }
}

ISR(TIMER1_COMPA_vect)
{
    seconds++;
    if(seconds >= 60)
    {
        seconds = 0;
        minutes ++;
        if(minutes >= 60)
        {
            seconds = 0;
            minutes = 0;
            hours ++;
            if(hours >= 24)
            {
                hours, minutes, seconds = 0;
            }
        }
    }

}

int main(void)
{
    DDRD &= ~(1 << PD2);
    DDRD &= ~(1 << PD3);
    DDRB &= ~(1 << PB6);
    DDRB &= ~(1 << PB7);
    DDRB |= (1 << PB0);

    PORTD |= (1 << PD2);
    PORTD |= (1 << PD3);
    PORTB |= (1 << PB6);
    PORTB |= (1 << PB7);

    _delay_ms(10);

    // LCD init
    LCD_Initalize();

    // Timer1 init
    TCCR1B |= (1 << WGM12);
    OCR1A = 977;
    TIMSK |= (1 << OCIE1A);

    TCNT0 = timer_start;
    TIMSK |= (1 << TOIE0);
    sei();
    TCCR0 |= (1 << CS02) | (1 << CS00);

    while(1)
    {
        if(hours >= 24)
        {
            hours = 0;
        }
        if(minutes >= 60)
        {
            minutes = 0;
        }
        if(seconds >= 60)
        {
            seconds = 0;
        }

        if(modeFlag > 3)
        {
            modeFlag = 1;
        }

        itoa(seconds, secondsBuffer, 10);
        itoa(minutes, minutesBuffer, 10);
        itoa(hours, hoursBuffer, 10);

        LCD_Clear();
        LCD_GoTo(0, 0);
        if(ableToEdit == 1 && modeFlag == 1)
        {
            LCD_GoTo(4, 0);
            LCD_WriteText("Godziny");
        }
        else if(ableToEdit == 1 && modeFlag == 2)
        {
            LCD_GoTo(5, 0);
            LCD_WriteText("Minuty");
        }
        else if(ableToEdit == 1 && modeFlag == 3)
        {
            LCD_GoTo(5, 0);
            LCD_WriteText("Sekundy");
        }
        else
        {
            LCD_GoTo(0, 0);
            LCD_WriteText("Aktualna godzina");
        }

        LCD_GoTo(4, 1);
        switch(hours)
        {
            case 24:
                LCD_WriteText("00");
                break;
            case 0:
                LCD_WriteText("00");
                break;
            case 1:
                LCD_WriteText("01");
                break;
            case 2:
                LCD_WriteText("02");
                break;
            case 3:
                LCD_WriteText("03");
                break;
            case 4:
                LCD_WriteText("04");
                break;
            case 5:
                LCD_WriteText("05");
                break;
            case 6:
                LCD_WriteText("06");
                break;
            case 7:
                LCD_WriteText("07");
                break;
            case 8:
                LCD_WriteText("08");
                break;
            case 9:
                LCD_WriteText("09");
                break;
            default:
                LCD_WriteText(hoursBuffer);
        }
        LCD_GoTo(6, 1);
        LCD_WriteText(":");
        LCD_GoTo(7, 1);
        switch(minutes)
        {
            case 0:
                LCD_WriteText("00");
                break;
            case 1:
                LCD_WriteText("01");
                break;
            case 2:
                LCD_WriteText("02");
                break;
            case 3:
                LCD_WriteText("03");
                break;
            case 4:
                LCD_WriteText("04");
                break;
            case 5:
                LCD_WriteText("05");
                break;
            case 6:
                LCD_WriteText("06");
                break;
            case 7:
                LCD_WriteText("07");
                break;
            case 8:
                LCD_WriteText("08");
                break;
            case 9:
                LCD_WriteText("09");
                break;
            default:
                LCD_WriteText(minutesBuffer);
        }
        LCD_GoTo(9, 1);
        LCD_WriteText(":");
        LCD_GoTo(10, 1);
        switch(seconds)
        {
            case 0:
                LCD_WriteText("00");
                break;
            case 1:
                LCD_WriteText("01");
                break;
            case 2:
                LCD_WriteText("02");
                break;
            case 3:
                LCD_WriteText("03");
                break;
            case 4:
                LCD_WriteText("04");
                break;
            case 5:
                LCD_WriteText("05");
                break;
            case 6:
                LCD_WriteText("06");
                break;
            case 7:
                LCD_WriteText("07");
                break;
            case 8:
                LCD_WriteText("08");
                break;
            case 9:
                LCD_WriteText("09");
                break;
            default:
                LCD_WriteText(secondsBuffer);
        }
        _delay_ms(200);
    }

    return 0;
}

 

komentarz zamknięcia: Problem został rozwiązany
komentarz 8 stycznia 2021 przez Oscar Nałogowiec (29,300 p.)

Zmienne modeFlag i ableToEdit też powinny być volatile.

1 odpowiedź

0 głosów
odpowiedź 7 stycznia 2021 przez profesorek96 Szeryf (91,420 p.)
Polecam poczytać o czymś takim jak przerwania. Z tego co pamiętam Atmega 8 posiada przerwanie od przepełnienia bufora. Przepełnienie to występuje po czasie zależnym od częstotliwości zegara procesora. Dzięki wykorzystaniu przerwań był byś w stanie uzyskać pewną asynchroniczność.
komentarz 8 stycznia 2021 przez tonn204 Mądrala (7,470 p.)
Dzięki za podpowiedź, chodzi ci o w timerze? Bo innego, nie widzę.

Podobne pytania

0 głosów
0 odpowiedzi 208 wizyt
pytanie zadane 25 stycznia 2021 w C i C++ przez tonn204 Mądrala (7,470 p.)
0 głosów
1 odpowiedź 365 wizyt
0 głosów
1 odpowiedź 197 wizyt
pytanie zadane 4 listopada 2020 w C i C++ przez tonn204 Mądrala (7,470 p.)

92,975 zapytań

141,938 odpowiedzi

321,181 komentarzy

62,302 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...