PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mit Atmega32 LCD 2x16 ansteuern Problem!!!



semicolon
29.05.2006, 19:31
Hallo Leute

Ich habe ein Problem. Mein LCD läuft nicht.

Atmega32
PORTC7-PORTC4: Daten
PORTC3: E
PORTC2: RS
PORTC1:R/W

Habe folgenden Code geschrieben:

main.c

#include "io.h"
#include "iom32.h"
#include "delay.h"
#include "lcd_2x16.h"

void wait_s () {

int i;
for (i = 0; i <20000; i++) {

asm volatile("NOP");

}
}

//Variabeln
static int RS = 0;

//display löschen
void clrLCD() {

RS = 0;
lcd_send(clr);
wait_s();
RS = 1;
}

//Cursor auf home setzen
void homeDisplay() {

RS = 0;
lcd_send(home);
RS = 1;
}

//Display initialisieren
void initDisplay() {

_delay_ms(20); //warten bis Display parat
RS = 0;
PORTC = 0;
lcd_send(function_set | _8Bit);
_delay_ms(4.1);
lcd_send(function_set | _8Bit);
_delay_us(100);
lcd_send(function_set | _8Bit);
lcd_send(function_set | _4Bit);
lcd_send(function_set | _2line);
lcd_send(control | display_on |cursor_on | blink_on);
clrLCD();
homeDisplay();
RS = 1;
}

//Display auf zweite Zeile setzen
void second_row() {

RS = 0;
lcd_send(0x80 | 0x40);
RS = 1;
}

//Daten an LCD senden
void lcd_send(char c) {

int data = c;

//Hight - Nibble
PORTC = (RS<<2);
PORTC |= ((data & 0xF0));
PORTC |= (1<<3);
_delay_ms(1.6);
PORTC &= ~(1<<3);

//Low - Nibble
PORTC = 0;
PORTC = (RS<<2);
PORTC |= ((data & 0x0F)<<4);
PORTC |= (1<<3);
_delay_ms(1.6);
PORTC &= ~(1<<3);
PORTC= 0;


}

int main (void)
{

DDRB = (1<<DDB0) | (1<<DDB2);
DDRC = 0xFF;
DDRD = 0xFF;
wait_s();
initDisplay();

//disaeblen jtag
MCUCSR|=(1<<JTD);
MCUCSR|=(1<<JTD);

lcd_send(0x65);

while (1) {/* Note [6] */

wait_s();
PORTB = 1;
wait_s();
PORTB = 4;
}

return (0);
}

lcd_2x16.h

#include "io.h"


#define clr 0x01
#define home 0x02
#define display_on 0x04
#define blink_on 0x01
#define cursor_on 0x02
#define control 0x08
#define function_set 0x20
#define _4Bit 0x00
#define _8Bit 0x10
#define _2line 0x08
#define LCD PORTC


extern void clrLCD();
extern void lcd_send(char);
extern void homeDisplay();
extern void initDisplay();
extern void second_row();
extern void put_Data(const int *displayData);
extern void lcd_send(char c);

Ich seh den Fehler einfach nicht.[/code]

SprinterSB
30.05.2006, 16:14
Du Initialisierst das Ding als 8-Bit, schickst die Daten aber *immer* im 4-Bit-Format. Vielleicht ist es das ja?

Sende mal als erstes nach einem Reset das _4Bit, und zwar nur eine Übertragung, also nur das High-Nibble, das die Information trägt. Danacherst "normale" Kommunikation mit immer High- und Low-Nibble.

semicolon
30.05.2006, 18:56
Ok, das kann ich mal ja versuchen!!!

Bezüglich dem 8-Bit, habe ich in diversen Foren gesehen, dass viele zuerst auf 8-Bit setzten und dann erst in den 4-Bit Modus wechseln.

Ich habe schon viel Zeit investiert aber es kommen immer nur die schwarzen Balken in der ersten Zeile. Zuerst dachte ich, dass es der Port C ist, weil noch das JTAG darüber läuft. Aber als ich ihn dann disaebelte gings trotzdem nicht.

Ansonsten weiss ich nichts mehr. Bin am Ende meines Wissens. Für weiter Tipps oder Lösungsvorschläge wäre ich froh.

vajk
30.05.2006, 19:15
Hallo,
wenn Du willst, kann ich auch Dir meinen Code zur Verfügung stellen, ist für das Pollin 27x4 und für ein 20x4 ausgelegt, aber sollte auch für weniger Zeilen gehen :-) Ist für Mega128 und 16 MHz ausgelegt und hat den Vorteil, daß jeder Pin zuzuordnen ist.
Bei Interesse, PMe mir halt Deine eMail-Adresse.
Hab sogar schon ein Lob dafür bekommen, sei schön schnell ...

semicolon
30.05.2006, 20:06
ok würde dein Angebot annehmen, einzig ist nur, dass ich nur im 4-Bit Betrieb arbeite, da ich sonst zu wenig Ports habe.

semicolon
30.05.2006, 20:10
mein Problem besteht wahrscheinlich darin, dass mein senden der Daten nicht stimmt und zwar bezüglich der Hight- und Low-Nibble. Deshalb meine Frage:

Ist diese Funktion in Ordnung?

SprinterSB
30.05.2006, 20:44
Hier mal, so wie ich es mache (schematsch)


#include <util/delay.h>
#include <avr/io.h>

void vfd_send0 (uint8_t);
void vfd_send1 (uint8_t);
void vfd_send_nibble (uint8_t);

void vfd_send0 (uint8_t b)
{
CLR (PORT_RS);
vfd_send_nibble (b>>4);
vfd_send_nibble (b);
}

void vfd_send1 (uint8_t b)
{
SET (PORT_RS);
vfd_send_nibble (b>>4);
vfd_send_nibble (b);
}

void vfd_send_nibble (uint8_t b)
{
CLR (PORT_E);
CLR (PORT_RW);

VFD_CLR_DB; // PORT_DB[0..3] = 0
if (b & (1<<0)) SET (PORT_DB0);
if (b & (1<<1)) SET (PORT_DB1);
if (b & (1<<2)) SET (PORT_DB2);
if (b & (1<<3)) SET (PORT_DB3);

SET (PORT_E);
LOOP (100);
CLR (PORT_E);
}


Sollte eigentlich zu verstehen sein, was da gemacht wird.
LOOP wird abgebildet auf _delay_loop_1 aus util/delay.h

Ausserdem warte ich nach dem Reset ne Zeit lang, bevor ich ein Display anfasse (mehrere zig ms).

vajk
30.05.2006, 21:06
kleine Anmerkung - hatte ich vergessen - natürlich 4-Bit-Mode ;-) Wer verschenkt gerne Ports .. 7 Bit plus LCD-Reset reichen schon :-)

semicolon
30.05.2006, 21:34
ok dann bin ich sehr interessiert natürlich

willst du meine Mail?

vajk
30.05.2006, 22:15
... Bei Interesse, PMe mir halt Deine eMail-Adresse. ...

semicolon
30.05.2006, 22:21
oh, jetzt hat es endlich geklappt. Ich danke dir gleich viel mals für dein Angebot. Mein Fehler bestand darin, dass ich eben bereits bei der Einstellung auf den 4-Bit Modus mit High und Low Nibble gearbeitet habe. Tja, dummer Fehler.