www.mikrocontroller.net

Forum: Compiler & IDEs UART initialisieren / gcc


Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich versuch mit WinAVR ein Programm zu schreiben,
das mir über den UART meines ATmega32 ein paar Zeichen
zum PC sendet.

Dafür hab ich eine Funktion UART_init geschrieben die
mir den UART initialisieren soll.
Compilieren funktioniert ohne Probleme, beim debuggen
spring er allerdings nicht in UART_init. Kann es sein
das der Compiler das Unterprogramm wegoptimiert??

WAs kann ich dagegen machen? Bei Gelegenheit vielleicht
noch ein Tip ob die Übertragung auf diese Weise
funktionieren könnte!

Danke, Stefan



Hab das Programm mal drangehängt.


#include <avr/io.h>
 void UART_init(void)
 {

 // Baudrate einstellen

 sbi(UBRRH,7);        // Zugriff auf UBRRH ermöglichen
 UBRRH = (UBRRH | 0x00);
 UBRRL = 0x17;        // 9600 bps

  // Frame Format einstellen

 cbi(UCSRC,7);              // Zugriff auf UCSRC
 cbi(UCSRC,6);         // Asynchrone Übertragung
 UCSRC = (UCSRC | 0x10);     // Even Parity
 cbi(UCSRC,3);        // 1 Stop Bit
 UCSRC = (UCSRC | 0x03);    // 8 Datenbit
 cbi(UCSRB,2);

 // RxD, TxD freischalten

 sbi(UCSRB,3);        // TxD Pin freischalten
 sbi(UCSRB,4);        // RxD Pin freischalten

 }

 void send_fkt(char byte)
 {
  while ( !(UCSRA & (1<<UDRE)));
  UDR = byte;
 }

 int main(void)
 {

 UART_init;


 while(1)
    {
  send_fkt("O");    // Zeichen übertragen
  send_fkt("k");
  send_fkt(" ");
    }
 return 0;
 }

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Kann es sein das der Compiler das Unterprogramm wegoptimiert?

Sowas könnte bei -O3 Optimierung in der Tat erfolgen, bei allen
geringeren Optimierungen dagegen nicht.

Aber:

> UART_init;

Dafür hast Du keine Warnung bekommen (`statement has no effect' oder
sowas)?  Das würde mich wundern...

Du solltest Dir mal ansehen, wie man in C Funktionen aufruft. ;-)  Du
hast die Adresse der Funktion referenziert, sie aber nicht aufgerufen.
Da Du die Adresse hernach nicht benutzt, hat der Compiler das
natürlich wirklich wegoptimiert.

Hinweis: Falls Du die Optimierung ganz ausschaltest (-O0), dann
bekommst Du eine Reihe von Warnungen nicht mehr, die erst im
Optimiererlauf (Programmflußanalyse) festgestellt werden können.
`statement has no effect' könnte dazu gehören.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit dem Programmaufruf hatte ich schon
gefunden, war wirklich ein blöder Fehler! :-)

Allerdings ist mir das mit der Optimierung
des Compilers schon passiert, deswegen würd
mich mal interessieren wo sich das einstellen
läßt. Denk mal im makefile aber ich konnte
nichts entsprechendes finden.


Noch ne Frage zur Adressierung der UART Register.
Ich benutze eine ATmega32, soviel ich verstanden
hab liegen die Register UCSRC & UBRRH auf der
selben Adresse. Nach dem Datenblatt lassen sich
die beiden Register durch das setzen des MSB
auswählen.

Hab das folgendermaßen versucht:

cbi(UCSRC,7);
UCSCR = 0x...

sbi(UBRRH,7);
UBRRH = 0x...

aber beim debuggen bleibt das ohne Erfolg.
Wie kann ich die Register adressieren?

Ciao Stefan

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Allerdings ist mir das mit der Optimierung des Compilers schon
> passiert, ...

Was denn?

> deswegen würd mich mal interessieren wo sich das einstellen
> läßt. Denk mal im makefile aber ich konnte nichts entsprechendes
> finden.

So schwer zu finden?  Im Standard-WinAVR-Template gibt's extra
einen Makro OPT dafür, einschließlich Kommentar.

