Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C]Zegarek nie liczy czasu

10 Gru 2008 19:28 1497 12
  • Poziom 11  
    Witam wszystkich !!!
    Jakiś czas temu wykonałem sobie zegarek z wyświetlaczami LED. (najprostszy jaki może być)
    I problem jest w tym ,że nie odlicza czasu tylko stoi w miejscu pokazuje same zera i nie reaguje na przyciskanie przycisków co jest nie tak?

    Oto i program
    Code:

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

    const unsigned char cyfry[]={0b00011000,0b11011011,0b10001100,0b10001001,0b01001011,0b00101001,0b00101000,0b10011011,0b00001000,0b00001001};
    const unsigned char dziesiatki_godzin=0b11110111;
    const unsigned char jednosci_godzin=0b11111011;
    const unsigned char dziesiatki_minut=0b11101111;
    const unsigned char jednosci_minut=0b11011111;

    volatile unsigned char sekundy = 0;
    volatile unsigned char godziny = 0;
    volatile unsigned char minuty = 0;

    SIGNAL(SIG_OVERFLOW2)
    {


    if (++sekundy==59)
      {
      sekundy=0;
      minuty++;
      }
    if bit_is_clear(PINB,0)
      {
      minuty++;
      }
    if (minuty==59)
      {
      minuty=0;
      godziny++;
      }
    if bit_is_clear(PINB,1)
      {
      godziny++;
      }
    if (godziny==23)
      {
      godziny=0;
      }
    }

    int main (void)
    {

    DDRD = 0xFF;
    DDRC = 0xFF;
    DDRB &= ~_BV(0);
    DDRB &= ~_BV(1);


    ASSR |= _BV(AS2);
    TCCR2 |= _BV(CS20) |_BV(CS22);
    TIMSK|=_BV (TOIE2);
    sei();

    for (;;)
    {
    PORTD=cyfry[minuty%10];
    PORTC=jednosci_minut;
    _delay_us (100);
    PORTD=cyfry[minuty/10];
    PORTC=dziesiatki_minut;
    _delay_us (100);
    PORTD=cyfry[godziny%10];
    PORTC=jednosci_godzin;
    _delay_us (100);
    PORTD=cyfry[godziny/10];
    PORTC=dziesiatki_godzin;
    _delay_us (100);
    }
    return(0);
    }

    Poprawiłem tytuł - regulamin p.11.2
    [zumek]
  • Poziom 32  
    Jaki to procesor ? Czy podłączyłeś kwarc do wejścia timera 2 skoro ustawiasz go jako asynchroniczny.
  • Poziom 30  
    Jeśli to mega8 to czy dałeś kondensatory przy kwarcu...?
  • Poziom 11  
    Oczywiście ,że podłączyłem kwarc zewnęczny ale bez kondensatorów a ten procesor to atmega8.
    Moderowany przez zumek:

    W przyszłości, kluczowe informacje proszę umieszczać przy zakładaniu tematu, a nie dopiero jak ktoś poprosi.

  • Poziom 26  
    jest
    Code:
    DDRB &= ~_BV(0); 
    
    DDRB &= ~_BV(1);

    powinno być
    Code:
    DDRB = ~(_BV(1) | _BV(0));


    jeżeli dalej nie działa spróbuj dodatkowo zakomentować
    Code:
    if bit_is_clear(PINB,0) 
    
      {
      minuty++;
      }
    if bit_is_clear(PINB,1)
      {
      godziny++;
      }
  • Poziom 30  
    Proponuję poczytać :
    http://www.atmel.com/dyn/resources/prod_documents/doc1259.pdf
    oraz
    http://www.atmel.com/dyn/resources/prod_documents/Avr134.zip

    Co prawda można napisać wszystko samemu (np. żeby się czegoś nauczyć)
    Projekt z załączników dotyczy procesora ATMega 103, ale pewnie łatwo to zaadaptować na inne maszyny (ja robiłem trochę bardziej skomplikowaną formę zegara RTC na ATmega 169).
  • Poziom 11  
    Wyrzuciłem ustawianie godzin, minut i działa ale przecież musze jakoś ustawiać czas no a jeśli dam ustawianie minut i godzin to pokazują sie głupoty ;/
    Jak mam zrobić ustawianie godziny żeby czas liczyło dobrze?
  • Poziom 30  
    Jak na mój gust to tak...
    Z przerwania wywal obsługę przycisków...
    Zostaw tylko przeliczanie czasu...
    Może to wyglądać np tak...
    Code:

    SIGNAL (TIMER2_OVF_vect)
    {
     if(sec<59) sec++;
      else {sec=0; if(min<59) min++;
       else {min=0; if(godz<23) godz++;
        else {godz=0;} }}
    }

    Obsługę przycisków przenieś do pętli głównej...
    Jak na razie tylko to mi się na oczy rzuciło...
  • Poziom 11  
    Wyrzuciłem z procedury przerwania obsługę przycisków, ale po co do tego zmieniać samą procedurę jak przecież zegar czas odlicza. Pozostaje właśnie tylko problem z ustawianiem minut i godzin.
  • Poziom 38  
    No to napisz to jak Ci radzą w pętli głównej.
    Jak przycisk wcisniety wait 100ms, zmienna++
    i juz:>
    cala FILOZOFIA:>
  • Poziom 11  
    Zamierzam dopisać do tego programu ustawianie czasu i budzeni. Do dyspozycji mam 3 przyciski i tak sobie to wymyśliłem. Dwa przyciski będą służyć do ustawiania godzin i minut zarówno budzenia jak i czasu pokazywanego przez zegarek, budzenie będzie migało,żeby odróżnić je na wyświetlaczu od czasu pokazywanego przez zegarek, a za pomocą 3 przycisku będę przechodził z budzenia do czasu który normalnie pokazuje zegarek. Myślałem żeby to zrobić w 2 pętlach nie skończonych i za pomocą tego 3 przycisku i polecenia break; zmieniał bym pętlę i czas pokazywany na wyświetlaczu ( 1 pętla nie skończoną to normalny czas a 2 to budzenie). Jak by wyglądał wasz ogólny zarys tego co chce zrobić , a może ktoś ma inną propozycje - lepszą , łatwiejszą???
  • Poziom 26  
    Cytat:
    budzenie będzie migało,żeby odróżnić je na wyświetlaczu od czasu pokazywanego przez zegarek

    to jest trochę kłopotliwe
    prościej daj 2 diody led, 1 świeci jak ustawiasz zegar 2 jak budzik.

    Code:
    //zmienne pomocnicze ;)
    
    //wrzuć do main
    uint8_t b0[2]={0,0};
    uint8_t b1[2]={0,0};
    uint8_t b2[2]={0,0};
    uint8_t mode=0;
    uint8_t busy=0;

    //od tąd dopisz do swojej pętli  for (;;)
    //detekcja zmiany stanu przycisku
    b0[1]=b0[0];if(bit_is_clear(PINB,0)){b0[0]=0;}else{b0[0]=1;}
    b1[1]=b1[0];if(bit_is_clear(PINB,1)){b1[0]=0;}else{b1[0]=1;}
    b2[1]=b2[0];if(bit_is_clear(PINB,2)){b2[0]=0;}else{b2[0]=1;}

    //detekcja i akcja wciśnięcia przycisku
    //mode=0 idle
    //mode=1 ustawianie budzika
    //mode=2 ustawianie zegara
    if(b0[1]>b0[0]){
       if(busy){mode=0;}
       else{
       if(++mode==3){mode=0;}else{mode++;}}}

    if(b1[1]>b1[0]){
       if(mode=1){if(++godziny_budzenia==24){godziny_budzenia=0;};}
       if(mode=2){if(++godziny==24){godziny=0;};};busy=1;}

    if(b2[1]>b2[0]){
       if(mode=1){if(++minuty_budzenia==60){minuty_budzenia=0;};}
       if(mode=2){if(++minuty==60){minuty=0;};};busy=1;}

    if(mode==0){PORTB&=~(2<<3);}else{
     if(mode==1){PORTB|=1<<3;}//dioda od ustawiania budzika
     if(mode==2){PORTB|=1<<4;}//dioda od ustawiania zegara
    }


    w skrócie naciskasz mode[b0] zmieniasz tryb na ustawianie budzika ustawiasz budzik naciskasz na mode[b0] i masz spowrotem zegar

    naciskasz mode[b0] zmieniasz tryb na ustawianie budzika naciskasz ponownie mode[b0] zmieniasz tryb na ustawianie zegara ustawisz zegar bądz naciskasz jeszcze raz i wracasz do idle[zwykły zegara]



    Po 2 pisałem z głowy, kod nie jest optymalny ale powinno działać
  • Pomocny post
    Poziom 26  
    wyświetlanie czasu

    Code:
    PORTD=cyfry[minuty%10]; 
    
    PORTC=jednosci_minut;
    _delay_us (100);
    PORTD=cyfry[minuty/10];
    PORTC=dziesiatki_minut;
    _delay_us (100);
    PORTD=cyfry[godziny%10];
    PORTC=jednosci_godzin;
    _delay_us (100);
    PORTD=cyfry[godziny/10];
    PORTC=dziesiatki_godzin;
    _delay_us (100);

    zamień na
    Code:

    if(mode==1){
    PORTD=cyfry[minuty_budzenia%10];
    PORTC=jednosci_minut;
    _delay_us (100);
    PORTD=cyfry[minuty_budzenia/10];
    PORTC=dziesiatki_minut;
    _delay_us (100);
    PORTD=cyfry[godziny_budzenia%10];
    PORTC=jednosci_godzin;
    _delay_us (100);
    PORTD=cyfry[godziny_budzenia/10];
    PORTC=dziesiatki_godzin;
    _delay_us (100);}

    else{

    PORTD=cyfry[minuty%10];
    PORTC=jednosci_minut;
    _delay_us (100);
    PORTD=cyfry[minuty/10];
    PORTC=dziesiatki_minut;
    _delay_us (100);
    PORTD=cyfry[godziny%10];
    PORTC=jednosci_godzin;
    _delay_us (100);
    PORTD=cyfry[godziny/10];
    PORTC=dziesiatki_godzin;
    _delay_us (100);}



    co do buzera

    Code:

    //gdzieś przed przerwaniem
    volatile uint8_t budz=0;
    //gdzieś na końcu przerwania
    if((godziny_budzenia==godziny)&&(minuty_budzenia==minuty)&&(sekundy==0)){
    budz=1;}
    //na końcu for(;;)
    if((budz==1)&&((PORTC&=1<<pin_od_wyłącznika_budzenia)==0)){budz=0;}else{PORTC|=1<<pin_od_budzenia;}//pin_od_budzenia załączony cały czas kiedy budzenie


    po 1 poprawiłem poprzedni post[dodane zabezpieczenie]
    po 2 naucz się C
    po 3 zacznij pisać na forum a nie na PW

    pozdrawiam