Forum: Mikrocontroller und Digitale Elektronik UART am ATmega644P


von Jellbie*O (Gast)


Lesenswert?

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.

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 UART #1
############
1
   unsigned int baud=9600;    
2
3
   UBRR1H = (F_CPU / 16* (unsigned char)(baud>>8)-1)>>8; 
4
   UBRR1L = (F_CPU / 16* (unsigned char)(baud>>8)-1); 
5
   UBRR1 = 103; 
6
7
   UBRR1  = (F_CPU / (BAUD * 8L) - 1); 
8
   UCSR1A = (0<<U2X1); 
9
   UCSR1B = (1<<TXEN1); 
10
   UCSR1C = (0<<UMSEL10); 
11
   UCSR1C = (0<<UPM11) | (0<<UPM10); 
12
   UCSR1C = (0<<USBS1); 
13
   UCSR1C = (0<<UCSZ12) | (1<<UCSZ11) | (1<<UCSZ10); 
14
   UCSR1C = (0<<UCPOL1);


##### Senden eines Zeichens
############
1
void USART_Transmit( unsigned char data ) 
2
{ 
3
4
while ( !( UCSR1A & (1<<UDRE1)) ) 
5
; 
6
UDR1 = data; 
7
} 
8
9
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.

von Johannes M. (johnny-m)


Lesenswert?

Jellbie*O wrote:
>    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);
Das ist doch wohl nicht Dein Ernst, oder? Vielleicht mal überlegt, was 
passiert, wenn man einem Register einen Wert zuweist und in der nächsten 
Zeile einen anderen? Das, was da steht, ist kompletter Schwachsinn! Und 
das ist noch euphemistisch ausgedrückt...

Außerdem ist das ganze 0 << irgendwas nicht wirklich guter 
Programmierstil.

von Jellbie*O (Gast)


Lesenswert?

1
#include <avr/io.h> 
2
#define F_CPU 16000000L   //definiert den CPU Takt 
3
4
void USART_Transmit( unsigned char data ) 
5
{ 
6
   while ( !( UCSR1A & (1<<UDRE1)) ) 
7
   ; 
8
    UDR1 = data; 
9
} 
10
11
12
int main() 
13
{ 
14
   unsigned int BAUD=9600; 
15
   UBRR1 = (F_CPU / (BAUD * 16) - 1); 
16
17
   UCSR1B = (1<<TXEN1); 
18
   UCSR1C = (1<<UCSZ11) | (1<<UCSZ10); 
19
   while (1) 
20
   { 
21
      USART_Transmit(65); 
22
   } 
23
24
   return 0; 
25
}

Funktioniert auch nicht. Hat wer ein Idee? - abgesehen von meinem 
Vorposter welcher selbst keine Ahnung hat sondern anscheinend mehr drauf 
aus ist seine Beiträge-Statistik zu erhören.

von spess53 (Gast)


Lesenswert?

Hi

Im Datenblatt ist doch ein Beispiel. Mal das Testen.

>Funktioniert auch nicht. Hat wer ein Idee? - abgesehen von meinem
>Vorposter welcher selbst keine Ahnung hat sondern anscheinend mehr drauf
>aus ist seine Beiträge-Statistik zu erhören.

Wieso? Wo er Recht hat, hat er Recht.

MfG Spess

von Justus S. (jussa)


Lesenswert?

Jellbie*O wrote:

> Funktioniert auch nicht. Hat wer ein Idee? - abgesehen von meinem
> Vorposter welcher selbst keine Ahnung hat sondern anscheinend mehr drauf
> aus ist seine Beiträge-Statistik zu erhören.

bei so einer Reaktion bekommt man echt Lust zu Antworten...

ich riskiere es trotzdem mal: µC ausbauen und Tx mit Rx verbinden, dann 
mit dem PC was hinschicken, was dann zurückkommen sollte...so könnte man 
mal Hardware-Fehler ausschliessen...

von Johannes M. (johnny-m)


Lesenswert?

