PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UART funktioniert nicht



semicolon
27.04.2007, 17:29
Hallo Leute

Ich möchte eigentlich nur zuerste einmal einen einzigen Buchstaben über die UART an den PC senden. Aber mit folgendem Code funktioniert das nicht.

#include <avr/io.h>

#define F_CPU 16000000

#define UART_BAUD_RATE 9600

#define UBRR_BAUD ((F_CPU/(16*UART_BAUD_RATE))-1)





int main( void )
{
UCSRB |= (1<<TXEN);
UCSRC |= (1<<URSEL)|(1<<UCSZ0) | (1<<UCSZ1);
UBRRH = 0;
UBRRL = 103;

while (!(UCSRA & (1<<UDRE))) {
}

UDR = 'c';

return 0;
}

Habe eine AVR Atmega16 mit 16MHz Quarz

Was habe ich falsch gemacht???

Danke

franzl
27.04.2007, 19:05
Hi,
kann sein dass ich mich täusche, aber werden in C Buchstaben und Wörter nicht " gekennzeichnet.
mfg franz

PicNick
27.04.2007, 19:08
Schau mal da bei den GCC-Beispielen
https://www.roboternetz.de/wissen/index.php/Sourcevergleich

CowZ
27.04.2007, 19:50
Hi,

"Buchstaben", also Chars werden mit 'c' gekennzeichnet, Strings (automatisch mit \0 terminiert) werden mit "foobar" angegeben.

Ich könnte mir vorstellen, dass es helfen würde, nach dem
UDR = 'c';
noch ein while(1); einzubauen, damit der Controller noch sendet und nicht gleich resetted (was auch immer er dann macht, es ist vermutlich nichts schönes).

Ansonsten Baudrate kontrollieren:
- UBBRH / UBBRL nach Datenblatt
- Taktfrequenz des µC richtig? (wirklich 16 MHz?, Fuseeinstellungen)
- Max232 überprüfen

Gruß, CowZ

Superhirn
27.04.2007, 19:53
Hallo.

also so hab ichs gemacht: http://www.gruebler.at/index.php?id=126

schaus dir mal durch.
UBRRH = 0;
UBRRL = 103; schaut unschön aus. du berechnest eh oben mit einem #define den richtigen wert. und dann so einsetzten:

UBRRH = (uint8_t) (UBRR_BAUD>>8);
UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff);
--------------
while (!(UCSRA & (1<<UDRE))) {
}
solltest du zu
while (!(UCSRA & (1<<UDRE))) {
;
}
tauschen da gcc sonst die schleife wegoptimiert.

lg
Thomas

semicolon
27.04.2007, 22:01
Mit Hilfe dieses Links, habe ich folgenden Source verwendet:
https://www.roboternetz.de/wissen/index.php/Sourcevergleich

#include <avr/io.h>

#define F_CPU 16000000
#define USART_BAUD_RATE 9600
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)

//-----------------------------------------------------
void _writeString (const char *string)
{
while (*string)
{
while (!(UCSRA & (1<<UDRE)))
{;}

UDR = *string++;
}
}

//-----------------------------------------------------
int main()
{
char bZeichen;

UCSRB = (1 << RXEN) | (1 << TXEN);
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
UBRRL = (unsigned char) USART_BAUD_SELECT;

while (1)
{
while ( !(UCSRA & (1 << RXC)) )
{;}
bZeichen = UDR;

while (!(UCSRA & (1 << UDRE)))
{;}
UDR = bZeichen;
}

return 0;
}


Aber leider tut sich gar nichts am Terminal. Da bin ich mir sicher, dass alles richtig eingestellt ist. 8-Bit, 1 Stopp-Bit, no parity and no flowcontrol, Baud-Rate 9600!!!
Dann kann ich wirklich nichts anderes einstellen.

Hat jemand noch eine Idee, was hier nicht geht???

Superhirn
28.04.2007, 06:49
Du hast UBBRH vergessen:
UBRRH = (uint8_t) (UBRR_BAUD>>8);
UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff);

Schau mal meine sources an. die wurden speziell auf ATmega16 und atmega32 verwendet. die haben shcon unmengen an bytes geschickt.

wenn dein controller kein zeichen empfangt, kann er auch nichts senden. sendn ist am anfang einfacher als empfangen.

while (!(UCSRA & (1 << UDRE)))
{;}
UDR = '#';

sollte machen dass du auch ein # empfangs wenn du nichts empfangst.