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

Zegar binarny na na mikroprocesorze Atmega8

joboo 16 Lut 2009 17:29 102111 171
  • #151
    jokerrro
    Poziom 11  
    Witam!! czy jeżeli bym chciał zrezygnować z wyświetlania jedności sekund to wystarczy ze usunę te 4 diody i tranzystor za nie odpowiedzialny?? czy coś jeszcze trzeba zmienić?? z góry dzięki za odpowiedz. pozdrawiam
    Potrafisz napisać podobny artykuł? Wyślij do mnie a otrzymasz kartę SD 64GB.
  • PCBway
  • #152
    CzarleeSheen
    Poziom 2  
    Wykonałem takie cudo wg shematu.Płytka może nie wygląda najlepiej,ale ze względu na prostotę układu nie chciałem jej frezować więc użyłem jakiejś uniwersalnej. Miłej zabawy.

    Link
  • #153
    osvch
    Poziom 12  
    Witam, mógłbym prosić o szczegółowe opisanie jakie fuse bity ustawić w bascomie? I jeśli można prosze o podanie działającego programu do zegara napędzanego przez kwarc 16MHz :) Pzdr.
  • #154
    halish
    Poziom 9  
    Witam,
    zastanawiam się nad samodzielnym zaprojektowaniem takiego zegarka, także przy pomocy Atmega8. Będzie to jednak mój pierwszy projekt w procesorach (i w elektronice w ogóle), w związku z tym mam kilka pytań.

    O ile dobrze zrozumiałem kod w Bascomie (piszę w C), to sterowanie odbywa się poprzez wyświetlanie wiersz po wierszu co 4ms, co daje przeciętnie 1ms na wiersz. Takie małe czasy sprawiają, że wydaje sie, że diody świecą światłem ciągłym. Bardzo proszę o ewentualne poprawienie mojego rozumowania.

    Jeżeli sterujemy pinami, to w jakim celu podłączone są tranzystory BC557? Próbowałem podłączać pojedynczą diodę do dwóch pinów uC, z których jeden był ustawiony na 0, a drugi na 1, i dioda się świeciła. Bardzo proszę o wyjaśnienie tego.

    Pozdrawiam,
    Mateusz Haligowski
  • PCBway
  • #155
    osvch
    Poziom 12  
    Tranzystory są po to aby nie spalić ATMEGI za dużym prądem pobieranym przez diody, tranzystory dużo nie kosztują a lepiej je mieć niż tracić pieniądze na zakup nowego procka.
  • #156
    CzarleeSheen
    Poziom 2  
    wsad do programu jest na elektrodzie.drakerus na drugiej stronie forum zamieścił grzecznie cały wsad.Wystarczy wrzucić go do atmegi i ustawić jaki zegar sobie życzymy...czy zewnętrzny czy też wewnętrzny (chodzi tu oczywiście o 4MHz) . To jaki ma być zegar ustalamy za pomocą programu AVR8_Burn-O-Mat 2.0.1. Osobiście polecam zastosowanie zegaru zwenętrznego bo wewnętrzny późni się mocno! Przez to "mocno" rozumiem 1min na godz! Na filmiku powyżej jest też zegarek kwarcowy,tyle, że pod płytką.
    Nie wiem jak założycielowi tematu udało się wystartować za pomocą jego programu, gdyż jest on wadliwy.
  • #157
    FiNS
    Poziom 2  
    halish napisał:

    O ile dobrze zrozumiałem kod w Bascomie (piszę w C), to sterowanie odbywa się poprzez wyświetlanie wiersz po wierszu co 4ms, co daje przeciętnie 1ms na wiersz.


    Ja ten kod rozumiem tak, ze wyswietlana jest co 4ms kolumna po kolumnie, a nie wiersz po wierszu. W danym momencie na porcie C mamy jedynki, tylko na jednym pinie z portu C jest 0. Wybieramy wiec kolejno kazda z kolumn (np jednosci minut). Natomiast na porcie D ustawiamy piny w taki sposob ze dajemy 0 na tym pinie ktory jest polaczony z dioda ktora w wybranej kolumnie ma sie w danym momencie zapalic. Jednak nie programuje w bascomie, wiec prosze aby ktos potwierdzil, czy jest tak jak napisalem.
  • #158
    trzaska456
    Poziom 17  
    Witam...
    zaczołem robić ten zegarek całkiem niedawno i cały czas niedziała niemaiałem tranzystorów BC557 to
    wstawiłem BC556 (z notówynika że różnią się tylko napięciem) Czy to będzie działać to pierwsza sprawa ;-)
    Stosuje Atmega8L-8PU i wrzucam *.hex za pomocą AVR Studio 4.14 wedug wstawki joboo i rezonator 16MHz (to z 2 nózkami) a jeśli chodzio generator to mam tylko 32 MHz i niekojarze oco chodzi z tymi fusebitamiSSS
    Prosze o pomoc i zgóry dziękuje
    pozdrowienia trzaska456
  • #159
    FiNS
    Poziom 2  
    Witam. Czy ktos moze powiedziec jakich dokladnie uzyl tranzystorow, na schemacie pisze tylko BC557 a do wyboru mam BC557A, BC557B i BC557C z roznym wzmocnieniem pradowym i nie wiem ktory wybrac. Jaki prad moze maksymalnie wplywac na pojedynczy pin AVR'a? Jezeli dobrze rozumiem to ten uklad dziala tak, ze jezeli w kolumnie swiecimy tylko jedna diode, to caly prad z tranzystora (dajmy na to 100mA) poplynie tylko przez nia do jednego pinu AVR'a, natomiast jesli swieci sie kilka diod w kolumnie to prad rozplynie sie do avr na kilka pinow (np przy czterech swiecacych diodach 4x 25mA). Jaki wiec prad maksymalnie moze tam poplynac na jeden pin przy swieceniu tylko jednej diody w kolumnie zeby AVR to wytrzymal?
  • #160
    trzaska456
    Poziom 17  
    ja wlutowałem z jakiejś płyty BC557B nie wiem czy są ok ale myślę że typ B lub C starczy i tak to te same tranzystory tylko o innej wartości
  • #161
    trzaska456
    Poziom 17  
    ok zegarek działa ale chcę się jeszcze pobawić no i nie wiem gdzie ustawia się te fusebit-y
    Proszę o pomoc
  • #162
    wlw_wl
    Poziom 38  
    trzaska456:
    Atmega8L obsługuje maksymalnie 8MHz taktowania zewnętrznego więc albo zmień rezonator albo Atmegę, najwięcej co możesz podać to 16MHz dla Atmega8 (bez L) 16PU (np.). Fusebity w tym przypadku ustawiasz po to, żeby "powiedzieć" prockowi z jakiego zegara ma korzystać, jak masz generator to 0000 (external clock), resztę masz objaśnioną na pierwszych stronach tematu. Ustawia się je w Bascomie po skompilowaniu programu w programatorze na zakładce Lock And Fuse Bits, było wytłumaczone dokładnie gdzie i co.

    FiNS
    Ja użyłem BC557C, ale wzmocnienie prądowe nie ma tutaj znaczenia bo tranzystory w tym układzie pracują jako klucze, tzn. wyłącznie w stanie zatkania lub nasycenia. Co do prądu to Atmega8 dzierży chyba do 200mA, na upartego ten układ mógłby działać bez tranzystorów z diodami bezpośrednio podpiętymi do procka, ale tak jest ładniej i ciekawiej (czyt. bezpieczniej). Poza tym raczej nie doczekasz godziny typu 39:79:79 więc ilość świecących naraz diód jest ograniczona.

    Natomiast ja mam wspomniany wczesniej problem, niektóre diody się nie wygaszają - lekko żarzą. Układ zasilam 12V przez stabilizator 7805 więc 5V powinno tam być, a zjawisko niewygaszonych diód to podobno objaw zbyt niskiego napięcia na procku.
    Jakaś inna możliwa przyczyna tego zjawiska?
  • #163
    Andrzej_01
    Poziom 10  
    Witam!
    Wykonałem ten zegarek lecz mam kilka problemów.
    1) Wsad drakerus'a zmodyfikowałem tak jak polecił kolega berq na 16MHz:
    $crystal = 16000000 i Config Timer1 = Timer , Prescale = 256, lecz zegarek 10 sekund zlicza w normalne 3 sekundy. Nie znam się na językach programowania ale zauważyłem że jak zmieniłem jeszcze w tym programie Timer1 = 3036 na Timer1 = 12144 to zegarek 10 sekund zlicza w normalne 8 sekund.
    Co mam zmienić żeby 1 sekunda trwała 1 sekundę?
    2) Fusebity ustawiłem w bascomie tak:
    BODLEVEL = 0
    BODEN = 1
    WORDS BOOT SIZE = 1024
    i bity 1110 sut 11
    oraz CKOPT = 1 ( wyczytałem że wartość 0 włącza obsługę Atmegi8 do 16MHz. Tak też miałem, ale gdy zegarek przyspieszał to zmieniłem. Nic to jednak nie dało)


    Proszę o szybką odpowiedź jak to mam ustawić, oraz co robię źle.
    Pozdrawiam.
  • #165
    DJ MHz
    Poziom 24  
    Witam.
    Też zmontowałem ten układzik. Koszt 10 zł (tyle atmega8) reszte miałem w domowym zaciszu. Po zmianie fusebitów oczywiście atmega padła :) dałem na generator, a mam wmontowany kwarc. Musiałem więc kupic za 1,5 zł 74HC14 żeby ją pobudzić.

    Soft drakona oczywiście, ponieważ ten pierwszy wogóle nie działał.
    Teraz zegarek ładnie śmiga na kwarcu 4 MHz zewnetrznym, pokazuje dokładnie.

    Pod linkiem filmik z działania zegara.

    Link
  • #166
    yaroray
    Poziom 9  
    Zrobiłem swój układ oraz napisałem program i zegar się spóźnia ok 6,5s na dobę. Zarówno wyświetlanie na diodach, jak i odliczanie czasu jest zrobione na przerwaniach od liczników. Nie mogę doszukać się gdzie jest błąd. Czy mógłby ktoś znający się na rzeczy rzucić okiem na mój kod? Jest dosyć dobrze opisany, więc nie powinno być problemu ze zrozumieniem. Byłbym bardzo wdzięczny.

    Code:

    #define F_CPU 16000000UL
    #include <avr/io.h>
    #include <util/delay.h>   
    #include <avr/interrupt.h>

    void delay_ms(int ms)
    {
       while (ms--)
       {
          _delay_ms(1);
       }
    }

    void delay_us(int us)
    {
       while (us--)
       {
          _delay_us(1);
       }
    }

    char sek_jed = 0b00000000;
    char sek_dzies = 0b00000000;
    char min_jed = 0b00000000;
    char min_dzies = 0b00000000;
    char godz_jed = 0b00000000;
    char godz_dzies = 0b00000000;

    char linia = 0b00000001;

    void konfiguracja (void)
    {
    //Wejscia
       DDRC &= ~_BV(5); //przycisk godz.
       DDRC &= ~_BV(4); //przycisk min.
       DDRC &= ~_BV(3); //przycisk sek.

    //Pull-ups on inputs
       PORTC|=_BV(5);
       PORTC|=_BV(4);
       PORTC|=_BV(3);

    //Outputs
       DDRD|=_BV(5); //dioda 8
       DDRD|=_BV(6); //dioda 4
       DDRD|=_BV(7); //dioda 2
       DDRB|=_BV(0); //dioda 1

       DDRB|=_BV(1); //tranzystor sek. jed.
       DDRB|=_BV(2); //tranzystor sek. dz.
       DDRB|=_BV(3); //tranzystor min. jed.
       DDRB|=_BV(4); //tranzystor min. dz.
       DDRB|=_BV(5); //tranzystor godz. jed.
       DDRC|=_BV(0); //tranzystor godz. dz.

       TCCR1B = 0b0000100; //preskaler licznika 1 - 256
       TCNT1 = 3036; //wartosc poczatkowa licznika (do zliczenia 62500 impulsow)
    //   TIMSK = 0b00000100; //wlaczenie przerwania przepelnienia licznika 1

       TCCR0 = 0b00000101;
       TCNT0 = 224; ////wartosc poczatkowa licznika (do zliczenia 32 impulsow (512us))
       TIMSK = 0b00000101; //wlaczenie przerwania przepelnienia licznika 0 i 1
    }

    void czas (void)
    {
       sek_jed++;

       if (sek_jed == 0b00001010)
       {
          sek_jed = 0b00000000;
          sek_dzies++;
       
          if (sek_dzies == 0b0000110)
          {
             sek_dzies = 0b00000000;
             min_jed++;
             
             if (min_jed == 0b00001010)
             {
                min_jed = 0b00000000;
                min_dzies++;
       
                if (min_dzies == 0b00000110)
                {
                   min_dzies = 0b00000000;
                   godz_jed++;
       
                   if ((godz_dzies == 0b00000010)&&(godz_jed == 0b00000100))
                   {
                      godz_dzies = 0b00000000;
                      godz_jed = 0b00000000;
                   }
                   else if (godz_jed == 0b00001010)
                   {
                      godz_jed = 0b00000000;
                      godz_dzies++;
                   }
                }
             }
          }
       }
    }

    void wyswietl (void)
    {

       if (linia == 0b00000001)
       {
          PORTB &= ~_BV(0); //1
          PORTD |= ~_BV(7); //2
          PORTD |= ~_BV(6);   //4   
          PORTD |= ~_BV(5);   //8

          if (bit_is_set(sek_jed, 0))
          {
             PORTB &= ~_BV(1);
          }
          else
          {
             PORTB |= _BV(1);
          }

          if (bit_is_set(sek_dzies, 0))
          {
             PORTB &= ~_BV(2);
          }
          else
          {
             PORTB |= _BV(2);
          }

          if (bit_is_set(min_jed, 0))
          {
             PORTB &= ~_BV(3);
          }
          else
          {
             PORTB |= _BV(3);
          }

          if (bit_is_set(min_dzies, 0))
          {
             PORTB &= ~_BV(4);
          }
          else
          {
             PORTB |= _BV(4);
          }

          if (bit_is_set(godz_jed, 0))
          {
             PORTB &= ~_BV(5);
          }
          else
          {
             PORTB |= _BV(5);
          }

          if (bit_is_set(godz_dzies, 0))
          {
             PORTC &= ~_BV(0);
          }
          else
          {
             PORTC |= _BV(0);
          }
       }

       else if (linia == 0b00000010)
       {
          PORTB |= _BV(0); //1
          PORTD &= ~_BV(7); //2
          PORTD |= _BV(6);   //4   
          PORTD |= _BV(5);   //8

          if (bit_is_set(sek_jed, 1))
          {
             PORTB &= ~_BV(1);
          }
          else
          {
             PORTB |= _BV(1);
          }

          if (bit_is_set(sek_dzies, 1))
          {
             PORTB &= ~_BV(2);
          }
          else
          {
             PORTB |= _BV(2);
          }

          if (bit_is_set(min_jed, 1))
          {
             PORTB &= ~_BV(3);
          }
          else
          {
             PORTB |= _BV(3);
          }

          if (bit_is_set(min_dzies, 1))
          {
             PORTB &= ~_BV(4);
          }
          else
          {
             PORTB |= _BV(4);
          }

          if (bit_is_set(godz_jed, 1))
          {
             PORTB &= ~_BV(5);
          }
          else
          {
             PORTB |= _BV(5);
          }

          if (bit_is_set(godz_dzies, 1))
          {
             PORTC &= ~_BV(0);
          }
          else
          {
             PORTC |= _BV(0);
          }
       }

       else if (linia == 0b00000100)
       {
          PORTB |= _BV(0); //1
          PORTD |= _BV(7); //2
          PORTD &= ~_BV(6);   //4   
          PORTD |= _BV(5);   //8

          if (bit_is_set(sek_jed, 2))
          {
             PORTB &= ~_BV(1);
          }
          else
          {
             PORTB |= _BV(1);
          }

          if (bit_is_set(sek_dzies, 2))
          {
             PORTB &= ~_BV(2);
          }
          else
          {
             PORTB |= _BV(2);
          }

          if (bit_is_set(min_jed, 2))
          {
             PORTB &= ~_BV(3);
          }
          else
          {
             PORTB |= _BV(3);
          }

          if (bit_is_set(min_dzies, 2))
          {
             PORTB &= ~_BV(4);
          }
          else
          {
             PORTB |= _BV(4);
          }

          if (bit_is_set(godz_jed, 2))
          {
             PORTB &= ~_BV(5);
          }
          else
          {
             PORTB |= _BV(5);
          }

          if (bit_is_set(godz_dzies, 2))
          {
             PORTC &= ~_BV(0);
          }
          else
          {
             PORTC |= _BV(0);
          }
       }

       else if (linia == 0b00001000)
       {
          PORTB |= _BV(0); //1
          PORTD |= _BV(7); //2
          PORTD |= _BV(6);   //4   
          PORTD &= ~_BV(5);   //8

          if (bit_is_set(sek_jed, 3))
          {
             PORTB &= ~_BV(1);
          }
          else
          {
             PORTB |= _BV(1);
          }

          if (bit_is_set(sek_dzies, 3))
          {
             PORTB &= ~_BV(2);
          }
          else
          {
             PORTB |= _BV(2);
          }

          if (bit_is_set(min_jed, 3))
          {
             PORTB &= ~_BV(3);
          }
          else
          {
             PORTB |= _BV(3);
          }

          if (bit_is_set(min_dzies, 3))
          {
             PORTB &= ~_BV(4);
          }
          else
          {
             PORTB |= _BV(4);
          }

          if (bit_is_set(godz_jed, 3))
          {
             PORTB &= ~_BV(5);
          }
          else
          {
             PORTB |= _BV(5);
          }

          if (bit_is_set(godz_dzies, 3))
          {
             PORTC &= ~_BV(0);
          }
          else
          {
             PORTC |= _BV(0);
          }
       }
       
       if (linia == 0b00000001)
       {
          linia = 0b00000010;
       }
       else if (linia == 0b00000010)
       {
          linia = 0b00000100;
       }
       else if (linia == 0b00000100)
       {
          linia = 0b00001000;
       }
       else if (linia == 0b00001000)
       {
          linia = 0b00000001;
       }

    }

    void przycisk_godz (void)
    {
       static int licz_godz = 0;
       static char licz_godz_flag = 0;

       if (bit_is_clear(PINC,5))
       {
          licz_godz++;
          if (licz_godz_flag == 0)
          {
             licz_godz_flag = 1;

             godz_jed++;
             if ((godz_jed == 0b00000100)&&(godz_dzies == 0b00000010))
             {
                godz_jed = 0b00000000;
                godz_dzies = 0b00000000;
             }
             else if (godz_jed == 0b00001010)
             {
                godz_jed = 0b00000000;
                godz_dzies++;
             }
          }
          else if ((licz_godz == 300)&&(licz_godz_flag == 1))
          {
             licz_godz = 0;
             licz_godz_flag = 2;

             godz_jed++;
             if ((godz_jed == 0b00000100)&&(godz_dzies == 0b00000010))
             {
                godz_jed = 0b00000000;
                godz_dzies = 0b00000000;
             }
             else if (godz_jed == 0b00001010)
             {
                godz_jed = 0b00000000;
                godz_dzies++;
             }
          }
          else if ((licz_godz == 30)&&(licz_godz_flag == 2))
          {
             licz_godz = 0;

             godz_jed++;
             if ((godz_jed == 0b00000100)&&(godz_dzies == 0b00000010))
             {
                godz_jed = 0b00000000;
                godz_dzies = 0b00000000;
             }
             else if (godz_jed == 0b00001010)
             {
                godz_jed = 0b00000000;
                godz_dzies++;
             }
          }         
       }
       else
       {
          licz_godz = 0;
          licz_godz_flag = 0;
       }
    }

    void przycisk_min (void)
    {
       static int licz_min = 0;
       static char licz_min_flag = 0;

       if (bit_is_clear(PINC,4))
       {
          licz_min++;
          if (licz_min_flag == 0)
          {
             min_jed++;
             licz_min_flag = 1;
             if (min_jed == 0b00001010)
             {
                min_jed = 0b00000000;
                min_dzies++;
                if (min_dzies == 0b00000110)
                {
                   min_dzies = 0b00000000;
                }
             }
          }
          else if ((licz_min == 300)&&(licz_min_flag == 1))
          {
             licz_min = 0;
             min_jed++;
             licz_min_flag = 2;
             if (min_jed == 0b00001010)
             {
                min_jed = 0b00000000;
                min_dzies++;
                if (min_dzies == 0b00000110)
                {
                   min_dzies = 0b00000000;
                }
             }
          }
          else if ((licz_min == 30)&&(licz_min_flag == 2))
          {
             licz_min = 0;
             min_jed++;
             if (min_jed == 0b00001010)
             {
                min_jed = 0b00000000;
                min_dzies++;
                if (min_dzies == 0b00000110)
                {
                   min_dzies = 0b00000000;
                }
             }
          }
       }
       else
       {
          licz_min = 0;
          licz_min_flag = 0;
       }
    }

    void przycisk_sek (void)
    {
       if (bit_is_clear(PINC,3))
       {
          sek_jed = 0b00000000;
          sek_dzies = 0b00000000;
          TCNT1 = 3036; //wartosc poczatkowa licznika (do zliczenia 62500 impulsow)
       }   
    }

    SIGNAL (SIG_OVERFLOW0)
    {
       TCNT0 = 224; //wartosc poczatkowa licznika (do zliczenia 32 impulsow (512us))
       wyswietl(); // wyswietlenie czasu na diodach
       przycisk_godz(); //przycisk ustawiajacy godziny
       przycisk_min(); //przycisk ustawiajacy minuty
       przycisk_sek(); //przycisk ustawiajacy (zerujacy) sekundy
    }

    SIGNAL (SIG_OVERFLOW1)
    {
       TCNT1 = 3036; //wartosc poczatkowa licznika (do zliczenia 62500 impulsow)
       czas(); //odswiezenie czasu (dodanie sekundy)
    }

    int main(void)
    {
       konfiguracja(); //konfiguracja portow i licznika 1
       sei(); //wlaczenie globalne przerwan

       while(1)
       {
          //asm ("nop");
       }
    }
  • #167
    sirnative
    Poziom 9  
    witam.
    Wiem, że temat już trochę odleżał ale mam nadzieje, że ktoś to jeszcze czyta,
    a mianowicie chodzi mi oto, że zrobiłem układ jak na pierwszej stronie zaprogramowałem atmege, tylko, że w sklepie była tylko ATMega8-l czyli może pracować z zewnętrznym kwarcem 8 Mhz, wiec zmieniłem w programie $fegcrystal 8000000.
    Trzeba zmieniać coś jeszcze? Po wgraniu programu nic sie nie dzieje na diodach wie ktoś może o co chodzi?
  • #168
    wlw_wl
    Poziom 38  
    $fegcrystal? :wink:
    Musisz zmienić prescalery timerów, było o tym pisane już ze czterdzieści razy w tym temacie, racz poczytać.
  • #169
    sirnative
    Poziom 9  
    Już zrobiłem i działa poprawnie ten zegar.
    $fegcrystal błąd podczas pisania chodziło o $crystal
  • #170
    art_es
    Poziom 2  
    witam. temat juz moze nie jest nowy ale dopiero o znalazlem. bardzo mi sie spodobal. i stad moje pytanie. czy zaprogramował by mi ktos taki procek. ja kompletnie sie na tym nie znam. bym był bardzo wdzieczny za pomoc.
  • #171
    victorantonio
    Poziom 9  
    o co chodzi z tym wyświetlaniem multipleksowanym? dana dioda zaświeci jak dam "1" na baze i "1" na kolektor tego tranzystora tak?
  • #172
    Robster
    Poziom 8  
    Witam

    Czy tranzystory:
    BC337-40 NPN 0.A - TO92
    BC327-40 PNP 0.A - TO92
    BD140-16 PNP 1.5A - TO162
    BD139-16 NPN 1.5A - TO162

    znajdą w tym schemacie zastosowanie? Tych pierwszych 2 posiadam po 5 sztuk, kolejnych po 3 sztuki (w schemacie trzeba skorzystać z 6). I zastanawia mnie czy mogę je wykorzystać, czy będę musiał kupić nowe.

    Praktycznie są to całkiem inne tranzystory niż te w schemacie, ale skoro mają pełnić tylko funkcję klucza, to może się nadają.

    Będę wdzięczny za odpowiedź.

    Pozdrawiam