Justus Skorps wrote:
> bei so einer Reaktion bekommt man echt Lust zu Antworten...
Tja, wenn er es selber besser weiß, warum fragt er dann?

> ich riskiere es trotzdem mal:
Eigentlich schade... Aber vermutlich wird er Dir nichts anderes sagen 
als über mich, denn Du bist ja auch angemeldet und nur darauf aus, Deine 
Beitragszahl hochzupuschen!

Ich kann langsam die langjährigen Teilnehmer hier verstehen, die nicht 
mehr angemeldet posten, damit keiner behaupten kann, sie wären 
Vielschreiber...

von holger (Gast)


Lesenswert?

>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.

Dann stimmt die Baudrate nicht.

von Jellbie*O (Gast)


Lesenswert?

Hardware-Fehler sind auszuschließen weil ein Beispiel von Bascom
einwandfrei funktioniert.
1
$regfile = "m644pdef.dat"
2
$crystal = 16000000
3
$baud1 = 9600
4
5
   Open "com2:" For Binary As #2
6
    Do
7
      Waitms 800
8
      Print #2 , "**** Hier steht was ****"
9
    Loop
10
End

somit brauche ich die uc nicht testen oder?
Trotzdem danke für den Tipp. :)

Was die beiligenede Dokumentation betrifft...
das Beispiel dort oben ist bereits teil der Dokumentation und 
funktioniert leider nicht.

USART_TRANSMIT wurde 1:1 übernommen und halt an den UART1 angepasst, 
weil der ATMega644P 2 UARTs besitzt.

Vielen Dank schonmal für die vielen Ideen.
Sonst vielleicht noch wer eine Idee?

Wäre echt für jeden Tipp dankbar

von Justus S. (jussa)


Lesenswert?

Jellbie*O wrote:

>    UBRR1 = (F_CPU / (BAUD * 16) - 1);

sprengt (BAUD * 16) hier nicht die int-Grenze?

von Peter D. (peda)


Lesenswert?

Jellbie*O wrote:
> Hardware-Fehler sind auszuschließen weil ein Beispiel von Bascom
> einwandfrei funktioniert.

Und warum nimmste nicht einfach nen funktionierenden C-Code ausm Web?

Z.B.:
Beitrag "AVR-GCC: UART mit FIFO"


Peter

von Jellbie*O (Gast)


Lesenswert?

Weils leider nicht funktionierte....


Hab in einem anderen Forum allerdings nun Hilfe gefunden.
Ich will keine Werbung machen oder so aber deswegen poste ich hier 
einmal das Ergebnis und nicht den Link.


Ich will das andere auch etwas davon haben, weil hasse es meistens das 
Topicersteller nur wissen wie die ANtwort lautet  - liegt ja nicht im 
Sinne eines Forums
1
#include <avr/io.h> 
2
#include <avr/delay.h>
3
#define F_CPU 16000000L   //definiert den CPU Takt 
4
5
void USART_Transmit( unsigned char data ) 
6
{ 
7
   while ( !( UCSR1A & (1<<UDRE1)) ) 
8
   ; 
9
    UDR1 = data; 
10
} 
11
12
13
int main() 
14
{ 
15
   unsigned int BAUD=9600; 
16
  UBRR1 = (F_CPU / (BAUD * 16L) - 1);
17
18
   UCSR1B = (1<<TXEN1); 
19
   UCSR1C = (1<<UCSZ11) | (1<<UCSZ10); 
20
   while (1) 
21
   { 
22
       _delay_ms(500);
23
      USART_Transmit(65); 
24
   } 
25
26
   return 0; 
27
}

Danke an alle die mir Tipps gaben und ja mir viele Denkanstöße gaben!
Danke! :)

von Lasse S. (cowz) Benutzerseite


Lesenswert?

Und an dem delay soll's gelegen haben? (Oder hab ich noch eine Änderung 
übersehen?)

Gruß, CowZ

von Jellbie*O (Gast)


Lesenswert?

man beachte die L`s


und ja weil das Programm zu schnell durchläuft

von Justus S. (jussa)


Lesenswert?

Jellbie*O wrote:
> man beachte die L`s

Justus Skorps wrote:
> sprengt (BAUD * 16) hier nicht die int-Grenze?

von spess53 (Gast)


Lesenswert?

Hi

>      _delay_ms(500);
>      USART_Transmit(65);

Das soll wohl ein Scherz sein. Wenn das die Lösung sein soll, habe ich 
bis jetzt immer alles falsch gemacht. Nämlich ohne Wartezeit.

MfG Spess

von Lasse S. (cowz) Benutzerseite


Lesenswert?

Hi,

stimmt, das L hatte ich übersehen :)

aber ist es nicht auch sträflich mit Longs zu rechnen und das ganze dann 
"einfach so" auf nen int zu übertragen? Und wär's nich cleverer, das 
ganze ohne den int zu machen, sondern einfach mit defines? dann kann der 
compiler gar nicht erst auf die idee kommen, das als variable 
zubetrachten...

Gruß, CowZ

von Jellbie*O (Gast)


Lesenswert?

// Nachtrag

Hätte nie gedacht das es einem einzigen L liegen könnte

Wo genau nun der Unterschied ist bei F_CPU 16000000L und dem UL am Ende
ist weiß ich immernoch net. Dasselbe bei der BAUD-Rate mit dem L.

Auf jeden Fall wirkte sich genau das auf das Ergebnis aus.

Nun bin ich in der lage ein einziges ZEichen zu senden und muss es 
nurnoch schaffen nen Buchstaben angeben zu können und daraus soller dann 
ja die Zahl schreiben.

Kann man da nicht einfach mit Char einen Buchstaben annehmen und dann 
einfach als INT übergeben?`

von holger (Gast)


Lesenswert?

USART_Transmit('A');

von Jellbie*O (Gast)


Lesenswert?

Thanks a lot, werd dann mal eine Funktion schreibe´n damit man gleich 
nen ganzen String angeben kann.


Tja und das mit der Pause ... auch wenns mir keiner glauben mag aber ich 
kann nur schreiben wie es ist... ich musste mind. 1ms angeben

Anderenfalls lief gar nix.

von Klaus (Gast)


Lesenswert?

>Funktioniert auch nicht. Hat wer ein Idee? - abgesehen von meinem
>Vorposter welcher selbst keine Ahnung hat sondern anscheinend mehr drauf
>aus ist seine Beiträge-Statistik zu erhören.

frecher Hund!

von Peter D. (peda)


Lesenswert?

Jellbie*O wrote:
> Weils leider nicht funktionierte....

Dann hast Du was falsch gemacht, auf meinem ATmega644 funktioniert er 
ja.

Kann sein, daß Du ihn nicht verstehst und deshalb falsch verwendest.
Wenn Du aber keine Lust hast, mir dazu Fragen zu stellen, kann ich Dich 
nicht dazu zwingen.

Dein erstes Posting nährt allerdings den Verdacht, daß Du schon mal 
grundsätzliche Probleme mit der Programmiersprache C hast 
(Mehrfachzuweisungen sind witzlos).


Peter

von Jellbie*O (Gast)


Lesenswert?

hab den ATmega644P und nicht den ATmega644

Eventueller Unterschied?

von ahem (Gast)


Lesenswert?

Datenblatt ?

von Peter D. (peda)


Lesenswert?

Jellbie*O wrote:
> hab den ATmega644P und nicht den ATmega644
>
> Eventueller Unterschied?

Haupsächlich nur die 2. UART.

Hast Du das Beispiel ausprobiert?
Hast Du Quarz und Baudrate definiert?
Was hat nicht funktioniert?


Peter

von Tian (Gast)


Lesenswert?

>Nächsten Donnerstag, also dem 19.03.2009, ist Abgabe Termin, somit
>bleibt nur noch wenig Zeit.

keien Panik, nächster Donnerstag ist erst der 12.3.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.