PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATMega32 UART problem --> Problem gelöst



ChristophB
12.03.2010, 16:02
Hallo ich versuche gerade meinen uC (atmega32) mit einem PC über UART zu verbinden.

Leider klappt das ganze nicht so richtig. Aus irgendeinem Grund liegen konstante 5V an meinem TX Pin. Der Max232 der das Signal wandeln soll funktioniert anscheinend, da hier passenderweiße -10 V anliegen.

Ich poste hier mal den Quellcode den ich verwende, villeicht kann mir ja jemand dabei helfen:



#include <avr/io.h>
#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert
(z.B. durch Übergabe als Parameter zum Compiler innerhalb
des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
"nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 1000000 definiert"
#define F_CPU 16000000UL /* Quarz mit 1,000000 Mhz */
#endif
#define BAUD 9600UL // Baudrate

// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.

#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
#endif

#include <util/delay.h> /* in älteren avr-libc Versionen <avr/delay.h> */
void long_delay(uint16_t ms) {
for(; ms>0; ms--) _delay_ms(1);
}

/* USART-Init beim ATmega16 */

void uart_init(void)
{
UCSRB |= (1<<TXEN); // UART TX einschalten
UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1

UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
}

int main( void )
{

PORTD = 0x012;
DDRD = 0x012;//->PortD (LED-Segment) als Ausgabe definiert

uart_init();


// bei neueren AVRs steht der Status in UCSRA/UCSR0A/UCSR1A, hier z.B. fuer ATmega16:
while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
{
}

while(1)
{
UDR = 'a'; /* schreibt das Zeichen a auf die Schnittstelle */

if(PORTD == 0x00){ //blink LED
PORTD = 0x04;
}
else{
PORTD = 0x00;
}
long_delay(100); //warte 100ms

UDR = 'b'; /* schreibt das Zeichen b auf die Schnittstelle */

if(PORTD == 0x00){ //blink LED
PORTD = 0x04;
}
else{
PORTD = 0x00;
}
long_delay(100); //warte 100ms

UDR = 'c'; /* schreibt das Zeichen c auf die Schnittstelle */

if(PORTD == 0x00){ //blink LED
PORTD = 0x04;
}
else{
PORTD = 0x00;
}

long_delay(1000); //warte 1000ms
}


return 0;
}

PicNick
12.03.2010, 16:56
Kopire doch einfach mal das Beispiel rein:
http://www.rn-wissen.de/index.php/Sourcevergleich#GCC_.28Hello.2C_world.29

Das sollte funzen. dann siehst du vielleicht selbst, wo unterschiede liegen

damfino
12.03.2010, 18:13
Ich hab vor ein paar Tagen auch mit dem UART und nicht funktionierenden Libraries gekämpft, meine Lösung stammt praktisch aus dem Atmega Datenblatt:

Baudrate kann man universell über define einstellen, oder direkt den Wert für ubrr aus dem Datenblatt übernehmen.



#define BAUD 9600
#define UBRR_BAUD ((F_CPU/(16UL*BAUD))-1)

UBRRH = (unsigned char)(UBRR_BAUD>>8);
UBRRL = (unsigned char)UBRR_BAUD;
UCSRB = (1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);


Ein while (!(UCSRA & (1<<UDRE))) vor jedem Senden schadet nicht damit nichts verloren geht, mein Programm wird trotzdem ohne merkbare Verzögerung abgearbeitet.

Weiters schalte ich die Ports anders, mit PORTD |= (1<<PD1), bzw PORTD &= ~ (1<<PD1), kann sein dass du mit deinem Befehl die Uart Schnittstelle als digitalen Ausgang überschreibst.

LG

ChristophB
12.03.2010, 19:45
kann sein dass du mit deinem Befehl die Uart Schnittstelle als digitalen Ausgang überschreibst.

jap genau das hab ich gemacht... leider funktioniert es auch ohne diesen fehler nicht.

das beispiel habe ich ausprobiert.... habe aber auch dabei einen dauer high zustand am Tx Pin. wird danwohl warscheinlich an meiner hardware liegen...was dann allerdings bedeuten würde das der uC defekt ist... ich werde diesen morgen austauschen , mal schaun was dabei herauskommt.

--->edit<-------

So das Problem lag wohl anscheinend an einem defekten uC. nach dem ich den atmega32 ausgetauscht hatte kahmen ohne Probleme die Datenpakete an.