ATmega164PA -> UARTs wollen nicht -.-

OP #2322062
Lesenswert?

Guten Tag liebe Gemeinde,
seit gestern Abend sitze ich an einem Problem, was mir bis jetzt 
jegliche graue Haare bereitet hätte, wenn ich denn welche hätte ;-)
Es geht um den UART beim ATmega164PA.

Ich "beclocke" diesen über einen Quarz mit 12MHz, habe ihn an meinem 
JTAGICE mk2 zum debuggen, alles wunderbar soweit.

Hier mal der Code, mit welchem ich die UARTs inite:
1
void uart_init(void)
2
{
3
  UBRR0 = (F_CPU/(16*19200ul))-1;
4
  UCSR0B = (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0);
5
  UCSR0C = (3<<UCSZ00);
6
  
7
  //configure UART -> FT232RL
8
  UBRR1 = (F_CPU/(16*(long)19200))-1;
9
  UCSR1B = (1<<TXEN1) | (1<<RXEN1) | (1<<RXCIE1);
10
  UCSR1C = (3<<UCSZ10);
11
}

F_CPU ist in diesem Fall auf 12000000ul gesetzt.
So, der aufmerksame Leser wird erkannt haben, dass am UART1 ein FT232RL 
hängt, welcher mir als USB Brücke für den Laptop dient.
Hier benutzt ich HTerm, um das ganze zu testen.

Empfangen funktioniert...wenn ich über HTerm 10mal hintereinander das 
Zeichen schicke, lande ich in der ISR und kann auch die Bits auf der 
Leitung mit dem Oszi erkennen, diese Richtung FT232RL -> ATmega geht 
also.
Senden allerdings nicht...
Zu Beginn des Programms ist der Pin low, logischerweise, habe ich die 
Init-Routine durchschritten, ist der Sende-Pin high, so soll es auch 
sein, aber dabei bleibts.
Sende ich mit dieser Routine ein Zeichen:
1
void uart1send(uint8_t data)
2
{
3
  while(!(UCSR1A & (1<<UDRE1)))
4
  UDR1 = data;
5
}

Das Gleiche habe ich auch mit dem UART0, hier ist das gleiche Phänomen 
am Ausgangspin.
Daher vermute ich mal, dass __irgendwo__ ein dummes Bit nicht gesetzt 
ist oder sonst eine Einstellung verkehrt, was mir das Senden verhindert.
Ich wüsste momentan nicht, an was es liegen könnte...FuseBits sind 
soweit alle richtig gesetzt, sonst funktioniert der Controller ja auch.

Kann mir jemand helfen?

MfG
Markus

P.S.:
Die Main schaut recht unspektakulär aus, aber hier dennoch:
1
int main(void)
2
{
3
  uint8_t test;
4
  uart_init();
5
  sei();
6
  
7
    while(1)
8
    {
9
    uart0send(0x55);
10
    uart1send(0x55);
11
    //TODO:: Please write your application code 
12
    }
13
}
#2322142
Lesenswert?

Markus Oberle schrieb:
> Hier mal der Code, mit welchem ich die UARTs inite:
> void uart_init(void)
> {
>   UBRR0 = (F_CPU/(16*19200ul))-1;
>   UCSR0B = (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0);
>   UCSR0C = (3<<UCSZ00);
>
>   //configure UART -> FT232RL
>   UBRR1 = (F_CPU/(16*(long)19200))-1;
>   UCSR1B = (1<<TXEN1) | (1<<RXEN1) | (1<<RXCIE1);
>   UCSR1C = (3<<UCSZ10);
> }

Hier hast du das aber unterschlagen.
OP #2322147
Lesenswert?

hm damn it.
ok, da geb ich dir recht.
So schaut meine Routine aktuell aus:
1
void uart_init(void)
2
{
3
  UBRR0 = (F_CPU/(16*19200ul))-1;
4
  UCSR0B = (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0) | (1<<TXCIE0);
5
  UCSR0C = (3<<UCSZ00);
6
  
7
  UBRR1 = (F_CPU/(16*(long)19200))-1;
8
  UCSR1B = (1<<TXEN1) | (1<<RXEN1) | (1<<RXCIE1) | (1<<TXCIE1);
9
  UCSR1C = (3<<UCSZ10);
10
}

kommt davon, wenn man gleichzeitig postet und nebenbei rumprobiert.

Erfolg bleibt weiterhin aus :-(
OP #2322211
Lesenswert?

So, ich darf teilweisen Erfolg verkünden...ich verstehs aber net...

es funktioniert, wenn ich die Zeile auskommentier:
1
while(!(UCSR1A & (1<<UDRE1)))

aber warum....KEINE AHNUNG! in allen möglichen Beispielen und laut 
Datenblatt, soll es SO mit der Zeile funktionieren...tut es aber nicht 
-.-
Gast #2322272
Lesenswert?

Exakt. Im Datenblatt steht, dass das UDRE Bit gesetzt wird, wenn das 
Senderegister leer ist und weiteres Datenbyte gesendet werden darf. Also
1
while (((UCSR1A & (1<<UDRE1))==0))
2
{
3
  __no_operation;
4
}
5

6
UDR1=dummy;

Wenn man die geschweiften Klammern nicht haben möchte, setzt man ein ; 
ans Ende der Zeile von der while-Anweisung.

So wie Du das hingeschrieben hast, schreibst Du ins UDR Register wenn es 
belegt ist.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren