logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C]Zegarek nie liczy czasu

_Damian 10 Gru 2008 19:28 1797 12
REKLAMA
  • #1 5842899
    _Damian
    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
    
    #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]
  • REKLAMA
  • #2 5847244
    GienekS
    Poziom 32  
    Jaki to procesor ? Czy podłączyłeś kwarc do wejścia timera 2 skoro ustawiasz go jako asynchroniczny.
  • #3 5847908
    pubus
    Poziom 30  
    Jeśli to mega8 to czy dałeś kondensatory przy kwarcu...?
  • #4 5847964
    _Damian
    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.

  • REKLAMA
  • #5 5848042
    skynet_2
    Poziom 26  
    jest
    DDRB &= ~_BV(0); 
    DDRB &= ~_BV(1);

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


    jeżeli dalej nie działa spróbuj dodatkowo zakomentować
    if bit_is_clear(PINB,0) 
      { 
      minuty++; 
      } 
    if bit_is_clear(PINB,1) 
      { 
      godziny++; 
      }
  • #6 5848480
    kemot55
    Poziom 31  
    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).
  • REKLAMA
  • #7 5855553
    _Damian
    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?
  • #8 5855991
    pubus
    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...
    
    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...
  • REKLAMA
  • #9 5857991
    _Damian
    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.
  • #11 5866186
    _Damian
    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ą???
  • #12 5878547
    skynet_2
    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.

    //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
    #13 5881663
    skynet_2
    Poziom 26  
    wyświetlanie czasu

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

    
    //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
REKLAMA