/* ----------------------------------------------- uart_and_lcd.c Demoprogramm fuer UART und Textdisplay mit HD44780 kompatiblem Controller. Datei kommt bewusst ohne externe Sourcen aus, da nicht angenommen werden kann, welche Toolchain zum Uebersetzen verwendet wird. MCU : ATmega8, ATmega48/88/168/328p, ATtiny2313/4313 Takt: 16 MHz 30.05.2026 R. Seelig ----------------------------------------------- */ #include #include #include /* ----------------------------------------------- UART ----------------------------------------------- Prototypen ----------------------------------------------- */ void uart_init(uint32_t baud); void uart_putchar(char ch); uint8_t uart_ischar(void); char uart_getchar(void); void uart_puts(const char *str); #define echo_enable 0 /* -------------------------------------------------------- Registernamen von ATmega8, ATtiny2313 / 4313 -------------------------------------------------------- */ #if defined __AVR_ATmega8__ || __AVR_ATmega8515__ || \ __AVR_ATtiny2313__ || __AVR_ATtiny4313__ #define UBRR0 UBRR #define UBRR0L UBRRL #define UBRR0H UBRRH #define UCSR0A UCSRA #define UCSR0B UCSRB #define UCSR0C UCSRC #define U2X0 U2X #define RXEN0 RXEN #define TXEN0 TXEN #define UCSZ00 UCSZ0 #define UCSZ01 UCSZ1 #define UDRE0 UDRE #define UDR0 UDR #define RXC0 RXC #endif /* ----------------------------------------------- LC-Display ----------------------------------------------- Bitmasken ----------------------------------------------- */ #define MASK0 ( 1 << 0 ) #define MASK1 ( 1 << 1 ) #define MASK2 ( 1 << 2 ) #define MASK3 ( 1 << 3 ) #define MASK4 ( 1 << 4 ) #define MASK5 ( 1 << 5 ) #define MASK6 ( 1 << 6 ) #define MASK7 ( 1 << 7 ) /* ----------------------------------------------- GPIO-Makros fuer LC-Anschluesse ----------------------------------------------- */ // rs => PB4 #define rs_output() ( DDRB |= MASK4 ) #define rs_set() ( PORTB |= MASK4 ) #define rs_clr() ( PORTB &= ~MASK4 ) // en => PB3 #define e_output() ( DDRB |= MASK3 ) #define e_set() ( PORTB |= MASK3 ) #define e_clr() ( PORTB &= ~MASK3 ) // d4 => PD5 #define d4_output() ( DDRD |= MASK5 ) #define d4_set() ( PORTD |= MASK5 ) #define d4_clr() ( PORTD &= ~MASK5 ) // d5 => PD4 #define d5_output() ( DDRD |= MASK4 ) #define d5_set() ( PORTD |= MASK4 ) #define d5_clr() ( PORTD &= ~MASK4 ) // d6 => PD3 #define d6_output() ( DDRD |= MASK3 ) #define d6_set() ( PORTD |= MASK3 ) #define d6_clr() ( PORTD &= ~MASK3 ) // d7 => PD2 #define d7_output() ( DDRD |= MASK2 ) #define d7_set() ( PORTD |= MASK2 ) #define d7_clr() ( PORTD &= ~MASK2 ) /* ------------------------------------------------------- Prototypen ------------------------------------------------------- */ void txlcd_init(void); void txlcd_gotoxy(uint8_t x, uint8_t y); void txlcd_putchar(char ch); void txlcd_puts(const char *str); void txlcd_clrscr(void); /* ------------------------------------------------------- Variable ------------------------------------------------------- */ uint8_t wherex, wherey; /* ------------------------------------------------------- Makro fuer Bittest ------------------------------------------------------- */ #define testbit(reg,pos) ((reg) & (1< 57600) { ubrr= (F_CPU/16/(uint16_t)(baud >> 1)); ubrr--; UCSR0A |= 1<>8); // Baudrate setzen UBRR0L = (uint8_t)ubrr; #if defined __AVR_ATmega8__ UCSR0B |= (1< HiNibble wird gesendet ( obere 4 Bits: 7..4 ) 0 => LoNibble wird gesendet ( untere 4 Bits: 3..0 ) ------------------------------------------------------- */ void nibbleout(uint8_t value, uint8_t nibble) { if (nibble) { if (testbit(value, 7 )) { d7_set(); } else { d7_clr(); } if (testbit(value, 6 )) { d6_set(); } else { d6_clr(); } if (testbit(value, 5 )) { d5_set(); } else { d5_clr(); } if (testbit(value, 4 )) { d4_set(); } else { d4_clr(); } } else { if (testbit(value, 3 )) { d7_set(); } else { d7_clr(); } if (testbit(value, 2 )) { d6_set(); } else { d6_clr(); } if (testbit(value, 1 )) { d5_set(); } else { d5_clr(); } if (testbit(value, 0 )) { d4_set(); } else { d4_clr(); } } } /* ------------------------------------------------------- txlcd_clock gibt einen Clockimpuls an das Display ------------------------------------------------------- */ void txlcd_clock(void) { e_set(); _delay_us(60); e_clr(); e_output(); _delay_us(60); } /* ------------------------------------------------------- txlcd_io sendet ein Byte an das Display Uebergabe: value = zu sendender Wert ------------------------------------------------------- */ void txlcd_io(uint8_t value) { nibbleout(value, 1); txlcd_clock(); nibbleout(value, 0); txlcd_clock(); } /* ------------------------------------------------------- txlcd_init initialisiert das Display im 4-Bitmodus ------------------------------------------------------- */ void txlcd_init(void) { char i; d4_output(); d5_output(); d6_output(); d7_output(); rs_output(); e_output(); rs_clr(); rs_output(); for (i= 0; i< 3; i++) { txlcd_io(0x20); _delay_ms(6); } txlcd_io(0x28); _delay_ms(6); txlcd_io(0x0c); _delay_ms(6); txlcd_io(0x01); _delay_ms(6); wherex= 0; wherey= 0; } /* ------------------------------------------------------- txlcd_gotoxy setzt den Textcursor an eine Stelle im Display. Die obere linke Ecke hat die Koordinate (1,1) Uebergabe: x,y : Position des Textcursors ------------------------------------------------------- */ void txlcd_gotoxy(uint8_t x, uint8_t y) { uint8_t txlcd_adr; txlcd_adr= (0x80+((y-1)*0x40))+x-1; rs_clr(); rs_output(); txlcd_io(txlcd_adr); wherex= x; wherey= y; } /* ------------------------------------------------------- txlcd_putchar gibt ein Zeichen auf dem Display aus Uebergabe: ch = auszugebendes Zeichen ------------------------------------------------------- */ void txlcd_putchar(char ch) { rs_set(); txlcd_io(ch); wherex++; } /* -------------------------------------------------- txlcd_puts Ascii-Z String auf Text-LCD ausgeben Uebergabe: *str : Zeiger auf zu sendenden String -------------------------------------------------- */ void txlcd_puts(const char *str) { while (*str) txlcd_putchar(*str++); } /* -------------------------------------------------- txlcd_clrscr loescht den Inhaltdes Textdisplays durch Neuinitialisierung -------------------------------------------------- */ void txlcd_clrscr(void) { txlcd_init(); txlcd_gotoxy(1,1); } /* -------------------------------------------------- Ende LC-Display-Funktionen -------------------------------------------------- */