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

[atmega16][C]zegar, pomoc w pisaniu

arachno 31 Lip 2008 20:02 2539 12
  • #1 31 Lip 2008 20:02
    arachno
    Poziom 9  

    witam,mam taki swój własny projekcik gdzie sercem układu jest atmega16, mam problem z częścią programu wyświetlającą czas na ekranie LCD alfanumerycznego.pomimo licznych poszukiwań znalazłam tylko poniższy kawałek programu. Pytanie brzmi jak zrobić by działał on na alfanumerycznym, a jeszcze lepiej by po prostu odliczył dokładny czas np. 10h (wiem że to dziwne dla niektórych ale mój program musi spełniać taką funkcję), w dodatku ważne by był w C, ponieważ w tym języku jest reszta programu. Proszę o pomoc w przeróbce bo jestem laikiem w C. Chcę wykorzystać do odliczania tego czasu 32,768 bo taki zamontowałam w płytce.


    Code:
    #include <avr/io.h>
    
    #include <avr/interrupt.h>
    #include <avr/signal.h>

    #define D1_ON PORTD &= 0xBF
    #define D2_ON PORTD &= 0xDF
    #define D3_ON PORTD &= 0xEF
    #define D4_ON PORTD &= 0xF7

    // tablica z kodami znaków dla wyświetlacza
    char znaki[17] = {192,249,164,176,153,146,130,248,128,144,136,131,198,161,134,142,0};
    // zmienna pomocnicza określająca którą cyfrę wyświetlacza w danym momencie należy wyświetlić
    char wysw;
    // zmianne licznikowe do odmierzania czasu
    char jednostki_sekund = 9, dziesiatki_sekund = 5,
    jednostki_minut = 9, dziesiatki_minut = 5,
    jednostki_godzin = 3, dziesiatki_godzin = 2;

    void aktualizuj_czas(void);

    //
    SIGNAL (SIG_OVERFLOW0)
    {
    TCNT0 = 250; // załadowanie do licznika wartości początkowej
    PORTD = 0xFF; // wygaszenie wszystkich cyfr wyświetlacza
    wysw++; // zwiększenie o 1 zmiennej wysw
    // w zależności od wartości wysw włącz odpowiednią cyfrę na wyświetlaczu
    switch(wysw){
    case 1:
    {
    PORTB = *(znaki + dziesiatki_godzin); // na wyświetlaczu wyświetl odpowiedni
    // znak pobrany z tablicy znaków
    D1_ON; // włącz pierwszą cyfrę wyświetlcza
    break; // opuść instrukcję switch
    }
    case 2:
    {
    PORTB = *(znaki + jednostki_godzin); // na wyświetlaczu wyświetl odpowiedni
    // znak pobrany z tablicy znaków
    D2_ON; // włącz drugą cyfrę wyświetlcza
    break; // opuść instrukcję switch
    }
    case 3:
    {
    PORTB = *(znaki + dziesiatki_minut); // na wyświetlaczu wyświetl odpowiedni
    // znak pobrany z tablicy znaków
    D3_ON; // włącz trzecią cyfrę wyświetlcza
    break; // opuść instrukcję switch
    }
    case 4:
    {
    PORTB = *(znaki + jednostki_minut); // na wyświetlaczu wyświetl odpowiedni
    // znak pobrany z tablicy znaków
    D4_ON; // włącz czwartą cyfrę wyświetlcza
    break; // opuść instrukcję switch
    }
    case 5:
    {
    wysw = 0; // zeruj zmienną wysw
    break; // opuść instrukcję switch
    }
    }
    }

    //




    SIGNAL (SIG_OVERFLOW1)
    {
    TCNT1L = 0xDC; // załadowanie do licznika TIMER1 wartości początkowych
    TCNT1H = 0x0B; // określających częstotliwość występowania przerwania
    aktualizuj_czas(); // wywołanie procedury aktualizującej czas
    }

    // procedura aktualizująca czas
    void aktualizuj_czas(void)
    {
    jednostki_sekund++; // zwiększ licznik jednostek sekund o 1
    if(jednostki_sekund == 10) // jeśli licznik jednostek sekund osiągnął wartość 10 to
    {
    jednostki_sekund = 0; // wyzeruj licznik jednostek sekund
    dziesiatki_sekund++; // zwiększ licznik dziesiątek sekund o 1
    if(dziesiatki_sekund == 6) // jeśli licznik dziesiątek sekund osiągnął wartość 6 to
    {
    dziesiatki_sekund = 0; // wyzeruj licznik dziesiątek sekund
    jednostki_minut++; // zwiększ licznik jednostek minut o 1
    if(jednostki_minut == 10) //jeśli licznik jednostek minut osiągnął wartość 10 to
    {
    jednostki_minut = 0; // wyzeruj licznik jednostek minut
    dziesiatki_minut++; // zwiększ licznik dzieisątekminut o 1
    if(dziesiatki_minut == 6) // jeśli licznik dziesiątek minut osiągnął wartość 6 to
    {
    dziesiatki_minut = 0; // wyzeruj licznik dziesiątek minut
    jednostki_godzin++; // zwiększ licznik jednostek godzin o 1
    if((dziesiatki_godzin == 2) && (jednostki_godzin == 4)) // jeżeli jest północ to
    {
    dziesiatki_godzin = jednostki_godzin = 0; // zeruj licznik dziesiątek i jednostek godzin
    }
    if(jednostki_godzin == 10) // jeśli licznik jednostek godzin osiągnął wartość 10 to
    {
    jednostki_godzin = 0; // wyzeruj licznik jednostek godzin
    dziesiatki_godzin++; // zwiększ licznik dziesiątek godzin o 1
    }
    }
    }
    }
    }
    }



    // Program główny
    int main(void)
    {
    // konfiguracja portów I/O
    DDRB = 0xFF;
    DDRD = 0xFC;
    PORTB = 0xFF;
    PORTD = 0xF7;
    // ustawienie trybu pracy licznika
    TCCR0 = 0x04;
    TCCR1B = 0x03;

    // wpisanie wartości początkowej
    TCNT0 = 128;
    // odblokowanie przerwania od licznika
    TIMSK = 130;
    // globalne odblokowanie przerwań
    sei();
    // pusta pętla nieskoczona
    while(1);
    return 0;
    }


    Porty od LCD-ka to odpowiednio PC3,PC2,PC1,PC0 -- D4,D5,D6,D7, E-PC4, RS-PC5
    Gdzie w dodatku umieścić procedurę inicjalizacjiLCD i jak wysłać to już bezpośrednio na wyświetlacz

    Z góry dzięki za wskazówki i mam nadzieję że wybaczycie mi mój słaby poziom.

    0 12
  • #2 31 Lip 2008 20:56
    piotrva
    Moderator na urlopie...

    dokładnie nie znam C, ale musisz:
    1. Ściągnąć odpowiednią bibliotekę do obsługi LCD (sprawdź koniecznie model sterownika z tyłu wyświetlacza)
    2. Zamienić wyświetlanie w Twoim programie na funkcję z biblioteki LCD, którą musisz koniecznie wcześniej skonfigurować na odpowiednie porty (zgodnie z wybranym 4/8 bitowym przesyłem danych)

    0
  • #3 31 Lip 2008 21:06
    arachno
    Poziom 9  

    biblioteka do obsługi LCD jak najbardziej obecna, poniewaz moj program wyglada troche inaczej i robi juz wczesniej mnostwo innych rzeczy, a co do wyswietlania na lcd to mam do tego taka funkcje LCD_WriteText(), pytanie brzmi co w nia wpisac "wysw"? Tylko skad procesor bedzie wiedzial co wyrzucic na wyswietlacz jesli w signal(sig_overflow0) deklaruje porty wyswietlacza led zamiast lcd, chyba zeby to wyrzucic? ale dziekuje za zainteresowanie... prosze pomozcie

    0
  • #4 31 Lip 2008 22:08
    greatlukas
    Poziom 13  

    możesz wywalić całkowicie

    Code:
    SIGNAL (SIG_OVERFLOW0)

    bo tam jest realizowana obsługa wyświetlaczy LED.

    a żeby wyświetlić aktualny czas musisz mieć dobrą bibliotekę do LCD,
    i tak:
    1. na początku w funkcji main() musisz zainicjalizować cały wyświetlacz.
    2. następnie w funkcji
    Code:
    void aktualizuj_czas(void)

    na początku dodaj:
    Code:

    unsigned char czas[9];

    a na samym końcu tej funkcji dopisz
    Code:

    sprintf(czas,"%d%d:%d%d:%d%d",dziesiatki_godzin, jednostki_godzin, dziesiatki_minut, jednostki_minut, dziesiatki_sekund, jednostki_sekund);
    LCD_WriteText(czas);

    i to powinno zadziałać :)

    oczywiście jest to jeden z milionów sposobów na zrealizowanie zegarka :) a już na pewno nie jest idealny :P

    0
  • #5 01 Sie 2008 08:34
    arachno
    Poziom 9  

    no i czapa:

    main.c:145: error: previous definition of 'LCD_WriteText' was here


    Code:
    void LCD_WriteText(char * text)
    
    {
    while(*text)
      LCD_WriteData(*text++);
    }


    a zrobiłam dokładnie jak prosiłeś:

    Code:
    void aktualizuj_czas(void)
    
    unsigned char czas[9];
    {
    jednostki_sekund++; // zwiększ licznik jednostek sekund o 1
    if(jednostki_sekund == 10) // jeśli licznik jednostek sekund osiągnął wartość 10 to
      {
      jednostki_sekund = 0; // wyzeruj licznik jednostek sekund
      dziesiatki_sekund++;  // zwiększ licznik dziesiątek sekund o 1
      if(dziesiatki_sekund == 6) // jeśli licznik dziesiątek sekund osiągnął wartość 6 to
        {
        dziesiatki_sekund = 0; // wyzeruj licznik dziesiątek sekund
        jednostki_minut++; // zwiększ licznik jednostek minut o 1
        if(jednostki_minut == 10) //jeśli licznik jednostek minut osiągnął wartość 10 to
          {
          jednostki_minut = 0; // wyzeruj licznik jednostek minut
          dziesiatki_minut++; // zwiększ licznik dzieisątekminut o 1
          if(dziesiatki_minut == 6) // jeśli licznik dziesiątek minut osiągnął wartość 6 to
            {
            dziesiatki_minut = 0; // wyzeruj licznik dziesiątek minut
            jednostki_godzin++; // zwiększ licznik jednostek godzin o 1
            if((dziesiatki_godzin == 2) && (jednostki_godzin == 4)) // jeżeli jest północ to
              {
              dziesiatki_godzin = jednostki_godzin = 0; // zeruj licznik dziesiątek i jednostek godzin
              }
            if(jednostki_godzin == 10) // jeśli licznik jednostek godzin osiągnął wartość 10 to
              {
              jednostki_godzin = 0; // wyzeruj licznik jednostek godzin
              dziesiatki_godzin++; // zwiększ licznik dziesiątek godzin o 1
              }
            }
          }
        }
      }
    }

    sprintf(czas,"%d%d:%d%d:%d%d",dziesiatki_godzin, jednostki_godzin, dziesiatki_minut, jednostki_minut, dziesiatki_sekund, jednostki_sekund);

    LCD_WriteText(czas);



    i jeszcze to:

    main.c:611: error: expected ')' before string constant

    Code:
    sprintf(czas,"%d%d:%d%d:%d%d",dziesiatki_godzin, jednostki_godzin, dziesiatki_minut, jednostki_minut, dziesiatki_sekund, jednostki_sekund);


    może jakiś inny sposób? mniej zawiły?biblioteka jest dobra bo czesc programu juz wczesniej chodzila na lcd ale teraz zajmuje sie tylko tym

    0
  • #6 01 Sie 2008 11:33
    ndru_w
    Poziom 11  

    Witam,
    Nie wiem mogę się mylić ale deklaracja zmiennej unsigned char czas [9]; powinna być w innym miejscu niż między nazwą funkcji a pierwszym jej bracketem to jeśli chodzi o main.c:611...
    A co do pierwszego błędu sprawdź czy dobrze zadeklarowałeś funkcje, czy je odpowiednio podołączałeś do projetku, itp.
    Pozdrawiam

    0
  • #7 01 Sie 2008 12:30
    Balu
    Poziom 38  

    Tak jak pisze ndru_w brak prototypu funkcji - brak na początku pliku #include "moja_Bibl_lcd.h":)

    0
  • #8 01 Sie 2008 12:35
    arachno
    Poziom 9  

    no tak programista z bozej laski nie dodal 2 klamerek, teraz jjuz nie wyrzuca bledow, pytanie tylko dlaczego ekran tak jakby miga nic nie wyswietlajac, co robie jesscze zle?
    funkcje na pewno sa dobrze poumieszczane, bo do innej czesci programu wszystko dziala, ale umieszcze caly program zeby nie bylo watpliwosci::


    Code:
    #include <avr/io.h>
    
    #include <avr/interrupt.h>
    #include <stdlib.h>
    #include <avr/delay.h>
    #include <inttypes.h>
    #include <HD44780.h>

    #define PORT(x)   XPORT(x)
    #define XPORT(x) (PORT##x)

    #define PIN(x) XPIN(x)
    #define XPIN(x) (PIN##x)

    #define DDR(x) XDDR(x)
    #define XDDR(x) (DDR##x)

    #define SW_PORT B
    #define SW1 3
    #define SW2 2
    #define SW3 1
    #define SW4 0

    // Funkcja wystawiająca półbajt na magistralę danych
    //
    //-------------------------------------------------------------------------------------------------
    void waitms(char x)
    {
    unsigned char a, b; // zmnienne licznikowe
    for( ; x > 0; --x) // ta pętla zostanie wykonana x-razy
      for(b = 10; b > 0; --b) // a ta 10 razy
       for(a = 100; a > 0; --a) // natomiast ta 100 razy
       __asm("nop"); // dodatkowa instrukcja opóźniająca o 1 cykl
       // razem to da opóźnienie ok. x * 1ms
       // x od 0 do 255
    }



    void _LCD_OutNibble(unsigned char nibbleToWrite)
    {
    if(nibbleToWrite & 0x01)
       LCD_DB4_PORT |= LCD_DB4;
    else
       LCD_DB4_PORT  &= ~LCD_DB4;

    if(nibbleToWrite & 0x02)
       LCD_DB5_PORT |= LCD_DB5;
    else
       LCD_DB5_PORT  &= ~LCD_DB5;

    if(nibbleToWrite & 0x04)
       LCD_DB6_PORT |= LCD_DB6;
    else
       LCD_DB6_PORT  &= ~LCD_DB6;

    if(nibbleToWrite & 0x08)
       LCD_DB7_PORT |= LCD_DB7;
    else
       LCD_DB7_PORT  &= ~LCD_DB7;
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja zapisu bajtu do wyświetacza (bez rozróżnienia instrukcja/dane).
    //
    //-------------------------------------------------------------------------------------------------
    void _LCD_Write(unsigned char dataToWrite)
    {
    LCD_E_PORT |= LCD_E;
    _LCD_OutNibble(dataToWrite >> 4);
    LCD_E_PORT &= ~LCD_E;
    LCD_E_PORT |= LCD_E;
    _LCD_OutNibble(dataToWrite);
    LCD_E_PORT &= ~LCD_E;
    _delay_us(15);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja zapisu rozkazu do wyświetlacza
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_WriteCommand(unsigned char commandToWrite)
    {
    LCD_RS_PORT &= ~LCD_RS;
    _LCD_Write(commandToWrite);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja zapisu danych do pamięci wyświetlacza
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_WriteData(unsigned char dataToWrite)
    {
    LCD_RS_PORT |= LCD_RS;
    _LCD_Write(dataToWrite);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja wyświetlenia napisu na wyswietlaczu.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_WriteText(char * text)
    {
    while(*text)
      LCD_WriteData(*text++);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja ustawienia współrzędnych ekranowych
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_GoTo(unsigned char x, unsigned char y)
    {
    LCD_WriteCommand(HD44780_DDRAM_SET | (x + (0x40 * y)));
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja czyszczenia ekranu wyświetlacza.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_Clear(void)
    {
    LCD_WriteCommand(HD44780_CLEAR);
    _delay_ms(2);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja przywrócenia początkowych współrzędnych wyświetlacza.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_Home(void)
    {
    LCD_WriteCommand(HD44780_HOME);
    _delay_ms(2);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Procedura inicjalizacji kontrolera HD44780.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_Initalize(void)
    {
    unsigned char i;
    LCD_DB4_DIR |= LCD_DB4; // Konfiguracja kierunku pracy wyprowadzeń
    LCD_DB5_DIR |= LCD_DB5; //
    LCD_DB6_DIR |= LCD_DB6; //
    LCD_DB7_DIR |= LCD_DB7; //
    LCD_E_DIR    |= LCD_E;   //
    LCD_RS_DIR    |= LCD_RS;  //
    _delay_ms(15); // oczekiwanie na ustalibizowanie się napiecia zasilajacego
    LCD_RS_PORT &= ~LCD_RS; // wyzerowanie linii RS
    LCD_E_PORT &= ~LCD_E;  // wyzerowanie linii E

    for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
      {
      LCD_E_PORT |= LCD_E; //  E = 1
      _LCD_OutNibble(0x03); // tryb 8-bitowy
      LCD_E_PORT &= ~LCD_E; // E = 0
      _delay_ms(5); // czekaj 5ms
      }

    LCD_E_PORT |= LCD_E; // E = 1
    _LCD_OutNibble(0x02); // tryb 4-bitowy
    LCD_E_PORT &= ~LCD_E; // E = 0

    _delay_ms(1); // czekaj 1ms
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_4_BIT); // interfejs 4-bity, 2-linie, znak 5x7
    LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF); // wyłączenie wyswietlacza
    LCD_WriteCommand(HD44780_CLEAR); // czyszczenie zawartosći pamieci DDRAM
    _delay_ms(2);
    LCD_WriteCommand(HD44780_ENTRY_MODE | HD44780_EM_SHIFT_CURSOR | HD44780_EM_INCREMENT);// inkrementaja adresu i przesuwanie kursora
    LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_OFF | HD44780_CURSOR_NOBLINK); // włącz LCD, bez kursora i mrugania
    }

    // zakomentowana moja czesc programu!!!!!!!!!!!!!

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

    #define D1_ON PORTC &= 0x08
    #define D2_ON PORTC &= 0x04
    #define D3_ON PORTC &= 0x02
    #define D4_ON PORTC &= 0x01

    // tablica z kodami znaków dla wyświetlacza
    char znaki[17] = {192,249,164,176,153,146,130,248,128,144,136,131,198,161,134,142,0};
    // zmienna pomocnicza określająca którą cyfrę wyświetlacza w danym momencie należy wyświetlić
    char wysw;
    // zmianne licznikowe do odmierzania czasu
    char jednostki_sekund = 9, dziesiatki_sekund = 5,
         jednostki_minut = 9, dziesiatki_minut = 5,
         jednostki_godzin = 3, dziesiatki_godzin = 2;



    void aktualizuj_czas(void);


    //
     
    SIGNAL (SIG_OVERFLOW1)

    {

    TCNT1L = 0xDC; // załadowanie do licznika TIMER1 wartości początkowych
    TCNT1H = 0x0B; // określających częstotliwość występowania przerwania
    aktualizuj_czas(); // wywołanie procedury aktualizującej czas


    }
    //


    // procedura aktualizująca czas
    void aktualizuj_czas(void)
    {unsigned char czas[9];
    {

    jednostki_sekund++; // zwiększ licznik jednostek sekund o 1
    if(jednostki_sekund == 10) // jeśli licznik jednostek sekund osiągnął wartość 10 to
      {
      jednostki_sekund = 0; // wyzeruj licznik jednostek sekund
      dziesiatki_sekund++;  // zwiększ licznik dziesiątek sekund o 1
      if(dziesiatki_sekund == 6) // jeśli licznik dziesiątek sekund osiągnął wartość 6 to
        {
        dziesiatki_sekund = 0; // wyzeruj licznik dziesiątek sekund
        jednostki_minut++; // zwiększ licznik jednostek minut o 1
        if(jednostki_minut == 10) //jeśli licznik jednostek minut osiągnął wartość 10 to
          {
          jednostki_minut = 0; // wyzeruj licznik jednostek minut
          dziesiatki_minut++; // zwiększ licznik dzieisątekminut o 1
          if(dziesiatki_minut == 6) // jeśli licznik dziesiątek minut osiągnął wartość 6 to
            {
            dziesiatki_minut = 0; // wyzeruj licznik dziesiątek minut
            jednostki_godzin++; // zwiększ licznik jednostek godzin o 1
            if((dziesiatki_godzin == 2) && (jednostki_godzin == 4)) // jeżeli jest północ to
              {
              dziesiatki_godzin = jednostki_godzin = 0; // zeruj licznik dziesiątek i jednostek godzin
              }
            if(jednostki_godzin == 10) // jeśli licznik jednostek godzin osiągnął wartość 10 to
              {
              jednostki_godzin = 0; // wyzeruj licznik jednostek godzin
              dziesiatki_godzin++; // zwiększ licznik dziesiątek godzin o 1
              }
            }
          }
        }
      }
    }

    sprintf (czas,"%d%d:%d%d:%d%d",dziesiatki_godzin, jednostki_godzin, dziesiatki_minut, jednostki_minut, dziesiatki_sekund, jednostki_sekund);

    LCD_WriteText(czas);
    }
    // Program główny
    int main(void)
    {
    // konfiguracja portów I/O
       DDRA = 0x00;
       DDRB = 0xF0;
       DDRC = 0x7F;
       DDRD = 0x76;
       PORTA = 0x03;
       PORTB = 0xEF;
       PORTC = 0xFF;
       PORTD = 0x00;

    // ustawienie trybu pracy licznika

    LCD_Initalize();


    TCCR0 = 0x04;
    TCCR1B = 0x03;

    // wpisanie wartości początkowej
    TCNT0 = 128;
    // odblokowanie przerwania od licznika
    TIMSK = 130;



    sei();// globalne odblokowanie przerwań

    while(1);
    return 0;

    // pusta pętla nieskoczona


    }

    0
  • #9 01 Sie 2008 12:46
    Balu
    Poziom 38  

    Ta procedura w ISRze na pewno zdąża się wykonać cała? Może lepiej w ISRze ustawiać jakąś flagę, a w głównej pętli odświeżać po zmianie flagi?

    Łukasz

    0
  • #10 01 Sie 2008 12:47
    arachno
    Poziom 9  

    ale jak to zrobic?

    0
  • #11 01 Sie 2008 12:48
    Balu
    Poziom 38  

    To ja piszę program? Czy Ty?
    Dodać jedną zmienną globalną... ustawiać ją w ISRze a w pętli głównej if (zm)
    {zm=0;
    refresh_lcd...;
    }

    0
  • #12 01 Sie 2008 18:23
    greatlukas
    Poziom 13  

    a gdzie masz zadeklarowane PORT'y do LCD?
    LCD_DB4,5,6,7 i DDR'y, domyślam sie że w HD44780.h, ale wole zapytać :)
    Sprawdź czy napewno dobrze mas podefiniowane porty.
    Jezeli jest to zegar, do domyślam sie że przerwanie jest co 1s, także w ISR powinno sie zmieścić, ale takich rzeczy lepiej nei robić.

    dodaj sobie jakąś nową zmienną, np bitową, a w ISR ustawiaj tą zmienną, a w pętli głównej sprzwdzaj czy jest ona ustawiona, jeżeli tak, to wykonuj aktualizuj_czas(); a nastęnie wyzeruj tę nowo dodaną zmienną :)

    PS. udało Ci sie wcześniej coś wyświetlić na tym LCD?? moze masz kontrast źle ustawiony?

    0
  • #13 11 Sie 2008 17:13
    arachno
    Poziom 9  

    przecież pisałam że wszystko było wcześniej w porządku, wszystko uruchomione, prosty błąd się wkradał gdzieś bez przerwy, w końcu ruszyło( oczywiście wcześniej ale zapomniałam umieścić tu rozwiązania):


    Code:
    unsigned int rtc_sec=0;            //zmienne globalne
    

    void rtc_init(void)
    {
    ASSR=1<<AS2;                    // RTC clock from 32kHz crystal
    TCNT2=0;
    OCR2=((32768/1024)-1);;           
    TCCR2=_BV(WGM21)|7;             // Clear Timer on Compare match
    TIMSK|=_BV(OCIE2);                // Enable timer2 compare-match interrupt
    }


    ISR(TIMER2_COMP_vect)
    {
    ++rtc_sec;
    }


    Code:

    char dziesiatki_sekund = 0,
       jednostki_minut = 0,
       dziesiatki_minut = 0,
       jednostki_godzin = 0,
       dziesiatki_godzin = 0;


    void aktualizuj_czas(void)
    {
    unsigned char czas[9];
    if(rtc_sec == 60) // jeśli licznik jednostek sekund osiągnął wartość 10 to
    {
    rtc_sec = 0; // wyzeruj licznik jednostek sekund
    jednostki_minut++; // zwiększ licznik jednostek minut o 1

    if(jednostki_minut = 10)
    {
    sprintf (czas,"%d%d:%d%d",dziesiatki_godzin, jednostki_godzin, dziesiatki_minut, jednostki_minut);
    LCD_GoTo(5,1);
    LCD_WriteText(czas);
    }
    if(jednostki_minut == 10) //jeśli licznik jednostek minut osiągnął wartość 10 to
    {
    jednostki_minut = 0; // wyzeruj licznik jednostek minut
    dziesiatki_minut++; // zwiększ licznik dzieisątekminut o 1
    sprintf (czas,"%d%d:%d%d",dziesiatki_godzin, jednostki_godzin, dziesiatki_minut, jednostki_minut);
    LCD_GoTo(5,1);
    LCD_WriteText(czas);
    if(dziesiatki_minut == 6) // jeśli licznik dziesiątek minut osiągnął wartość 6 to
    {
    dziesiatki_minut = 0; // wyzeruj licznik dziesiątek minut
    jednostki_godzin++;     // zwiększ licznik jednostek godzin o 1
    if(jednostki_godzin == 10) // jeśli licznik jednostek godzin osiągnął wartość 10 to
    {
    jednostki_godzin = 0; // wyzeruj licznik jednostek godzin
    dziesiatki_godzin++; // zwiększ licznik dziesiątek godzin o 1
    }
    }
    }
    }

    return;
    }



    i oczywiście w odpowiednim miejscu, w którym potrzebowałam rozruchu zegara:

    Code:
    rtc_init();                        // inicjalizacja RTC
    
    sei();                           // globalne odblokowanie przerwań


    wszystkim bardzo dziękuję za pomoc, w szczególności Balu

    0