PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : USART mit Atmega88 16Mhz



robo-sebi
28.06.2009, 20:49
Hallo,

das folgende Skript soll auf dem Terminal "Hallo" schreiben. Leider kommen keine Signale zum Terminal. Es ist definitiv kein Hardwarefehler.
Skript:
main.c:
#include <avr/io.h>
#include <util/delay.h>
#include "usart.h"


void delay_ms(uint16_t ms)
{
for(uint16_t t= 0; t <=ms; t++)
_delay_ms(1);
}

int main()
{
//USART konfigurieren
init_usart();
while(1){//USART-Ausgabe
usart_sendchar('H');
usart_sendchar('a');
usart_sendchar('l');
usart_sendchar('l');
usart_sendchar('o');
}
return(0);
}
usart.h:


#define USART_RECEIVE_COMPLETE() (UCSR0A & RXC0)
#define UART_BAUD_RATE 38400L
#define UART_BAUD_CALC(UART_BAUD_RATE,F_CPU) ((F_CPU)/((UART_BAUD_RATE)*16L)-1)


void init_usart();
void usart_sendchar(char c);

usart.c:

#include <avr/io.h>
#include <util/delay.h>
#include "usart.h"

void init_usart(){
//Eingabeparameter einstellen - Aktivierung
UBRR0H = (uint8_t) (UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);
UBRR0L = (uint8_t) UART_BAUD_CALC(UART_BAUD_RATE,F_CPU);

UCSR0A = 0x00;
UCSR0B = 0;
//Senden aktivieren
UCSR0B |= TXEN0;
//Empfangen aktivieren
UCSR0B |= RXEN0;
//Konfiguration der Bitlaenge
UCSR0C = UCSZ01 | UCSZ00; // 8-Bit character length
}

void usart_sendchar(char c){
while(!(UCSR0A & UDRE0));//Warten bis UDR bereit ist
UDR0 = c;
}


Es wäre nett, wenn jemand mal drüber gucken könnte, wo der Fehler liegt.


MfG Sebastian

Besserwessi
28.06.2009, 21:47
Der IO Port von TX muß noch als Ausgang definiert werden.

McJenso
28.06.2009, 22:11
Hallo fast Nachbar,

UCSR0B |= TXEN0;

was zur Hölle machst du da?

Schau dir mal diese Zuweisung an.
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
Im Datenblatt findest du Beispiele zur Initialisierung. Sonst kannst du auch mal unter dem Stichwort Bitoperationen suchen.

Ach und lass die Finger vom DDR. In dem Moment, indem du das TXEN-Bit setzt, wird der Pin von der normalen Funktion gelöst.

Gruß

Jens

robo-sebi
30.06.2009, 17:05
Hallo Jens und Besserwessi,

vielen Dank für eure Mühe. Es war mir eine große Hilfe. Dass mit den Bitoperatoren kenne ich auch, ich hatte nur den Code von einem anderen C-Skript genommen und gedacht, dass die Konstanten weitestgehend gleich sind. Naja, ich habe es verbessert. Doch zeigt das Terminal nur lauter komische Zeichen trotz korrekter Einstellung.
Mein verbesserter Code (ohne <?php und ?>):
main.c:
[php:1:535e303ed1]
#include <avr/io.h>

#include <util/delay.h>

#include "usart.h"







int main()

{

//USART konfigurieren

init_usart();

usart_write_crlf();

while(1){//USART-Ausgabe

usart_sendchar('H');

usart_sendchar('a');

usart_sendchar('l');

usart_sendchar('l');

usart_sendchar('o');

usart_write_crlf();

}

return(0);

}
[/php:1:535e303ed1]
usart.c:
[php:1:535e303ed1]
#include <avr/io.h>

#include <util/delay.h>

#include "usart.h"



void init_usart(){

//Eingabeparameter einstellen - Aktivierung

UBRR0H = (uint8_t) (UART_BAUD_CALC(UART_BAUD_RATE,16000000)>>8);

UBRR0L = (uint8_t) UART_BAUD_CALC(UART_BAUD_RATE,16000000);

UCSR0A = 0x00;

DDRD = 10;

//Senden aktivieren

//Empfangen aktivieren

UCSR0B = (1<<RXEN0)|(1<<TXEN0);

//Konfiguration der Bitlaenge

UCSR0C = (3<<UCSZ00); // 8-Bit character length

}



void usart_sendchar(uint8_t data){

while(!( UCSR0A & (1<<UDRE0)));//Warten bis UDR bereit ist

UDR0 = data;

}

void usart_write_crlf()

{

usart_sendchar(USART_CHAR_CR);

usart_sendchar(USART_CHAR_LF);

}
[/php:1:535e303ed1]
und zu guter letzt:
usart.h:

[php:1:535e303ed1]// Macros



#define UART_BAUD_RATE 38400L

#define UART_BAUD_CALC(UART_BAUD_RATE,F_CPU) ((F_CPU)/((UART_BAUD_RATE)*16L)-1L)

#define USART_CHAR_LF 10L

#define USART_CHAR_CR 13L





void init_usart();

void usart_sendchar(uint8_t data);

void usart_write_crlf();
[/php:1:535e303ed1]
Liegt es an den Fuses oder wodran kann der Fehler liegen?
(Laut Datenblatt müsste alles funktionieren!)

MfG Sebastian
PS: Ich komme auch aus Lippe (also doch Nachbar ;-) )

McJenso
30.06.2009, 19:31
Hallo,

komische Zeichen deuten meist auf eine falsch eingestellte Baudrate hin.
Das kann an der Initialisierung liegen oder auch an den Fusebits. Du scheinst einen 16MHz Quarz am Controller zu haben. Da müssen natürlich die Fusebits entsprechend eingestellt sein, sonst läuft der weiter auf dem internen Takt. Die Initialisierung sieht soweit okay aus. Ich gehe davon aus, dass die Einstellungen am PC passen 38,4k 8N1.

Bielefeld ist von mir hier in Leo auch nur einen Steinwurf entfernt. Dafür kann ich von hier den Hermann nicht sehen :-(

Gruß

Jens

robo-sebi
01.07.2009, 21:33
Nienhagen? Schuckenbaum? Greste? Asemissen? Bechterdissen?
Ich komme auch aus Leo und wohne bei den 3 Windkraftanlagen. Es könnte sogar sein, dass ich bei dir die Stromzähler abgelesen habe (Ferienjob - Ablesegebiet: Teile von Schuckenbaum und Nienhagen- falls du dort wohnst).

Also mit dem Mikrocontroller habe ich es jetzt zu Stande bekommen, dass "Hallo" im Terminal erscheint. Seltsamerweise muss ich die Baudrate im Terminal auf 4800 stellen für die einprogrammierten 38400. Die Fusebits müssten auch passen (Einstellung: Ext Quarz über 8 Mhz - leider keine 16Mhz-Einstellungsmöglichkeit).

MfG Sebastian

McJenso
01.07.2009, 21:54
Hallo,


auf 4800 stellen für die einprogrammierten 38400
Das ist Faktor 8.
Nachtigal ich hör dir trapsen.
Der AtMega 88 hat in den Fusebits ein CKDIV8 Bit. Dadurch wird der Takt durch 8 geteilt.
Ich wohne im Ortsteil Krentrup. Quasi auf'm Feld, aber das ist hier ja fast bei jedem so :-)
Gruß

Jens