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

[ATTiny2313][AVRGCC] Restart AVR po ustawieniu UDRIE

xPatryk 13 Kwi 2009 13:19 1607 2
  • #1 6409127
    xPatryk
    Poziom 15  
    Witajcie,

    próbuję właśnie wykorzystać bibliotekę RKAvrLib do realizacji transmisji RS485 w oparciu o przerwania i tu napotkałem problem...

    Po inicjalizacji UART'u wszystko działa poprawnie, dopóki nie próbuję wysłać jakiegokolwiek komunikatu przez UART.

    przykładowo wywołanie:
    UART_putstr_P(PSTR("Test nadawania"))


    uruchamia funkcję biblioteczną:

    
    #include "../uart.h"
    
    void UART_putstr_P(const char *s)	// wysyła łańcuch s z FLASH na UART
    {
    #ifdef UART_DE_PORT
    //  sbi(UART_DE_PORT,UART_DE_BIT);	// odblokuj nadajnik RS485
    #endif
      register u08 c;
      while ((c = pgm_read_byte(s++)))	// dopóki nie napotkasz 0
      {
        UART_putchar(c);			// wysyłaj znak
      }
    #ifdef UART_DE_PORT
    //  cbi(UART_DE_PORT,UART_DE_BIT);	// zablokuj nadajnik  RS485
    #endif
    }
    


    Wysyła ona w pętli kolejne znaki do funkcji putchar:

    
    #include "../uart.h"
    
    int UART_putchar(char c)    // wysyła znak c na UART
    {
    
    //  cbi(_UCR_,RXEN);			// zablokuj odbior 
      sbi(UART_DE_PORT,UART_DE_BIT);	// odblokuj nadajnik RS485
    
      while((UART_BUF_SIZE - (UART_t_in - UART_t_out)) <= 2);  // Wait...
      // Add data to the transmit buffer, enable TXCIE
      UART_tbuf[UART_t_in & UART_TMASK] = c;
      UART_t_in++;
    
      // ------------ PROBLEM WYWOŁUJE TA LINIA: ----------//
     
      sbi(_UCR_, UDRIE);      // włącz przerwanie od pustego bufora
      
      // ------------ PROBLEM WYWOŁUJE POWYŻSZA LINIA ----------//
    
      cbi(UART_DE_PORT,UART_DE_BIT);	// zablokuj nadajnik  RS485
    //  sbi(_UCR_,RXEN);			// odblokuj odbior 
    
      return 0;
    }
    


    Która po zakończeniu powoduje restart programu / zawieszenie się procesora i w rezultacie również restart albo po prostu powrót do początku main().

    Wykomentowanie oznaczonej linii sprawia, iż program przestaje się wysypywać. Oczywiście wysyłanie wtedy nie działa.

    Obsługa przerwania jest zrealizowana następująco:

    SIGNAL(SIG_UART_DATA)
    {
      if(UART_t_in != UART_t_out)
      {
        _UDR_ = UART_tbuf[UART_t_out & UART_TMASK];
        UART_t_out++;
      }
      else
      {
        _UCR_ &= ~(1<<UDRIE);
      }
    }
    


    Co może być przyczyną problemów z działaniem?

    Pozdrawiam serdecznie i z góry dziękuję za pomoc...
    Patryk
  • Pomocny post
    #2 6409682
    BoskiDialer
    Poziom 34  
    "SIG_UART_DATA" - co to jest? nie znam tego. W nagłówku avr/io.h (iotn2313.h) jest: USART_UDRE_vect(=SIG_USART0_DATA=SIG_USART0_UDRE). Jeśli nie to jest problemem, to widocznie funkcja obsługuje inne przerwanie niż zamierzone, podczas gdy właściwa (jej brak) powoduje reset. Wklej komunikaty kompilatora.
  • #3 6410106
    xPatryk
    Poziom 15  
    Witaj,

    zapomniałem dodać, iż zdefiniowane jest makro zapewniające przenoszalność kodu:

    /*
     * podmiana nazw rejestrów dla różnych układów AVR
     */
    
    // ---------------------------------------------------------------
    
    /*
     * _UBRR_
     */
    #ifdef	UBRR
    #define _UBRR_	UBRR
    #endif
    
    #ifdef	UBRRL
    #define _UBRR_	UBRRL
    #endif
    
    #ifdef	UBRR0
    #define _UBRR_	UBRR0
    #endif
    
    #ifdef	UBRR0L
    #define _UBRR_	UBRR0L
    #endif
    
    // ---------------------------------------------------------------
    
    /*
     * _UBRRH_
     */
    #ifdef	UBRRH
    #define _UBRRH_	UBRRH
    #endif
    
    #ifdef	UBRR0H
    #define _UBRRH_	UBRR0H
    #endif
    
    #ifdef	UBRRHI
    #define _UBRRH_	UBRRHI
    #endif
    
    // ---------------------------------------------------------------
    
    /*
     * _UDR_
     */
    #ifdef	UDR
    #define _UDR_	UDR
    #endif
    
    #ifdef	UDR0
    #define _UDR_	UDR0
    #endif
    
    // ---------------------------------------------------------------
    
    /*
     * _UCR_
     */
    #ifdef	UCR
    #define _UCR_	UCR
    #endif
    
    #ifdef	UCSRB
    #define _UCR_	UCSRB
    #endif
    
    #ifdef	UCSR0B
    #define _UCR_	UCSR0B
    #endif
    
    // ---------------------------------------------------------------
    
    /*
     * _USR_
     */
    #ifdef	USR
    #define _USR_	USR
    #endif
    
    #ifdef	UCSRA
    #define _USR_	UCSRA
    #endif
    
    #ifdef	UCSR0A
    #define _USR_	UCSR0A
    #endif
    
    // ---------------------------------------------------------------
    
    #ifdef SIG_UART0_RECV
    #define SIG_UART_RECV          SIG_UART0_RECV
    #endif
    
    #ifdef SIG_UART0_DATA
    #define SIG_UART_DATA          SIG_UART0_DATA
    #endif
    
    #ifdef SIG_UART0_TRANS
    #define SIG_UART_TRANS         SIG_UART0_TRANS
    #endif


    oraz definicja sbi i cbi:
    
    #ifndef cbi
    /**
     Zmienia stan bitu BIT w porcie PORT na 0
     \note Zastosowano dla kompatybilności z starszymi programami
    */
    #define cbi(PORT, BIT) (_SFR_BYTE(PORT) &= ~_BV(BIT))
    #endif
    
    #ifndef sbi
    /**
     Zmienia stan bitu BIT w porcie PORT na 1
     \note Zastosowano dla kompatybilności z starszymi programami
    */
    #define sbi(PORT, BIT) (_SFR_BYTE(PORT) |= _BV(BIT))
    #endif


    Co do kompilacji, generowane są jedynie ostrzeżenia o przstarzałości biblioteki signal.h:

    Cytat:
    c:/winavr-20080411/lib/gcc/../../avr/include/avr/signal.h:36:2: warning: #warning "This header file is obsolete. Use <avr/interrupt.h>."


    Komunikatów o błędach brak.

    Dodano po 37 [minuty]:

    Mówcie mi ślepy albo roztrzepany.

    Jednak faktycznie - kwestia błędnego nazewnictwa. Tak to jest, jak się czyta nagłówki od "2313" a nie od "tn2313" :)

    Po poprawieniu, działa :)
REKLAMA