PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UART am ATMega644P



JellbieO
05.03.2009, 15:18
Hallo Leute,

wie der eine oder andere ja vll noch weiß ist mein Team nach wie vor am Projekt "autonomer Roboter" dabei und neigt sich langsam dem Ende.

Nächsten Donnerstag, also dem 19.03.2009, ist Abgabe Termin, somit bleibt nur noch wenig Zeit :-k

Wir stehen allerdings erneut vor einem Problem - dem UART

Wenn wir versuchen ein einziges Zeichen zu senden und abzufangen, kommt zwar etwas an, allerdings meist nicht das gewünschte Zeichen wie wir eigentlich wollten.

Eigentlich von uns gewollt ist eine Standard-Übertragung
8 Datenbits, 1 Stopbit, Parity None, Asynchronous Modus, bei 9600 BAUD


Unser leider gescheitertes Vorgehen:


- ATmega644P-20PU
- Externer 16Mhz Quarz
- ISP-Schnittstelle nach RN Standard
- verwendeter UART#1
- MAX232 mit Kondensatoren
- NULL-Modem Kabel
- Stecker (RXD & TXD)


Initialisierung des UART1


unsigned int baud=9600;

UBRR1H = (F_CPU / 16* (unsigned char)(baud>>8)-1)>>8;
UBRR1L = (F_CPU / 16* (unsigned char)(baud>>8)-1);
UBRR1 = 103;

UBRR1 = (F_CPU / (BAUD * 8L) - 1);
UCSR1A = (0<<U2X1);
UCSR1B = (1<<TXEN1);
UCSR1C = (0<<UMSEL10);
UCSR1C = (0<<UPM11) | (0<<UPM10);
UCSR1C = (0<<USBS1);
UCSR1C = (0<<UCSZ12) | (1<<UCSZ11) | (1<<UCSZ10);
UCSR1C = (0<<UCPOL1);



Senden eines Zeichens


void USART_Transmit( unsigned char data )
{

while ( !( UCSR1A & (1<<UDRE1)) )
;
UDR1 = data;
}

USART_Transmit(65);


Sämtliche Programmeinstellungen wurden kontrolliert, ebenfalls was die Baudrate von 9600 betrifft etc. Im Datenblatt des ATmega644P wurden wir unter anderem fündig was UBRR1 = 103; betrifft


Eigentlich sollte das ganze nun ein großes A übertragen.
Seit 2 Wochen probieren wir nun schon herum und kommen leider nicht weiter.

Wir würden uns wirklich über jeden Tipp freuen.
Hoffe natürlich bei möglichen Fragen schnell Antworten geben zu können.

Hubert.G
05.03.2009, 16:16
Wenn ihr die Init so schreibt



unsigned int BAUD=9600;
#define F/CPU 16000000L

UBRR1 = (F_CPU / (BAUD * 8L) - 1);
UCSR1B = (1<<TXEN1);
UCSR1C = (1<<UCSZ11) | (1<<UCSZ10);

dann sollte es funktonieren
Das xxx =(0<<xxx) ist Unsinn

JellbieO
05.03.2009, 16:50
Alles klar, ich werds direkt ausprobieren und mich anschließend melden.


dann sollte es funktonieren
Das xxx =(0<<xxx) ist Unsinn


geb ich dir natürlich vollkommen Recht. Diente eigentlich auch zwischenzeitlich nur dazu damit wir die ganzen Möglichkeiten durchgehen konnten - Aus reinster Verzweifler heraus ;)

Aber ich danke dir schonmal soweit, melde mich

JellbieO
05.03.2009, 17:16
Habe nun folgendes geschrieben, allerdings wurdert mich das F/CPU - War das kein Rechtscheibfehler (F_CPU) ?


Compiler meckert:



#include <avr/io.h>
#define F/CPU 16000000L //definiert den CPU Takt

void USART_Transmit( unsigned char data )
{
while ( !( UCSR1A & (1<<UDRE1)) )
;
UDR1 = data;
}


int main()
{
unsigned int BAUD=9600;
UBRR1 = (F_CPU / (BAUD * 8L) - 1);
UCSR1B = (1<<TXEN1);
UCSR1C = (1<<UCSZ11) | (1<<UCSZ10);
while (1)
{
USART_Transmit(65);
}

return 0;
}



Was habe ich falsch gemacht?

Nach wie vor für jede Hilfe dankbar

Hubert.G
05.03.2009, 17:40
Das war sicher ein Schreibfehler von mir, natürlich F_CPU
Ausserdem muss es heissen UBRR1 = (F_CPU / (BAUD * 16) - 1);

JellbieO
05.03.2009, 17:55
Hab nun das geschrieben und das Funktioniert leider immernoch nix.
kommt scheinbar gar nix an...



#include <avr/io.h>
#define F_CPU 16000000L //definiert den CPU Takt

void USART_Transmit( unsigned char data )
{
while ( !( UCSR1A & (1<<UDRE1)) )
;
UDR1 = data;
}


int main()
{
unsigned int BAUD=9600;
UBRR1 = (F_CPU / (BAUD * 16) - 1);

UCSR1B = (1<<TXEN1);
UCSR1C = (1<<UCSZ11) | (1<<UCSZ10);
while (1)
{
USART_Transmit(65);
}

return 0;
}



EIn anderes Beispiel unter Bascom allerdings funktioniert einwandfrei, somit schonmal kein Hardwarefehler denke ich.



$regfile = "m644pdef.dat"


$crystal = 16000000
$baud1 = 9600

Open "com2:" For Binary As #2


Do
Waitms 800
Print #2 , "**** Hier steht was ****"
Loop
End


Irgendwie wirds langsam echt deprimierend...
Hat sonst noch wer eine Idee oder sieht einfach den Fehler?

Dankbar für jede Hilfe

Hubert.G
05.03.2009, 18:33
Ich sehe jetzt auch keinen Fehler, ausser das du dauernd ausgibst ohne wait.

Hubert.G
05.03.2009, 18:48
Das kommt davon wenn man schlampig abschreibt und nicht kopiert
UBRR1 = (F_CPU / (BAUD * 16L) - 1);

JellbieO
05.03.2009, 18:49
Well Done Man :)

Könnte dich knutschen O:)


Es funktioniert!! Danke Dir!!

und natürlich für diejenigen die dasselbe Problem haben denen will ich natürlich die Lösung nicht vorenthalten:



#include <avr/io.h>
#include <avr/delay.h>
#define F_CPU 16000000L //definiert den CPU Takt

void USART_Transmit( unsigned char data )
{
while ( !( UCSR1A & (1<<UDRE1)) )
;
UDR1 = data;
}


int main()
{
unsigned int BAUD=9600;
UBRR1 = (F_CPU / (BAUD * 16L) - 1);

UCSR1B = (1<<TXEN1);
UCSR1C = (1<<UCSZ11) | (1<<UCSZ10);
while (1)
{
_delay_ms(500);
USART_Transmit(65);
}

return 0;
}