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

[Atmega32][C][Eclipse] - bład programu gdy przerwamnie timer0 aktywne

dejmos 03 Gru 2012 11:39 1779 12
REKLAMA
  • #1 11604471
    dejmos
    Poziom 23  
    Witam

    Od pewnego czasu zmagam się z problemem odbioru danych przez procesor ATmega32 w kodzie Menchester.
    Opisze w skrócie jak działa poniższy układ.
    W przerwaniu (tryb CTC) timera 0 znajduje się funkcja obsługująca trzy wyświetlacze LED (wspólna Anoda) oraz funkcja skanująca klawiaturę.
    Katody wyświetlaczy podłączone są pod PORTB, anody pod piny PD5, PD6, PD7.
    Pin PD4 jest wyjściem danych.
    PIN PD2 jest wejściem danych.
    Podczas odbioru danych z pinu PD2 ( funkcja zgłoszenie ) występuje błąd tylko wtedy gdy przerwanie z timera 0 jest aktywne. Gdy na czas odbioru danych zablokuję to przerwanie procesor ładnie odbiera wysyłane do niego dane. I moje pytanie brzmi: Co jest nie tak z przerwaniem? Czy jego obsługa wpływa jakoś na wejście PD2?
    Dodam że zmiana pinów kluczy tranzystorowych na Port np C nie pomaga.
    Obsługa odbioru danych w przerwaniu INT0 też nic nie daje.

    [Atmega32][C][Eclipse] - bład programu gdy przerwamnie timer0 aktywne

    [code]
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 11604544
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #3 11604665
    dejmos
    Poziom 23  
    Nadajnik wysyła coś w rodzaju preembuły po to są te opóźnienia aby odbiornik zareagował tylko na początek a resztę pominął.
    Instrukcja: odebrana_dana |=(0<<(i-1));
    zeruje konkretny bit o numerze i-1 w zmiennej odebrana_dana w zależności od stanu na pinie PD2
    Instrukcja: odebrana_dana |=(1<<(i-1));
    ustawia konkretny bit o numerze i-1 w zmiennej odebrana_dana w zależności od stanu na pinie PD2
  • REKLAMA
  • Pomocny post
    #4 11604720
    Konto nie istnieje
    Konto nie istnieje  
  • #5 11604922
    dejmos
    Poziom 23  
    Funkcja powinna wyglądać tak:
    [code]
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    działa to na zasadzie:
    REJESTR |= (1<<NUMER_BITU) - ustawianie bitu
    REJESTR &= ~(1<<NUMER_BITU) - zerowanie bitu
    W moim przypadku rejestrem jest odebrana_dana zaś numerem bitu jest (i-1).
    Bit jest ustawiany bądź zerowany w zależności od stanu pinu PD2
    Więc co w tym jest nie tak?
  • Pomocny post
    #6 11608061
    Konto nie istnieje
    Konto nie istnieje  
  • Pomocny post
    #7 11608135
    dondu
    Moderator na urlopie...
    dejmos napisał:
    Podczas odbioru danych z pinu PD2 ( funkcja zgłoszenie ) występuje błąd tylko wtedy gdy przerwanie z timera 0 jest aktywne.
    Gdy na czas odbioru danych zablokuję to przerwanie procesor ładnie odbiera wysyłane do niego dane.
    I moje pytanie brzmi: Co jest nie tak z przerwaniem?

    Konkretnie to, co wskazał albertb:
    albertb napisał:
    ... jeśli masz włączone przerwanie to jego czas dodaje się do tych 1780us ...

    bo z komentarza w kodzie wynika, że przerwanie z Timer0 masz z f=100Hz. Jest więc duże prawdopodobieństwo, że w trakcie odmierzania opóźnień (liczonych przez Ciebie w mikrosekundach) w funkcji zgloszenie() i rec_cmd() trafia Ci się przerwanie, które wcale nie jest krótkie - kolejno: skanowanie(), wyswietlanie() oraz piszled() + dodatkowe operacje na stosie (prolog + epilog) - nie znamy częstotliwości kwarcu, na schemacie jest nieczytelny.

    Powinieneś więc kompletnie przebudować program, by albertb nie musiał już pisać, że:
    albertb napisał:
    Większość kodów przewijających się tutaj napisanych amatorsko stosuje przerwania od timera do mało krytycznych czasowo operacji (jak multipleksowanie wyświetlacza, odczyt klawiatury itp) a na delayach w kodzie głównym realizuje operacje krytyczne (jak odbiór danych zależnych od zegara, OneWire itp).
  • #8 11608211
    dejmos
    Poziom 23  
    Dzięki za rady. Zrobię tak jak napisał albertb czyli funkcje skanowania i wyświetlania wyrzucę z przerwania timera0, będą się wykonywały w pętli głównej programu, a funkcje odpowiedzialne za odbiór i nadawanie danych uzależnię od timera (dla zwiększenia dokładności). Tylko jest jeszcze mały problem, mianowicie jest kilka funkcji (których w listingu programu nie umieściłem) a które wykonują się dość długo... na tyle długo aby wyświetlacz zaczął migać. W tych funkcjach korzystam czasami z opóźnień, których czas nie jest krytyczny. Czy zamiast nich wstawić np kilka razy funkcję wyswietlanie() w pętli for? tak aby wygenerować to opóźnienie a jednocześnie zlikwidować miganie wyświetlacza? Czy też są inne sposoby na to? I jak obliczyć czas wykonania funkcji wyswietlanie() aby mniej więcej określić jakie opóźnienia będzie generować?

    Częstotliwość oscylatora 8MHz :-)
  • Pomocny post
    #9 11608226
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #11 11608700
    dondu
    Moderator na urlopie...
    albertb napisał:
    dondu: Ja wcale tego pisać nie muszę :-)
    Po prostu zastanawiam się skąd taka maniera bierze.
    Ale dzięki za dbałość o mnie.
    Właściwie to ciekawsza byłaby dla mnie odpowiedź niż zlikwidowanie tej maniery.

    Moim zdaniem z braku umiejętności posługiwania się timerami, czyli po prostu brakiem doświadczenia, ale to jest normalne zjawisko, więc szansa że zaniknie jest niewielka :)


    dejmos napisał:
    Tylko jest jeszcze mały problem, mianowicie jest kilka funkcji (których w listingu programu nie umieściłem) a które wykonują się dość długo... na tyle długo aby wyświetlacz zaczął migać. W tych funkcjach korzystam czasami z opóźnień, których czas nie jest krytyczny. Czy zamiast nich wstawić np kilka razy funkcję wyswietlanie() w pętli for? tak aby wygenerować to opóźnienie a jednocześnie zlikwidować miganie wyświetlacza? Czy też są inne sposoby na to?

    Timery + przerwania, timery + przerwania ... jak najmniej lub wcale nie używać delay(). No i wykorzystanie flag w przerwaniach, by wykonywały się krótko.
  • #12 11612342
    dejmos
    Poziom 23  
    Witam

    Nawiązując do tematu opóźnień w odbiorze danych mam pytanie. Czy takie zastosowanie timerów w kodzie jest poprawne? Czy może robi się to w trochę inny... może bardziej profesjonalny sposób? Nadawanie i odbiór w kodzie menchester. czas trwania jednego bitu 2ms (na razie do testów, później czas będzie krótszy).

    [code]
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #13 11612409
    Konto nie istnieje
    Konto nie istnieje  
REKLAMA