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