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

[ATtiny2313][avr-gcc] timer0 ctc nie chce współpracować

lekto 25 Maj 2013 11:15 3231 25
REKLAMA
  • #1 12343343
    lekto
    Poziom 35  
    Witam, trafiłem na problem podczas programowania, konkretnie nie udaje mi się uruchomić multipleksowania w przerwaniu. Kod się kompiluje, ładuje do µC ale nie chce działać. Siedzę nad tym od czwartku, robiłem to na podstawie sporej liczby projektów.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    edit 1:
    Po dodaniu funkcja multiplex() jest uruchamiana tylko raz.
  • REKLAMA
  • Pomocny post
    #2 12344512
    dondu
    Moderator na urlopie...
    1: możesz podać argument _delay_ms(1000) zamiast 4 razy wykonywać _delay_ms(250);

    2. W warunkach, dla własnego dobra stosuj nawiasy, by się nie pomylić z priorytetami:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    ale czy jesteś pewien, że chcesz użyć &, czy może && ?
    http://mikrokontrolery.blogspot.com/2011/02/kurs-jezyka-c-spis-tresci.html

    3. Dlaczego używasz liczb binarnych?
  • #3 12344651
    lekto
    Poziom 35  
    1.
    delay.h napisał:
    The maximal possible delay is 262.14 ms / F_CPU in MHz.


    2. Zapamiętam z tymi nawiasami, co do ampersandu to faktycznie błąd ale działało jak jest, oczywiście o tym też będę już pamiętać.

    3. Tymczasowo bym dobrze widział co jest w zmiennych.

    Po zmianie dalej świeci jedna dioda (od dziesiątek godzin).

    Kompiluje to komendą: "avr-gcc main.c -O3"
    Jeśli jest "-O3" to przerwanie jest w tablicy przerwań (sprawdzane za pomocą "avr-objdump -d") i dioda zapala się.
    Przy "-O2", "-O1" i -"O0" przerwanie jest w tablicy ale dioda się nie zapala.
  • #4 12345110
    slx
    Poziom 19  
    Masz tablicę 4 elementową volatile uint8_t czas[4] (indeksy od 0 do 3), a w funkcji multiplex() wystawiasz na PORTB jej piąty element (i przyjmuje wartości od 0 do 4).
    To nie błąd, ale SIGNAL() jest przestarzałe, zamiast tego jest ISR().
    Cytat:
    1. The maximal possible delay is 262.14 ms / F_CPU in MHz.
    Wyrwane z kontekstu, czytałeś ciąg dalszy?
    Cytat:
    3. Tymczasowo bym dobrze widział co jest w zmiennych.
    Jak sobie wolisz. Ale ustawiając rejestry konfiguracyjne, warto korzystać z nazw zdefiniowanych w plikach nagłówkowych.
  • REKLAMA
  • #5 12345220
    lekto
    Poziom 35  
    Z tymi indeksami to znowu moje niedopatrzenie, niestety dalej nie chce to "chodzić".
    Z SIGNAL i ISR kombinowałem i obie wersje nie chciałby działać, zapamiętam to o używaniu ISR.
  • #6 12346509
    dondu
    Moderator na urlopie...
    A propos 1 i tego co napisał kol. slx: http://mikrokontrolery.blogspot.com/2011/04/gcc-avr-funkcje-opoznienia-delay.html
    Swoją drogą odmierzanie czasu za pomocą delay - rozumiem, że to tylko do testów?

    Jeszcze uwaga dot. F_CPU - nie definiuj w kodzie z tych powodów: http://mikrokontrolery.blogspot.com/2011/03/fcpu-gcc-gdzie-definiowac.html

    Stosuj ISR(): http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

    lekto napisał:
    3. Tymczasowo bym dobrze widział co jest w zmiennych.

    Tylko, że kompletnie nie ruzumiem, tych liczb - są "jakieś dziwne" patrz warunek:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod



    lekto napisał:
    Kompiluje to komendą: "avr-gcc main.c -O3"
    Jeśli jest "-O3" to przerwanie jest w tablicy przerwań (sprawdzane za pomocą "avr-objdump -d") i dioda zapala się.
    Przy "-O2", "-O1" i -"O0" przerwanie jest w tablicy ale dioda się nie zapala.

    A dlaczego nie -Os?

    Wklej aktualną wersję po wszystkich poprawkach, skompiluj z -Os i napisz dokładnie jaki jest efekt
  • #7 12346585
    lekto
    Poziom 35  
    Bity 7-4 sterują diodami, 3-0 tranzystorami npn.
    0b00101000 oznacza że ma się zapalić pierwszy segment czyli dziesiątki godzin, i druga dioda znacząca "2". Godzina z jaką zaczyna zegar to 23:28.
    Warunek sprawdza czy dodana właśnie sekunda zmieniła godzinę na 24, jeśli tak to zmienia godzinę na 00.

    Po kompilacji z "-Os" przerwanie jest w tablicy przerwań ale wszystkie diody zgaszone są.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #8 12346667
    dondu
    Moderator na urlopie...
    Zacznijmy od podstaw pisania czytelnych programów. Zamiast liczb bitowych, stosuj przesunięcia i nazwy bitów, co ułatwi Tobie i nam znalezienie błędów: http://mikrokontrolery.blogspot.com/2011/02/kurs-jezyka-c-przesun-bity-lewo.html

    W szczególności stosuj to do rejestrów ustawiających jakieś funkcjonalności mikrokontrolera, czy nazw pinów.
    Przykład: http://mikrokontrolery.blogspot.com/2011/03/led-sterowany-przez-timer.html


    W ten sposób, nie będziemy musieli sięgać do dokumentacji, by sprawdzić czy prawidłowo ustawiłeś, na przykład:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #9 12346733
    lekto
    Poziom 35  
    Robiłem z tymi przesunięciami na początku, ale nie chciało to działać to zacząłem wpisywać binarne wg dokumentacji.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #10 12346794
    dondu
    Moderator na urlopie...
    W trybie timera, który ustawiasz wykorzystujesz tylko jeden z rejestrów OCR zobacz tabelkę: Table 40. Waveform Generation Mode Bit Description
    i ustal który.

    Wykorzystujesz przerwanie z przepełnienia timera. Skoro jednak wykorzystujesz tryb CTC oraz ustawiasz (wprawdzie na razie na maks) rejestr OCR, to domyślam się, że chciałeś wykorzystać przerwania od momentu osiągnięcia przez timer zadanej wartości równej wartości rejestru OCR.

    Jeżeli tak, to nie ten wektor przerwań i nie ta flaga.


    Zamiast dodawania stosuj sumę logiczną:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #11 12346855
    lekto
    Poziom 35  
    Chciałem zrobić multipleksowanie, w książce "Mikrokontrolery AVR, Język C, Podstawy programowania" przeczytałem że do tego używa się trybu CTC i przerwania "TIMER0_COMP_vect".
  • Pomocny post
    #12 12346896
    dondu
    Moderator na urlopie...
    Dlatego właśnie napisałem, że w swoim programie używasz niewłaściwego przerwania.
    Znajdź odpowiednik tego które podałeś wyżej, ale dla ATtiny2313: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

    Do tego właściwą flagę w rejestrze TIMSK.

    I pokaż cały program po tych modyfikacjach.
    Teraz będziesz już na właściwej drodze do sukcesu :)
  • #13 12346989
    lekto
    Poziom 35  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #15 12347005
    lekto
    Poziom 35  
    Przy 0xF0 nic się nie dzieje.
  • REKLAMA
  • #17 12347046
    lekto
    Poziom 35  
    Schematu jako takiego nie ma, jeśli będzie trzeba to mogę go narysować. wszystko jest na płytce stykowej. Z każdego pinu portu B wychodzi rezystor 1k. Piny 7-4 idą na anod, 3-0 idą na bazy tranzystorów BC550C. Między VCC i GDN jest kondensator 100nF.

    Zauważyłem że jest problem z funkcją multiplex(), jeśli jest wywoływana w pętli to świeci tylko segment od dziesiątek godzin, jeśli zmienię "i" na 1 to jedności godzin.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    To powoduje że multipleksowanie działa.
  • #19 12347086
    lekto
    Poziom 35  
    [ATtiny2313][avr-gcc] timer0 ctc nie chce współpracować

    Ta dioda na dole po lewej to prowizoryczna sonda do sprawdzania stanów.
    Mój poprzedni post zedytowałem zanim zdążyłem zauważyć że odpisałeś.


    Funkcja dodaj też nie działa, dopiero jak wkleję ją bezpośrednio to rusza, coś jest gdzieś namieszane...
  • #20 12347205
    dondu
    Moderator na urlopie...
    lekto napisał:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    To powoduje że multipleksowanie działa.

    W takim razie sprawdzać schematu nie będziemy.

    W jakim programie (IDE) kompilujesz kod?
    Pytam ponieważ używasz definicji:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    co jest zbędne - typ mikrokontrolera ustaw w opcjach projektu.

    Czy masz jakieś warninigi - pokaż log po kompilacji.
  • #21 12347225
    lekto
    Poziom 35  
    Nie używam żadnego IDE, avr-gcc, avrdude, motepad++ i MkAvrCalculator do fusebitów.

    avr-gcc main.c -Os -DF_CPU=1000000UL
    
    
    
    avr-objcopy -O ihex a.out o.hex
    
    
    
    avrdude -p t2313 -c usbasp -B 8 -U flash:w:o.hex
    
    avrdude: set SCK frequency to 93750 Hz
    avrdude: AVR device initialized and ready to accept instructions
    
    Reading | ################################################## | 100% 0.02s
    
    avrdude: Device signature = 0x1e910a
    avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
    
             To disable this feature, specify the -D option.
    avrdude: erasing chip
    avrdude: set SCK frequency to 93750 Hz
    avrdude: reading input file "o.hex"
    avrdude: input file o.hex auto detected as Intel Hex
    avrdude: writing flash (316 bytes):
    
    Writing | ################################################## | 100% 0.33s
    
    
    
    avrdude: 316 bytes of flash written
    avrdude: verifying flash memory against o.hex:
    avrdude: load data flash data from input file o.hex:
    avrdude: input file o.hex auto detected as Intel Hex
    avrdude: input file o.hex contains 316 bytes
    avrdude: reading on-chip flash data:
    
    Reading | ################################################## | 100% 0.20s
    
    
    
    avrdude: verifying ...
    avrdude: 316 bytes of flash verified
    
    avrdude: safemode: Fuses OK
    
    avrdude done.  Thank you.
    
    D:\Projekty\zegar binarny>
  • #22 12347250
    dondu
    Moderator na urlopie...
    W takim układzie uprościłbym kod do niezbędnego minimum w celu sprawdzenia multipleksowania:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    a jeżeli nie, to sprawdźmy czy przerwanie w ogóle się wykonuje wywalając z ISR wywołanie funkcji muliplex i wstawiając zmianę stanu jednej z diod na przeciwny.
  • #23 12347278
    lekto
    Poziom 35  
    Cisza, w tablicy przerwań brak przerwania.

    00000000 <__vectors>:
       0:   0c c0           rjmp    .+24            ; 0x1a <__ctors_end>
       2:   27 c0           rjmp    .+78            ; 0x52 <__bad_interrupt>
       4:   26 c0           rjmp    .+76            ; 0x52 <__bad_interrupt>
       6:   25 c0           rjmp    .+74            ; 0x52 <__bad_interrupt>
       8:   24 c0           rjmp    .+72            ; 0x52 <__bad_interrupt>
       a:   23 c0           rjmp    .+70            ; 0x52 <__bad_interrupt>
       c:   22 c0           rjmp    .+68            ; 0x52 <__bad_interrupt>
       e:   21 c0           rjmp    .+66            ; 0x52 <__bad_interrupt>
      10:   20 c0           rjmp    .+64            ; 0x52 <__bad_interrupt>
      12:   1f c0           rjmp    .+62            ; 0x52 <__bad_interrupt>
      14:   1e c0           rjmp    .+60            ; 0x52 <__bad_interrupt>
      16:   1d c0           rjmp    .+58            ; 0x52 <__bad_interrupt>
      18:   1c c0           rjmp    .+56            ; 0x52 <__bad_interrupt>
    
  • Pomocny post
    #24 12347296
    dondu
    Moderator na urlopie...
    Program, który wkleiłem powyżej skompilowany w AVR Studio 4 dla ATtiny2313:

    Cytat:

    Disassembly of section .text:

    00000000 <__vectors>:
    0: 12 c0 rjmp .+36 ; 0x26 <__ctors_end>
    2: 2a c0 rjmp .+84 ; 0x58 <__bad_interrupt>
    4: 29 c0 rjmp .+82 ; 0x58 <__bad_interrupt>
    6: 28 c0 rjmp .+80 ; 0x58 <__bad_interrupt>
    8: 27 c0 rjmp .+78 ; 0x58 <__bad_interrupt>
    a: 26 c0 rjmp .+76 ; 0x58 <__bad_interrupt>
    c: 25 c0 rjmp .+74 ; 0x58 <__bad_interrupt>
    e: 24 c0 rjmp .+72 ; 0x58 <__bad_interrupt>
    10: 23 c0 rjmp .+70 ; 0x58 <__bad_interrupt>
    12: 22 c0 rjmp .+68 ; 0x58 <__bad_interrupt>
    14: 21 c0 rjmp .+66 ; 0x58 <__bad_interrupt>
    16: 20 c0 rjmp .+64 ; 0x58 <__bad_interrupt>
    18: 1f c0 rjmp .+62 ; 0x58 <__bad_interrupt>
    1a: 3e c0 rjmp .+124 ; 0x98 <__vector_13>
    1c: 1d c0 rjmp .+58 ; 0x58 <__bad_interrupt>
    1e: 1c c0 rjmp .+56 ; 0x58 <__bad_interrupt>
    20: 1b c0 rjmp .+54 ; 0x58 <__bad_interrupt>
    22: 1a c0 rjmp .+52 ; 0x58 <__bad_interrupt>
    24: 19 c0 rjmp .+50 ; 0x58 <__bad_interrupt>


    czyli jest prawidłowo. Nie mam pod ręką ATtiny2313, by sprawdzić czy działa.

    Wniosek - coś nie tak robisz w swoim środowisku - kompilacja dla innego AVR'a niż ATtiny2313?

    EDIT:
    Wstawiłem załącznik z plikami .lss i .hex
  • #25 12347359
    lekto
    Poziom 35  
    Ruszyło, wywaliłem definicje uC z main.c i dałem jako parametr kompilacji. Kto by pomyślał że to takie ważne. :D
  • #26 12347361
    dondu
    Moderator na urlopie...
    lekto napisał:
    Ruszyło, wywaliłem definicje uC z main.c i dałem jako parametr kompilacji. Kto by pomyślał że to takie ważne. :D

    A pisałem o tym wyżej :)

    dondu napisał:
    ... typ mikrokontrolera ustaw w opcjach projektu.

    czyli w Twoim przypadku jako parametr.
REKLAMA