• 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?

Object Storage Arubacloud
0 głosów
332 wizyt
pytanie zadane 3 stycznia 2021 w C i C++ przez tonn204 Mądrala (7,440 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,290 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,440 p.)
Dzięki za podpowiedź, chodzi ci o w timerze? Bo innego, nie widzę.

Podobne pytania

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

92,555 zapytań

141,404 odpowiedzi

319,557 komentarzy

61,940 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...