Erfahrene Probleme mit Atmel AVR und deren Lösungen
Problem: Senden über RS232 will einfach nicht:
- Pegelwandler (Max232) richtig angeschlossen? Eventuell TX+RX auf TTL- oder RS232-Seite tauschen.
- Masseverbindung auf Pin5 von 9-pol Sub-D auf GND geschaltet?
- Pin3 an PC sendet (-12V)?
- Pin2 an PC empfängt (-12V vom Max232 vorhanden)?
- Software richtig initialisiert? Baudrate, Stoppbits, Parität?
Oft wird der Fehler gemacht, das mit der internen Taktung des AVR hohe Baudraten betrieben werden sollen.
Vergiss es, ohne ordentlichen Quarztakt wird oft nur wirres Zeugs gesendet.
Mit einem 4MHz-Quarz und 9600 Baud klappt es auch beim Nachbarn. ![]()
Ohne externen Quarz sollte man die Baudrate ganz nach unten schrauben. 300baud sind zu Testzwecken keine Schande.
Ist die korrekte Taktfrequenz im AVR-Studio unter Project -> Configuration Options eingestellt?

Pin15 (PD1) ist TX, also Senden, vom AVR zum Max232.
Folgender Code gewinnt keinen Schönheitspreis, funktioniert aber.
Es wird im Sekundentakt einfach ein "A" gesendet. 9600 / 8 / N / 1
/* UART-Init beim ATMEGA32*/
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h> /* bei alter avr-libc: #include <avr/delay.h> */
#ifndef F_CPU
#warning "F_CPU nicht definiert, wird nun nachgeholt"
#define F_CPU 4000000L
#endif
#define BAUD 9600L
#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-1000) // Fehler in Promille
int main(void)
{
// Sendet ein Zeichen über die UART Schnittstelle (RS232)
void uart_putc(const unsigned char c)
{
while( (UCSRA & 1<<UDRE) == 0 ) ; //warten, bis UDR leer ist
UDR = c; //und ausgeben, den Rest macht der uC alleine
}
UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // 8 Datenbits, keine Parität, ein Stoppbit
UBRRH = UBRR_VAL >> 8; /* Baudrate einstellen */
UBRRL = UBRR_VAL & 0xFF; /* Baudrate einstellen */
UCSRB |= (1<<TXEN); /* UART TX einschalten */
UCSRB |= (1 << RXEN ); /* UART RX einschalten */
while (1)
{
_delay_ms(1000);
uart_putc('A');
}
}
Extrem wichtig:
Ein Berliner vom Vortag, oder vom vor-Vortag, wird wieder richtig lecker wie frisch vom Bäcker, wenn man ihn 10 Sekunden in der Mikrowelle abgedeckt aufwärmt.
LED am Ausgang leuchtet nicht richtig, d.h. nicht in voller Helligkeit.
Ich geb' es zu, selbst gerade erfahren: Warum zum Kuckuk leuchtet die Kontroll-LED nicht richtig hell!?
Also Stück für Stück Code herausgenommen, ... immer noch nicht.
Manchmal kommt man nicht sofort auf die einfachsten Sachen, wie "Grundregel Nummer 1":
Eingänge definiert man z.B. mit DDRx = 0b00000000 oder auch DDRx = 0X00.
Ausgänge definiert man z.B. mit DDRx = 0b11111111 oder auch DDRx = 0XFF.
Oder man schreibt, wenn der Rest des Port als Eingang benutzt wird, sich einen bestimmten Pin als Ausgang um:
DDRB = 0b00000000; // Alle Pin von PORTB als Eingang
DDRB |= (1 << PB3) // Aber Pin PB3 als Ausgang
Definiert man einen Pin als Eingang (oder man definiert ihn überhaupt nicht),
hängt eine LED dran und schaltet den vermeintlichen Ausgang,
sieht es ziemlich duster aus mit dem Leuchten.
![]()
LCD zeigt gar nichts an
Pin 1 auf Minus !?
Pin 2 auf Plus !?
Pin 3 über Poti (Kontrast LCD)
Bei meiner Versuchsschaltung klappt es, wenn Pin3 so in etwa auf 0,6V+ eingestellt ist.
Bei mehr als 1V verschwindet der Text.
Bei weniger als 0,4V ist der Kontrast zu groß, so das die "Klötzchen" so langsam zu sehen sind.
Es gibt aber auch LCDs mit negativer Kontrastspannung. Wie man dieses testen kann steht unter
AVR-Codeschnipsel, siehe "Ansteuerung des LCD Powertip PG-12864F mit dem Toshiba T6963C - Contoller".
LCD mit 4 Zeilen a 20 Zeichen, Zeile 3+4 vertexten:
Sicher gibt es andere Lösungen (Set_pos auf die richtige Adresse des LCD), aber so geht es auch:
/****************************************************************************
LCD Grundprogramm zu Einstellung Kontrast etc
Hier ein Display mit 4 Zeilen a 20 Zeichen
Die restlichen 20 Zeichen von Zeile 1 werden in Zeile 3 angezeigt
Die restlichen 20 Zeichen von Zeile 2 werden in Zeile 4 angezeigt
*****************************************************************************/
#include <avr/io.h>
#include <util/delay.h>
#include "LCD_display_free_int_pins.h"
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
#define F_CPU 4000000L
#endif
int main(void)
{
lcd_init();
lcd_send(COMMAND, LCD_CLEAR);
_delay_ms(100);
while (1)
{
lcd_set_cursor(1, 0); // Zeile 1 und 3
lcd_write ("12345678901234567890AAAAAAAAAAAAAAAAAAAA"); // Anzeige auf LCD
_delay_ms(500);
lcd_set_cursor(2, 0); // Zeile 2 und 4
lcd_write ("BBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCC"); // Anzeige auf LCD
_delay_ms(500);
}
}