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.

Timer0 - TIMER0 AVR C - jak ustawić rejestry?

mateusz19955 11 Mar 2014 18:23 3006 39
  • #1 11 Mar 2014 18:23
    mateusz19955
    Poziom 13  

    Witam, uczę się programowania w języku c++ na avr i mam problem z timerem0.
    Jak skonfigurować jego rejestry aby timer ten działał?

    Mam coś takiego ale to tryb ctc i nie działa mi na atmedze8

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Chciałbym aby przerwanie było generowane co 2ms.
    Jak to zrobić?
    A i czy ten wektor przerwania będzie dobry:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0 29
  • #2 11 Mar 2014 18:26
    Freddie Chopin
    Specjalista - Mikrokontrolery

    mateusz19955 napisał:
    uczę się programowania w języku c++

    Sorry, ale muszę się wtrącić, bo to chyba jakaś plaga zaraz będzie... Wszelkim osobom które chcą użyć skrótu "C++" w tytule proponuję zapoznanie się, czym się różni C od C++ i czym różni się programowanie tzw. proceduralne (C) od obiektowego (C++).

    4\/3!!

    0
  • #3 11 Mar 2014 18:28
    mateusz19955
    Poziom 13  

    Ok, ale umiesz to zrobić?

    0
  • #4 11 Mar 2014 18:48
    gaskoin
    Poziom 38  

    Pewnie nie umie tylko tak cwaniakuje.

    A powiesz nam jakiego µC używasz, czy mamy zgadywać ?

    0
  • #5 11 Mar 2014 18:53
    mateusz19955
    Poziom 13  

    Atmega8 przecież jest napisane.

    0
  • #7 11 Mar 2014 19:09
    Freddie Chopin
    Specjalista - Mikrokontrolery
  • #8 11 Mar 2014 19:10
    tadzik85
    Poziom 38  

    Freddie Chopin napisał:
    mateusz19955 napisał:
    Atmega8 przecież jest napisane.

    Ciekawe gdzie...

    4\/3!!


    Zaraz nad 1 listingiem :idea:

    0
  • #9 11 Mar 2014 19:22
    mateusz19955
    Poziom 13  

    Ok, wektor to był by ten:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Ale te rejestry nadal nie wiem jak ustawić.

    0
  • #10 11 Mar 2014 19:42
    gaskoin
    Poziom 38  

    To zajrzyj do manuala, bo nawet nie wiemy co chcesz osiągnąć

    0
  • #11 11 Mar 2014 20:36
    mateusz19955
    Poziom 13  

    chciałbym zrobić przerwanie, które co 2ms będzie mi wywoływało jakąś funkcję

    Dodano po 22 [minuty]:

    Napisze mi ktoś jak ustawić te rejestry?

    Dodano po 25 [minuty]:

    Dobra tak, może być:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Preskaler: 64
    Częstotliwość kwarcu: 8MHz.

    Nie wiem tylko czy TCNT0 = 6 dobże napisałem.
    Do czego służy to TCNT0?

    0
  • #12 11 Mar 2014 20:52
    gaskoin
    Poziom 38  

    http://www.atmel.com/images/atmel-2486-8-bit-avr-microcontroller-atmega8_l_datasheet.pdf napisał:
    TCNT0 - The Timer/Counter Register gives direct access, both for read and write operations, to the Timer/Counter unit 8-bit counter.

    0
  • #13 11 Mar 2014 20:56
    mateusz19955
    Poziom 13  

    To jest to co OCR0?
    Rejestr przepełnienia?

    0
  • #14 11 Mar 2014 21:17
    gaskoin
    Poziom 38  

    Nie ma takiego rejestru w m8. To jest wartość licznika

    0
  • #15 11 Mar 2014 21:18
    mateusz19955
    Poziom 13  

    No, to jak ustawić ten timer?

    0
  • #16 11 Mar 2014 21:47
    dondu
    Moderator Mikrokontrolery Projektowanie

    Zacznij od schematu Timer0 w Twoim mikrokontrolerze.
    Następnie zobacz schemat preskalera - jest w innym miejscu datasheet.
    Kolejnym krokiem jest opis rejestrów timer0.
    Dopiero wtedy kombinuj z wyborem trybu i ustawieniami rejestrów.

    Nie pisz programu, tylko napisz jak ustawiłbyś rejestry, by osiągnąć swój cel, a my Ci powiemy, czy dobrze kombinujesz.

    0
  • #17 11 Mar 2014 21:49
    mateusz19955
    Poziom 13  

    Ok, tak zrobię i jutro napisze.

    0
  • #18 12 Mar 2014 14:36
    mateusz19955
    Poziom 13  

    Kombinowałem ale nadal nie wiem jak to zrobić.
    Chciałbym aby dioda migała mi co 1s.

    To kod który napisałem, ale nie działa:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Co tu jest źle?

    0
  • #19 12 Mar 2014 14:53
    gaskoin
    Poziom 38  

    To, że wpisujesz zawsze za każdym razem stałą wartość do PORTD. Nikt Ci nie powie jak to zrobić bo nikt nie zna taktowania Twojej Atmegi

    0
  • #20 12 Mar 2014 14:56
    mateusz19955
    Poziom 13  

    No, taktowanie wewnętrznym oscylatorem 8MHz

    0
  • #21 12 Mar 2014 15:09
    gaskoin
    Poziom 38  

    Więc Twój zegar ma 8MHz = 8000khz = 8000000 Hz.
    Ustawiłeś prescaler na 256, więc timer0 jest taktowany zegarem 31250Hz. Oznacza to, że tyle naliczy w ciągu sekundy. Ponieważ Twój timer jest 8 bitowy, jego max wynosi 255. To znaczy, że w ciągu sekundy będziesz miał 122 przerwania. Możesz do tylu inkrementować zmienną, po czym zmieniać stan na PORTD (póki co jest zawsze stały). Prościej ustawić TIMER1 niż tak kombinować (bo jest 16 bitowy). W nocie masz wszystko opisane, nie wiem czemu błądzisz po ciemku, skoro tam jest jak krowie na rowie. Można też ustawić jego wyjście na nóżkę procesora. Wtedy nawet obsługi przerwania nie potrzebujesz.

    0
  • #22 12 Mar 2014 15:41
    mateusz19955
    Poziom 13  

    Czyli tak to ma wyglądać?
    Też nie działa.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Dobrze są ustawione te rejestry na początku programu?

    Dodano po 26 [minuty]:

    Niech ktoś napisze mi ten kod, a ja bym sobie go przeanalizował.
    Łatwiej mi będzie się w ten sposób nauczyć.

    0
  • #23 12 Mar 2014 15:53
    Wojtek75
    Poziom 23  

    mateusz19955 napisał:
    Też nie działa.

    Jeszcze pętla główna w funkcji "main" i już jesteś w domu.

    0
  • #24 12 Mar 2014 16:01
    mateusz19955
    Poziom 13  

    Kurde, nadal nie działa.
    Dałem pętlę while(1) w main i dioda nadal nie miga.

    0
  • #25 12 Mar 2014 16:09
    tehaceole

    Poziom 28  

    mateusz19955 za przeproszeniem od zadu strony się za to zabierasz. Najpierw poczytaj trochę o operacjach bitowych w AVR. Pobaw się w miganie diodą z użyciem zwykłego delayms(). Jak będziesz miał pewność co do działania tego fragmentu programu to dopiero idź dalej: dodaj obsługę timera. To co chcesz najprościej jest zrobić ustawiając timer w tryb CTC.

    I przede wszystkim: NOTA KATALOGOWA JEST PO TO, ABY JĄ CZYTAĆ... Nota to absolutna podstawa przy zabawach z peryferiami.

    Chcesz przeanalizować... Więc proszę: taka mała lektura. :)
    Powodzenia

    0
  • #26 12 Mar 2014 16:18
    Wojtek75
    Poziom 23  

    mateusz19955 napisał:
    Kurde, nadal nie działa.

    Daj aktualny kod. Jak masz ustawioną optymalizację?

    0
  • #27 12 Mar 2014 16:27
    gaskoin
    Poziom 38  

    Tam nie ma nic co można by zoptymalizować :)

    0
  • #28 12 Mar 2014 16:28
    mateusz19955
    Poziom 13  

    Z _delay_ms bawiłem się już i wiem jak to działa.
    W języku C pisałem już i operacje bitowe też przerabiałem.
    Mam tylko problem z ustawieniem tego timera.
    Notę katalogową też czytam, ale nic z niej nie rozumiem.
    Piszemy już tyle postów i nikt jak na razie mi nie napisał jak poprawnie to skonfigurować.
    Naprawdę szybciej było by jakby ktoś napisał mi ten kod a ja bym go wtedy na pewno zrozumiał.
    Ja zawsze się tak uczę, i sporo się już w taki sposób nauczyłem.
    Dla was to na pewno proste zadanie a ja chciałbym się nauczyć obsługi przerwań.
    Atmega8 na Timer0 nie ma CTC (chyba?).
    Więc proszę nie złośćcie się że idę na prościznę, prosząc was o napisanie gotowca, ale to na prawdę mi bardziej pomoże.

    0
  • #29 12 Mar 2014 17:34
    gaskoin
    Poziom 38  

    mateusz19955 napisał:
    Atmega8 na Timer0 nie ma CTC (chyba?).


    A czemu nie możesz użyć innego timera?

    0
  • #30 12 Mar 2014 17:47
    Wojtek75
    Poziom 23  

    Co do optymalizacji to w sumie racja nie jest potrzebna.

    Kod z posta nr. 12 jeżeli poprawnie dopisałeś pętle w funkcji main jest poprawny (dioda na PD7 powinna dać oznaki życia). Skoro nie działa to szukaj błędu gdzie indziej.

    0