Hallo,

ich habe mit meinem Mega32@8MHz externer Takt starke probleme mit USART.
Letztendlich soll es eine USART-Klasse mit Interruptbassierendem Eingangsbuffer werden, aber soweit komm ich garnicht.
Der Buffer scheint richtig zu funktionieren, wenn ich direkt vom Controller aus diesen Befülle funtkioniert alles erwartungsgemäß.

Es muss also an was anderem liegen.
Ich sende z.b. 1-29 (Dezimal, nicht die Zahlen) und dann gibt er mir reproduzierbar immer nur 1,2,3,4,9,14,19,24,29 aus - und das egal ob ich meinen Empfangsbuffer befülle über den Interrupt, oder direkt aus dem Register lese und sofort ausgebe.
Das gleiche ist z.b. mit a-l, da kommt jedes mal a,b,c,d,i,l raus.

Ich habe es mal versucht so kurz wie möglich zu halten:

Empfangsteil:
Code:
	static inline uint8_t _usart_get_UDR(void) {
 		#ifdef USART_RX_BUFFER	//mit rx-buffer
 			uint8_t temp; 			
			do {
				temp=ringbuffer_get(&usart_buffer_rx_rb);
			} while (usart_buffer_rx_rb.nothing_to_read==1);
 			
 		//	printf("|%s|",temp);
			return temp;
 		#endif
 		
 		#ifndef USART_RX_BUFFER	//ohne rx-buffer
 			while (!(UCSRA &(1<<RXC)));
 			uint8_t temp=UDR;
 			usart_putbyte(temp);
 			return temp;
 		#endif
	}

Initialisierung:
Code:
void usart_init(unsigned long baud) {
	UCR =(1 << RXEN) | (1 << TXEN );				//RXEN, TXEN
	#ifdef USART_RX_BUFFER
		UCR |=(1<<RXCIE);
	#endif
	
	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);	//8N1 asyncron 
	UBRR=((F_CPU / (16L * baud)) - 1);			//Baudrate

    do { UDR; } while (USR & (1 << RXC));		//eventuellen buffer entleeren
    
    stdout = &uart_str;							//"pipe" für printf

	#ifdef USART_RX_BUFFER
	    ringbuffer_init (&usart_buffer_rx_rb, usart_buffer_rx, USART_BUFFER_RX_SIZE);
	#endif
//    ringbuffer_init (&usart_buffer_tx_rb, usart_buffer_tx, USART_BUFFER_TX_SIZE);
}

Put und Get-Funktionen
Code:
/**
*	Put-Funktionen
*/
int usart_putchar (char c, FILE *stream) {
	if (c == '\n') usart_putchar ('\r', stream);	//häng noch nen \r davor...

	#ifdef USART_DROP_PACKET_AFTER
		int i=USART_DROP_PACKET_AFTER;
		while ((!(UCSRA & (1<<UDRE))) & (i>0))  i--;
	#endif

	#ifndef USART_DROP_PACKET_AFTER
		while (!(UCSRA & (1<<UDRE)));
	#endif

	UDR = c;										//sende char
	return 0;
}


void usart_putbyte (uint8_t Byte) {
	while (!(UCSRA & (1<<UDRE)));
	UDR = Byte;
}


void usart_putword (uint16_t *Word) {
	uint8_t 	i;
	uint8_t		*py;

	py = (uint8_t*) Word;
	for (i=0;i<2;i++) usart_putbyte (*py++);
}


void usart_putdword (uint32_t *DWord) {
	uint8_t 	i;
	uint8_t		*py;

	py = (uint8_t*) DWord;

	for (i=0;i<4;i++) usart_putbyte (*py++);
}


/**
*	Get-Funktionen
*/
uint8_t usart_getbyte (void) {
	//while (!(UCSRA &(1<<RXC)));
	return _usart_get_UDR();
}
Also ich vermute, dass er zeitlich einfach nicht nachkommt vlt... :-/

Grüße Uli

PS: natürlich habe ich es an 2 verschiedenen Schaltungen versucht...

PPS: auch bringt er zeichen durcheinander: wenn ich z.b. (dezimal) "11 108 236 128 13 11 180 128 52 13" sende kommt quasi immer "11 108 236 128 4 52 13" zurück... daraus folgere ich, dass er vlt die bits irgendwie verwurstelt...