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

Attiny2313 problem z odczytem zmiennej w przerwaniu timera

karbon 02 Wrz 2009 13:29 1551 7
  • #1 6971454
    karbon
    Poziom 21  
    Witam!

    Główne założenie tej części programu miało być takie, że program sprawdza zmienną w przerwaniu wywoływanym przez timer0 (co 1s) i jeżeli jest warunek spełniony to zwiększa odpowiednią zmienną co 1s.


    #include <avr/io.h> // dostęp do rejestrów
    #include <avr/interrupt.h> // funkcje sei(), cli()
    #include <avr/iotn2313.h>
    
    unsigned char volatile flagi;
    
    SIGNAL(SIG_OVERFLOW1)
    {
      TCNT1 = 22336; // wartosc pocztatkowa timera
    
      if(bit_is_set(flagi, 4))
      {
        czas_a++;
      }
    }
    
    int main()
    {
      flagi = 0x00;
    
      // konfiguracja timera, przerwania i uarta
    
      while(1)
      {}
    }



    Efekt jest taki, że program zawsze zwiększa zmienną!
    Jaki błąd popełniłem, siedzę już nad tym 2 doby i zero postępu?

    Drugie pytanie.
    Blok danych (data) zajmuje 120b (93.8%), czy pamięć wolna jest wykorzystywana do odkładania instrukcji na stos czy do tego celu jest inna niedostępna pamieć?
  • #2 6971482
    _Robak_
    Poziom 33  
    Na pewno nie jest to dzialajacy fragment kodu ;) Sprowadz swoj kod do minimalnej wersji ale dzialajacej ;]
  • #3 6971506
    szelus
    Poziom 34  
    Zaczynając od końca - pamięć RAM jest jedna, i stos się też tam musi zmieścić. Dlatego jeżeli dane zajmują 120 bajtów, to niestety przy przerwaniach bedą na pewno "zajeżdżane" przez stos. I to najprawdopodobniej tłumaczy, dlaczego zmienna czas_a jest zwiększana zawsze - po prostu do zmiennej flagi trafiaja dane ze stosu.

    Przy okazji - nie włączaj iotn2313.h bezpośrednio. Musisz podać (w makefile) kompilatorowi typ kontrolera i wtedy włączenie io.h wystarczy.
  • #4 6971542
    karbon
    Poziom 21  
    A ile powinno być wolnej pamięci RAM?
    Obsługuję 2 przerwania, timer i uarta.
  • #5 6971677
    szelus
    Poziom 34  
    To jest dość ciężko teoretycznie określić. Jeżeli dobrze pamiętam, to samo wejście w przerwanie potrzebuje coś ze 32 bajty. Zobacz w wygenerowanym kodzie, co jest odkładane na stos na poczatku obsługi przerwania.
    Plus to, co wykorzystujesz na wywołania funkcji i zmienne lokalne - dla najgorszego przypadku.
    Przy małym programie (jeżeli nie ma dużo funkcji) i 64 bajtach wolnych czułbym się w miarę bezpiecznie (zakładam, że nie obsługujesz przerwań zagłębionych).
  • #6 6971720
    karbon
    Poziom 21  
    Udało mi się zoptymalizować program do 107b RAM, wygląda na to, że zaczął działać.

    Wysyłam dane uartem takim tworem:

    void USART_Tx(unsigned char data)
    {
    	while ( !( UCSRA & (1<<UDRE)) );/* Wait for empty transmit buffer */ 
    	UDR = data;/* Put dafta into buffer, sends the data */ 
    } 
    
    
    unsigned char USART_Rx()
    { 
       while ( !(UCSRA & (1<<RXC)) );/* Wait for data to be received */ 
       return UDR;/* Get and return received data231 from buffer */ 
    }
    
    
    void USART_wyslij(char *s) 
    { 
    	while (*s)                               // do napotkania 0 
    	{ 
            //tu by sie cos przydalo atoi np 
    		USART_Tx(*s);                   // zapisz znak wskazywany przez s na LCD 
    		s++;                               // zwiększ s (przygotuj nastepny znak) 
    	} 
    }


    Bardzo dużo ramu to rezerwuje. Mimo tego, że mam jakiś ciąg char w pamięci programu to po wywołaniu funkcji USART_wyslij() (w parametrze mój ciąg charów) robi się 2x więcej pamieci zajete.
    Jest jakiś mniej zasobożerny sposób na wysyłanie ciągów uartem?
  • #7 6971818
    szelus
    Poziom 34  
    To nie problem USARTa, a ogólnie obsługi łańcuchów w AVR. Na innych architekturach stałe napisowe zwykle trafiaja do ROMu, natomiast na AVR musi być zrobiona kopia w RAMie, bo to oddzielna przestrzeń adresowa.
    Poczytaj o PROGMEM.
    Musiałbys przepisać funkcje UARTowe, aby przyjmowały wskaźniki do danych w pamięci flash.

    P.S. Nie wybrałeś czasem za słabego procesora na wymaganą funkcjonalność?

    P.S.2 Prawdopodobnie działa ci teraz przez przypadek...
  • #8 6971892
    karbon
    Poziom 21  
    W głąb testów wyszło, że im mniej RAMu zajmuje program to więcej funkcji działa :D
    Zostawiłem 81b i nadal kuleje...

    Jaki z uC byś polecił?
    Dobrze gdyby był w tej samej obudowie z takim samym rozstawem nóżek...

    Zacząłem przepisywać i mam dla kodu programu ok 1.5KB a dla RAM 11B 8)
REKLAMA