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

[Atmega16][C] Program działa tylko bez optymalizacji kodu

stasiu2323 16 Paź 2009 21:23 2018 8
  • #1 7137351
    stasiu2323
    Poziom 13  
    Witam.

    Program działa jeśli jest kompilowany bez optymalizacji. Skończyły mi się pomysły co może być nie tak.

    
    #define F_CPU 1000000L
    #define BAUD 1200
    #define MYUBRR F_CPU/16/BAUD-1
    
    #include <avr/io.h>
    #include <avr/iom16.h>
    #include <avr/interrupt.h>
    
    
    #define TXOFF (UCSRB&=!(1<<UDRIE))
    #define TXON (UCSRB|=(1<<UDRIE))
    
    
    volatile char TXBUSY;
    volatile char * txwsk;
    
    void USART_Init( unsigned int ubrr){
      /* Set baud rate */
      UBRRH = (unsigned char)(ubrr>>8);
      UBRRL = (unsigned char)ubrr;
      /* Enable receiver and transmitter */
      UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
      /* Set frame format: 8data, 1stop bit */
      UCSRC = (1<<URSEL)|(3<<UCSZ0);
    }
    
    
    SIGNAL(SIG_USART_DATA){
      char znak;
      znak=*(txwsk++);
      if (znak)
        UDR=znak;
      else{
        TXOFF;
        TXBUSY = 0;
      }
    }
    
    SIGNAL (SIG_USART_RECV){
    }
    
    
    char hello[]="Witam\r\n";
    
    
    int main(void){
      USART_Init ( MYUBRR );
      sei();
      txwsk=hello;
      TXBUSY=1;
      TXON;
      while (TXBUSY);
      txwsk=hello;
      TXBUSY=1;
      TXON;
      while (1){
      }
    }
    
  • #2 7137660
    psine.pl

    Poziom 30  
    Co ten program ma robić ?
    W czym kompilowany ?

    Co dokładnie nie działa ?

    Tak na pierwszy rzut oka to po co obsługujesz wysyłanie danych w przerwaniu skoro nie jest włączone ?
    Włączone masz przerwanie odbioru ...
  • #3 7137755
    JarekC
    Poziom 32  
    Witam,

    Rozumiem,że chciałeś aby program dwukrotnie wytransmitował słowo hello.

    Wszystko jest ok poza jednym małym szczegółem.
    Całą transmisje masz w przerwaniu od nadajnika (UART Transmit Complete ),
    jednak takie przerwanie nie zostanie zgłoszone dopóki nie zostanie wytransmitowany
    jakiś znak.
    W main musisz rozpocząć trasmisję poprzez wysłanie pierwszego znaku, a pozostałe
    zostaną wysłane w przerwaniu. Każdą nową transmisję musisz w ten sposób startować.

    Automatyczny start mógłbyś uzyskać korzystając z przerwań od UART Data Register Empty.


    PS.
    Ponieważ korzystam z innego kompilatora nie jestem pewien czy SIG_USART_DATA
    odpowiada przerwaniu od UART Transmit Complete.

    Pozdrawiam
    JarekC
  • #4 7137772
    stasiu2323
    Poziom 13  
    Program ma wysyłać "powitanie" na port szeregowy. Kompilowany przy pomocy Winavr + avr studio(w najnowszych dostępnych wersjach). Bez optymalizacji wysyła "Witam" ale tylko raz, a powinien dwa razy. Po włączeniu optymalizacji nie wysyła nic. Gdy robiłem transmisję przez polling wszystko było ok. Przerwanie włącza makro .
    Dzięki

    Plik iom16.h
    
    /* USART, Rx Complete */
    #define USART_RXC_vect			_VECTOR(11)
    #define SIG_USART_RECV			_VECTOR(11)
    #define SIG_UART_RECV			_VECTOR(11)
    
    /* USART Data Register Empty */
    #define USART_UDRE_vect			_VECTOR(12)
    #define SIG_USART_DATA			_VECTOR(12)
    #define SIG_UART_DATA			_VECTOR(12)
    
    /* USART, Tx Complete */
    #define USART_TXC_vect			_VECTOR(13)
    #define SIG_USART_TRANS			_VECTOR(13)
    #define SIG_UART_TRANS			_VECTOR(13)
    

    Więc przerwanie jest chyba ok.
    Pozdrawiam
  • Pomocny post
    #5 7137976
    JarekC
    Poziom 32  
    Przerwanie masz załączane poprawnie ale jest problem z wyłączaniem.

    Makro TXOFF powinno być:

    
    #define TXOFF (UCSRB&=~(1<<UDRIE)) 
    


    zamiast
    
    #define TXOFF (UCSRB&=!(1<<UDRIE)) 
    


    Operator ! to operator LOGICZNy negacji a ~to operator uzupełnienia jedynkowego.

    Ten błąd wyjaśnia jednokrotne wysyłanie hello, ponieważ po pierwszym wysłaniu
    makro TXOFF zerowało rejestr UCSRB, natomiast nie wyjaśnia całkowitego braku transmisji
    po optymalizacji. Ale spróbuj co się stanie po tej poprawce.

    Pozdrawiam
    JarekC
  • #6 7138043
    stasiu2323
    Poziom 13  
    JarekC:

    Masz rację. Bez optymalizacji wszystko jest ok. Po włączeniu optymalizacji napis "Witam" pojawia się tylko raz. Kompilator podczas optymalizacji pomija pierwsze przypisanie Tylko nie wiem dlaczego?

    Pozdrawiam
  • Pomocny post
    #7 7138554
    michalko12
    Specjalista - Mikrokontrolery
    stasiu2323 napisał:
    JarekC:

    Masz rację. Bez optymalizacji wszystko jest ok. Po włączeniu optymalizacji napis "Witam" pojawia się tylko raz. Kompilator podczas optymalizacji pomija pierwsze przypisanie Tylko nie wiem dlaczego?

    Pozdrawiam


    Tę linijkę kodu:
    volatile char * txwsk; 


    zastąp na:
    char * volatile txwsk; 
REKLAMA