PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : USART korrekt auslesen



damnit
04.11.2013, 16:02
Hallo zusammen,

habe ein Problem mit folgendem Quellcode:



#ifndef _UART_H_
#define _UART_H_

#include <avr/io.h>

extern void uart_init(void);



static inline int
uart_putc (const uint8_t c)
{
// Warten, bis UDR bereit ist für einen neuen Wert
while (!(UCSRA & (1 << UDRE)))
;

// UDR Schreiben startet die Übertragung
UDR = c;

return 1;
}

static inline uint8_t
uart_getc_wait(void)
{
// Warten, bis etwas empfangen wird
while (!(UCSRA & (1 << RXC)))
;

// Das empfangene Zeichen zurückliefern
return UDR;
}

static inline int
uart_getc_nowait(void)
{
// Liefer das empfangene Zeichen, falls etwas empfangen wurde; -1 sonst
return (UCSRA & (1 << RXC)) ? (int) UDR : -1;
}

#endif /* _UART_H_ */

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>



#define BAUDRATE 38400UL

//int a;
volatile unsigned char a = 0x00;

void uart_init()
{
uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);

UBRRH = (uint8_t) (ubrr>>8);
UBRRL = (uint8_t) (ubrr);

// UART Receiver und Transmitter anschalten
// Data mode 8N1, asynchron
UCSRA = (1 << RXC) | (1 << TXC);
UCSRB = (1 << RXEN) | (1 << TXEN) | (1<<RXCIE);
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);

// Receive-Buffer leeren
do
{
UDR;
}
while (UCSRA & (1 << RXC));

DDRD |= (1<<PD6); // PortD als Ausgang deklarieren
//PORTD = 0x00; // Ports auf LOW schalten

}


// Einen 0-terminierten String übertragen.

void uart_puts (const char *s)
{
do
{
uart_putc (*s);
}
while (*s++);
}



// Interupt wartet, bis Empfangsbit gesetzt wird und führt dann Routine aus

ISR(USART_RXC_vect)
{
a = UDR;
//PORTD ^=(1<<PD6);
if (a == 1)
{
PORTD |= (1<<PD6);
}
else
{
PORTD &=~(1<<PD6);
}

}





int main(void)
{

uart_init();
sei();




while (1) {

while (!(UCSRA & (1 << RXC)));

}



return 0;
}

Und zwar sende ich Zeichen mittels VB über die serielle Schnittstelle an meinen ATmega8.
In VB befinden sich zwei Buttons, der eine Sendet "1", der andere "0".
Leider bekomme ich es nicht auf die Reihen, dass PD6 auf High schaltet, wenn ich "1" sende und auf Low bei der "0".
Togglen des PD6 funktioniert, sprich die Interrupt Routine wird auch ausgeführt.
Mit BASIC läuft es ohne Probleme, nur mit C bekomm ich es einfach nicht auf die Reihe.

Für eure Hilfe bedanke ich mich schon mal im Voraus.
mfg
damnit

Che Guevara
04.11.2013, 16:35
Hi,

ich nehme an, du sendest die "0" bzw. "1" im ASCII Format? Dann musst du auch auf den ASCII-Wert prüfen, oder du sendest eben im Raw-Format (binär), dann klappts auch so.

Gruß
Chris

damnit
05.11.2013, 14:32
Hi Che Guevara,
danke für die schnelle Hilfe.
Der Fehler lag in dem von dir beschriebenen Problem und der falschen Baudrate.
mfg
damnit