Hallo zusammen,
ich habe mir vor ein paar Tage ein 4 Zeilen/16 Zeichen LCD mit HD44780
Controller gekauft und will das jetzt mit einem STK500 + Attiny2313
betreiben.
Das LCD zeigt beim Start in Zeile 2 und 4 Weisse Balken an. Nach der
Initialisierung durch den Atmega sind die Balken weg und das Display
leer. Leider wird mir der im Code vorgegebene Text nicht angezeigt. (Am
Kontrast schauben bringt auch nichts).
Die LCD Lib ist von Peter Fleury. Die LCD Pinbelegung, der CPU Tankt und
der 4Bit Mode wurden in der lcd.h angepasst.
Der Controller läuft mit 4MHz und der Flash wird über den ISP Mode
beschrieben.
Das LCD ist wie Folgt an den Controller angeschlossen:
LCD_DATA0_PIN -> PB0
LCD_DATA1_PIN -> PB1
LCD_DATA2_PIN -> PB2
LCD_DATA3_PIN -> PB3
LCD_RS_PIN -> PB4
LCD_RW_PIN -> PB5
LCD_E_PIN -> PB6
Wie man sieht soll das ganze im 4-Bit Mode laufen.
p.S.: In der main.c sind soviele Delays, weil ich gedacht habe, dass das
LCD evtl zu langsam für den Atmega ist und nicht hinterher kommt. Aber
auch daran scheint es nicht zu hängen.
Mr.x schrieb:> LCD_DATA0_PIN -> PB0> LCD_DATA1_PIN -> PB1> LCD_DATA2_PIN -> PB2> LCD_DATA3_PIN -> PB3> LCD_RS_PIN -> PB4> LCD_RW_PIN -> PB5> LCD_E_PIN -> PB6>> Wie man sieht soll das ganze im 4-Bit Mode laufen.
Bei den LCD, die ich bisher hatte, müssen im 4-Bit-Modus die
LCD-Datenpins 4 bis 7 mit den Datenleitungen des µC verbunden werden.
>Bei den LCD, die ich bisher hatte, müssen im 4-Bit-Modus die>LCD-Datenpins 4 bis 7 mit den Datenleitungen des µC verbunden werden.
Genau:
DB0 to DB3 4 I/O MPU
Four low order bidirectional tristate data bus
pins. Used for data transfer and receive
between the MPU and the HD44780U.
These pins are not used during 4-bit operation.
ansonsten stimmen die Zeiten deiner _delay_ms nicht.
Alternativ: schmeiss die _delay_ms am Anfang raus. Nach dem Textausgeben
ist ok. Du verbrutzels nach dem Einschalten erst mal 3 Sekunden und 3
Sekunden können lang sein, wenn man auf etwas wartet. Sicher, dass du
lang genug gewartet hast, ehe sich am LCD was tun sollte?
Hallo Herr Moderator,
Das F_CPU kann er sich schenken. Er verwendet die Fleury Library und die
funktioniert seit Jahren in dieser Form.
In der lcd.h ist folgender Eintrag:
#define XTAL 4000000 /**< clock frequency in Hz, used to
calculate delay timer */
Das sollte doch reichen, oder?
USBASP User schrieb:> Hallo Herr Moderator,>> Das F_CPU kann er sich schenken. Er verwendet die Fleury Library und die> funktioniert seit Jahren in dieser Form.
Es geht nicht um die Fleury Lib, es geht um
#include <util/delay.h>
und darum, dass seine main() mit ein paar _delay_ms anfängt.
USBASP User schrieb:> delay.h wird hier nicht verwendet. Daher ist F_CPU zwar nicht> syntaktisch falsch aber überflüssig.
Dann muss ich was an den Augen haben.
1. Posting
main.c
1
#include<stdlib.h>
2
#include<avr/io.h>
3
#include<avr/pgmspace.h>
4
#include<util/delay.h>
5
#include"lcd.h"
6
7
8
intmain(void)
9
{
10
11
/* initialize display, cursor off */
12
lcd_init(LCD_DISP_ON);
13
_delay_ms(1000);
14
lcd_clrscr();
15
_delay_ms(1000);
16
lcd_gotoxy(0,0);
17
_delay_ms(1000);
18
for(;;){/* loop forever */
19
/* clear display and home cursor */
20
lcd_puts("TEST");
21
_delay_ms(1000);
22
}
23
}
wenn die 4 mal so lang dauern wie vorgesehen, sind das 12 Sekunden bis
zum ersten mal was geschrieben wird. Da kann man schon mal die Nerven
verlieren. 12 Sekunden sind lang, wenn man darauf wartet.
Da die Balken verschwinden, wird sein LCD initialisiert.
Guten Morgen zusammen,
ich habe die Datenleitungen und die RS, RW, E Leitungen mal auf
verschiedene PORTs gelegt.
#define LCD_PORT PORTB /**< port for the LCD lines */
#define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN 0 /**< pin for 4bit data bit 0 */
#define LCD_DATA1_PIN 1 /**< pin for 4bit data bit 1 */
#define LCD_DATA2_PIN 2 /**< pin for 4bit data bit 2 */
#define LCD_DATA3_PIN 3 /**< pin for 4bit data bit 3 */
#define LCD_RS_PORT PORTD /**< port for RS line */
#define LCD_RS_PIN 0 /**< pin for RS line */
#define LCD_RW_PORT PORTD /**< port for RW line */
#define LCD_RW_PIN 1 /**< pin for RW line */
#define LCD_E_PORT PORTD /**< port for Enable line */
#define LCD_E_PIN 2 /**< pin for Enable line */
Außerdem habe ich die _delay_ms(1000) gelöscht. Das LCD bleibt
dummerweise immernoch leer.
Kann es vielleicht sein, dass die LCDlib nur für LCDs mit 2 Zeilen
geeignet ist und mit einem 4 Zeilen LCD nicht funktioniert?
Karl Heinz Buchegger schrieb:> Schmeiss mal den lcd_clear und den gotoxy raus. Je weniger du im> Programm hast, was schief gehen kann, desto besser.>> int main(void)> {>> /* initialize display, cursor off */> lcd_init(LCD_DISP_ON);> for (;;) { /* loop forever */> lcd_puts("TEST");> _delay_ms(1000);> }> }
Funktioniert leider auch nicht.
Ich glaube ja immernoch das LCD ist für den µC zu langsam (LCD arbeitet
noch die Initialisierung ab und der µC ist schon beim nächsten Befehl).
Kann es sein, dass die Optimierung -Os zuviel weg optimiert?
Die initialisierung funktioniert mitlerweile auch nurnoch bei jedem
zweiten oder dritten Neustart des µC.
Was mir noch aufgefallen ist:
1. STK500 Start -> Balke weg, LCD leer
2. STK500 Neustart / LCD hängt an einem externen Netzteil und wird nicht
neugestartet (LCD immernoch leer) -> Nach dem Zweiten Neustart sind die
Balken wieder da
Was mich TOTAL verwirrt ist, das ganze lief gestern morgen mal kurz. Bis
ich das STK500 neu gestartet habe, danach war das LCD wieder leer. Ich
habe gedacht, der Flash vom µC wo das Programm drauf war hat sich evtl
verabschiedet und habe code unverändert wieder auf das Controller
geschoben, aber dann ging nichtsmehr.. :(
Mr.x schrieb:> Karl Heinz Buchegger schrieb:>> Schmeiss mal den lcd_clear und den gotoxy raus. Je weniger du im>> Programm hast, was schief gehen kann, desto besser.>>>> int main(void)>> {>>>> /* initialize display, cursor off */>> lcd_init(LCD_DISP_ON);>> for (;;) { /* loop forever */>> lcd_puts("TEST");>> _delay_ms(1000);>> }>> }>> Funktioniert leider auch nicht.> Ich glaube ja immernoch das LCD ist für den µC zu langsam (LCD arbeitet> noch die Initialisierung ab und der µC ist schon beim nächsten Befehl).
Du kannst natürlich im LCD Code mal alle Wertezeiten etwas länger
machen.
> Kann es sein, dass die Optimierung -Os zuviel weg optimiert?
Nein.
> Die initialisierung funktioniert mitlerweile auch nurnoch bei jedem> zweiten oder dritten Neustart des µC.
OK.
Das ist ein Hinweis.
Mach die Wartezeiten im LCD Code überall ein wenig länger. Das dürfte
sich dann schon knapp am Limit bewegen.
Ich habe heute wieder ein bischen Zeit mich um das LCD Problem zu
kümmern.
Karl Heinz Buchegger schrieb:>> Die initialisierung funktioniert mitlerweile auch nurnoch bei jedem>> zweiten oder dritten Neustart des µC.>> OK.> Das ist ein Hinweis.> Mach die Wartezeiten im LCD Code überall ein wenig länger. Das dürfte> sich dann schon knapp am Limit bewegen.
Deswegen habe ich in der lcd.c in der Funktion "void lcd_init(uint8_t
dispAttr)" die Wartezeiten mal um 30% erhöht. Bisher aber ohne Erfolg.
Gibt es noch andere Zeiten die man erhöhen muss, die ich bis jetzt
übersehen habe?
delay(20800/*16000*/); /* wait 16ms or more after power-on
*/
/* initial write to lcd is 8bit */
LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); // _BV(LCD_FUNCTION)>>4;
LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); // _BV(LCD_FUNCTION_8BIT)>>4;
lcd_e_toggle();
delay(6489/*4992*/); /* delay, busy flag can't be checked
here */
/* repeat last command */
lcd_e_toggle();
delay(83/*64*/); /* delay, busy flag can't be checked here
*/
/* repeat last command a third time */
lcd_e_toggle();
delay(83/*64*/); /* delay, busy flag can't be checked here
*/
/* now configure for 4bit mode */
LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); //
LCD_FUNCTION_4BIT_1LINE>>4
lcd_e_toggle();
delay(83/*64*/); /* some displays need this additional
delay */
/* from now the LCD only accepts 4 bit I/O, we can use lcd_command()
*/
#else
/*
* Initialize LCD to 8 bit memory mapped mode
*/
/* enable external SRAM (memory mapped lcd) and one wait state */
MCUCR = _BV(SRE) | _BV(SRW);
/* reset LCD */
delay(20800); /* wait 16ms after power-on
*/
lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit
interface */
delay(6489); /* wait 5ms
*/
lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit
interface */
delay(83); /* wait 64us
*/
lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit
interface */
delay(83);
Kann ich die Wartezeiten beliebig weit erhöhen? Habekein Datenblatt zu
dem LCD gefunden in dem irgendwas daszu steht...
p.S.: Nachdem ich die Wartezeit um 20% erhöht hatte hat das LCD einmal
funktioniert. (Es wurden in allen Zeilen : angezeigt) Nach dem nächsten
neustart ging wie gewohnt wieder nichts.