PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Dual UART am mega128 - Es will einfach nicht



Christoph2
16.03.2013, 01:15
Hi,

ich will am mega128 beide UART Schnittstellen verwenden - und schaffe es einfach nicht diese zum laufen zu bringen.
Zuerst habe ich es mit der Library von Peter Fleury versucht, danach mit der AVRlib von Procyon - beides ohne Erfolg.

Dann habe ich das Datenblatt herausgesucht, und selber einige Funktionen programmiert (ich brauche einstweilen nur mal eine sende-Funktion):



#include<avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>

#defineF_CPU16000000

voiduart0_putc(unsignedchardata)
{
/* Wait for empty transmit buffer */
while(!(UCSR0A&(1<<UDRE0)));

/* Put data into buffer, sends the data */
UDR0=data;
}



voiduart1_putc(unsignedchardata)
{
/* Wait for empty transmit buffer */
while(!(UCSR1A&(1<<UDRE1)));

/* Put data into buffer, sends the data */
UDR1=data;
}


voiduart0_init()
{
/*
- Baudrate: 19200
- Parity: None
- Asynchron
- 8 Bit Data
- 1 Stop Bit
- Rx und Tx enabled
*/

//Configure UART0
UCSR0A=
(0<<U2X0)|// dont use double UART speed mode
(0<<MPCM0);// Dont use Multi-procesor communication mode


UCSR0B=
(0<<RXCIE0)|// Dont enable RX complete interrupt
(0<<TXCIE0)|// Dont enable TX complete interrupt
(0<<UDRIE0)|// Dont enable data register empty interrupt
(1<<RXEN0)|// Enable receiver.
(1<<TXEN0)|// Enable transmitter.
(0<<UCSZ02);// Use 8 bit character size


UCSR0C=
(0<<UMSEL0)|// Use asynchronous mode
(0<<UPM01)|// No parity check
(0<<UPM00)|// No parity check
(0<<USBS0)|// Use one stop bit
(1<<UCSZ01)|// Use 8 bit character size
(1<<UCSZ00);// Use 8 bit character size

//Baudrate 19200 @16MHz
UBRR0H=0;
UBRR0L=51;
}



voiduart1_init()
{
/*
- Baudrate: 19200
- Parity: None
- Asynchron
- 8 Bit Data
- 1 Stop Bit
- Rx und Tx enabled
*/

UCSR1A=0b00000000;
UCSR1B=0b00011000;
UCSR1C=0b00000110;

//Baudrate
UBRR1H=0;
UBRR1L=51;
}




intmain(void)
{
// PORT D
DDRD&=~(1<<2); // RX0
DDRD|=(1<<3); // TX0


// PORT E
DDRE&=~(1<<0); // RX1
DDRE|=(1<<1); // TX1


sei();


uart0_init();
uart1_init();

while(1)
{
uart0_putc('A');
uart1_putc('B');

_delay_ms(100);
}


}// ENDE main


Mit einem Debugger habe ich herausgefunden, dass das Programm in der while Schleife der Funktion uart0_putc() hängen bleibt.
Anscheinend wird der Ausgangspuffer nicht geleert. Am Oszi habe ich mir den TXD Pin angeschaut - da ist nichts hinausgekommen.
Das Bit UDRE0 wird auch nicht mehr auf 1 gesetzt, weil der Ausgangspuffer noch nicht geleert ist.

Aber woran liegt das? Mir fällt nichts ein was ich dagegen tun kann...
Gibt es irgendwo noch ein Bit, das ich setzen muss, damit die UART Schnittstellen aktiviert werden? Ich habe im Datenblatt nichts dazu gefunden.

Ich bin für jeden Tipp dankbar!

lg
Christoph

steveLB
16.03.2013, 08:10
Bei dir fehlen die Klammern.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART
"

while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
{ }
UDR = 'x'; /* schreibt das Zeichen x auf die Schnittstelle */
"

radbruch
16.03.2013, 08:30
Er verwendet ein ; nach der While-Schleife und benötigt deshalb hier keine {}

steveLB
16.03.2013, 08:43
Stimmt das fehlt auch noch, aber er hat ja schon mit Uart0 Probleme.

Ich würde nochmal den Uart aufbauen wie im Turorial, auch mit der Berechnung für den Bautratenfehler, dazu mal mit Bautrate 9600 anfangen und bei Funktion Schritt für Schritt in Richtung deines Wunsch-Uarts gehen.
Nachdem dann ein Uart funktioniert, verdoppelst die Funktionen und passt sie auf den zweiten Uart an, auch da die Berechnung und Initialisierungen etc..

oberallgeier
16.03.2013, 09:02
... [/CODE] ... UBRR1L=51 ... [/CODE]Irre ich mich oder gibt das irgendetwas über 39 kBd ? statt der von Dir angestrebten 19200 ?

Ich rechne üblicherweise so :

UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr; // Enable receiver and transmitter

Nur gaaanz nebenbei ... die Orgie mit den vielen 0-Zuweisungen

(0<<RXCIE0)|// Dont enable RX complete interrupt ...ist überflüssig/sehr ungewöhnlich. WENN Du die Bits löschen willst (weil sie "irgendjemand-irgendwo" gesetzt hat - nach nem Reset sind die sowieso "0"), dann eher in
der Art: "TCCR2A &= ~(1<<WGM21);"

Viel Erfolg

Christoph2
17.03.2013, 12:58
Hi,

vielen Dank für eure Antworten. Ich habe alles ausprobiert was ihr vorgeschlagen habt, aber das hat das Problem nicht gelöst.

Nach einigen Stunden Zeitverschwendung bin ich aber trotzdem draufgekommen: Es gibt ein Fusebit, das den "ATmega103 compatibilitymode" aktiviert. Dieses ist standardmäßig gesetzt. Dadurch hat der mega128 nur eine UART Schnittstelle, und wenn man wie ich beide konfiguriert, funktioniert gar keine...

Ist ja nett dass es diese Fuse gibt, aber WARUM VERDAMMT AKTIVIERT ATMEL DIESEN COMPATIBILITY MODE STANDARDMÄSSIG??? Wen interessiert der mega103...

Naja, danke für die Hilfe.

lg
Christoph