Oder <werbung>
http://www.sax.de/~joerg/mfile/
</werbung>

> Hab das folgendermaßen versucht:

> sbi(UBRRH,7);
> UBRRH = 0x...

Nun, das kann nicht gehen.  Überleg doch mal, Dein Schreibzugriff auf
UBRRH würde doch das zuvor geschriebene Bit 7 wieder überschreiben.

Ganz davon abgesehen: Du hast die Werte von Bit 7 vertauscht.  Bit 7
low selektiert UBRRH, Bit 7 high selektiert UCSRC.

Aber die Sache ist viel einfacher, als es sich auf den ersten Blick
liest: die zulässigen Vorteilerwerte in UBRRH sind allesamt so klein,
daß beim Schreiben von UBRRH Bit 7 sowieso immer low ist.  Wenn Du
beim Beschreiben dieser Adresse dagegen UCSRC meinst, dann mußt Du
stets auch »| _BV(URSEL)« mit reinnehmen.  Lesen ist etwas
komplizierter, siehe Datenblatt.  Allerdings solltest Du normalerweise
keinen Grund haben, eins dieser Register zu lesen, da Du ja deren
Inhalt normalerweise schon kennen solltest.

Autor: funker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bevor der Beitrag auf der nächsten Seite verschwunden ist:

Probiere auch schon länger das UART beim 8515 in C-Code zum laufen
bringen, mit dem STK500:

#include <avr/io.h>

void send(char zeichen);

int main()
{
 sbi(UCR,3);        // TX aktivieren
 outp(25,UBRR);      // 4MHz -> 9600 bps

 for(;;)
 {
  send('T');
  send('e');
  send('s');
  send('t');
  send('!');
 }
}


void send(char zeichen)
{

while ( !( USR & (1<<UDRE)) )
  {
UDR = zeichen;
  }
}


Sendet leider nichts ans Terminal, darum wollte ich mal fragen ob meine
send-Funktion bzw. das USR richtig ist.

Das Assembler-Beispiel aus dem Tut habe ich mit dem 4433 auch
ausprobiert, funktioniert auch, leider nicht immer. Manchmal muss ich
erst den Reset-Taster drücken, dass "merkwürdige" Zeichen wieder
"Test!" ergeben - mit dem STK-Board.

Autor: funker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hat sich auch schon wieder erledigt, warum verstehe ich zwar nicht, habe
die funktionen nach avrfreak design geschrieben - jetzt gehts:

#include <avr/io.h>


void InitUART(unsigned char baudrate){
  UBRR = baudrate;
  UCR |= (1<<TXEN);
}


void transmit(unsigned char data){
  while(! (USR & (1<<UDRE)))
  ;
  UDR = data;
}


main(void){
  InitUART(25);
  while(1){
  transmit('a');
  transmit('b');
  }

}

Autor: Rahul Ghose (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleiner Hinweis (da ich auch das Problem hatte):
Das STK500 verwendet einen Takt von 3,69MHz für den
"Slave"-Controller. Zumindest war das beim mitgelieferten at90s8515
so.
Einstellen kannst du die Frequenz im AVR-Studio bzw. mit
STK500-Plug-in.
Schönen Gruß
Rahul

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@funker:

void transmit(unsigned char data){
  while(! (USR & (1<<UDRE)))
  ;
  UDR = data;
}

Hier wird eine while-Schleife so lange ausgeführt (und NICHTS gemacht),
so lange die Bedingung "1" ergibt. Du könntest das ";" nach
Assembler in ein NOP übersetzen.

void send(char zeichen)
{

while ( !( USR & (1<<UDRE)) )
  {
UDR = zeichen;
  }
}

Hier wird in dieser while-Schleife Ständig das an die Funktion
übermittelte "zeichen" in UDR geschrieben.

So wäre das richtig (nur, um sicher zu stellen, daß das auch korrekt
verstanden wird :):

void send(char zeichen)
{

while ( !( USR & (1<<UDRE)) )
  {
     /* NOP ;) */
  }
UDR = zeichen;
}


Gruß,
Patrick...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.