Gast
#2206641
Hallo zusammen, ich hab hier schon gesucht aber nix gefunden was zu meinem Problem passt. Nachdem ich schon eine Weile herumexperimentiert hab, hab ich mein Problem auf das wesentlichste reduziert. Ich habe einen einfachen Testaufbau gemacht. ATMega32 mit 16Mhz Quartz, dessen UART Eingang (RX) über einen MAX232 an meinem PC hängt. Dann zu Testzwecken eine LED mit Widerstand an einen Pin von Port C. Ich habe ein kleines Testprogramm geschrieben das im Hauptteil PORTC auf Ausgang schaltet, den UART initialisiert (9600Baud) und in einer Endlosschleife nachfragt ob ein Byte angekommen ist, es evtl. ausliest und dann PORT C auf 0xff setzt und nach kurzer Zeit wieder auf 0x00. Mein Oszi sagt mir: PORTC ist für ca 12us auf high und dann kurz (ca. 2.5us) auf low. Da am PORTC eine LED hängt leuchtet diese auch wie erwartet (konstant Hell). Iss halt ne Art PWM. Jetzt sendet ein Programm auf meinem PC irgendwelche Daten an den ATMega. Mein Oszi sagt mir das der Spannugsverlauf auf PORTC ziemlich unregelmäßig wird. Es kommt tatsächlich vor das die LED für kurze Zeit (1/4 sec) ausgeht. Das irritiert mich. Der UART scheint sich massiv auf das Timing des Programmablauf auszuwirken. Folgendes hab ich probiert: UART komplett gar nicht initialisiert und nur PORTC an/aus in einer main while Schleife. PORTC an/aus in einer Interruptroutine, UART empfang in main. Ist dem ATMega völlig egal. Sobald der UART irgendwas empfängt, flackert die LED = die PWM auf PORTC kommt völlig durcheinander. Anbei mein auf das wesentlichste reduzierter code. Ich hoffe es hat jemand ne Idee? Tausend Dank Volker #include <avr/io.h> #define F_CPU 16000000UL // 16MHz #define BAUD 9600UL // Baudrate // Berechnungen #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler. #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010)) #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! #endif volatile unsigned char received ; void uart_init(void) { UBRRH = UBRR_VAL >> 8; // Wie oben berechnet UBRRL = UBRR_VAL & 0xFF;// Wie oben berechnet UCSRB = (1<<RXEN) | (1<<TXEN) ; // UART RX einschalten UCSRC = (1<<UCSZ1)|(1<<UCSZ0) |(1<<URSEL); // Asynchron 8N1 } void indicateAction(void) { int wait ; PORTC = 0b11111111 ; // just to wait a bit for (wait = 0 ; wait < 10 ; ++wait) ; PORTC = 0b00000000 ; } int main() { DDRC = 0xFF; // PORTC Ausgang uart_init(); while (1) { if (!(UCSRA & (1<<RXC))) { // no character } else { received = UDR ; } indicateAction() ; } }