Hallo Zusammen

Ich krieg es einfach nicht hin, mein LCD anzusteuern. Überall wird geschrieben, dass sei eigentlich nicht so ein Problem, aber bei mir klappts nicht

Also das Ganze sieht so aus: Ich habe ein 4x20Zeichen Display. Also 4 Zeilen mit je 20 Zeichen.
Das Datenblatt könnt ihr hier herunterladen.
Ich möchte es im 8-Bit Modus ansteuern. Dann brauche ich das Byte nicht zu zerlegen und für den Moment habe ich genug Ports.
Ich habe das Display folgendermassen mit dem RN-Control verkabelt:
RS auf PORTB, Pin 0
R/W habe ich, da ich nur schreiben möchte auf VSS gelegt (richtig so, oder?)
E auf PORTB, Pin 2
D0-D7 auf PORTC
Dazu erstmal eine Frage. Funktioniert das rein elektronisch? Oder funkt mir da noch irgendwas vom RN-Control rein? Den Motortreiber habe ich entfernt, und alle Jumper rausgezogen.

Mein Code sieht so aus:

b_setH und b_setL ist eine Präprozessordirektiven um ein Bit in einem Byte Hight bzw. Low zu setzten.

Konfiguriert wird das Ding im Haederfile:
m32_lcd.h
Code:
#ifndef M32_LCD_H_
#define M32_LCD_H_

// general ---------------------------------------------------------------------
#ifndef F_CPU
  #define F_CPU 16000000
#endif

// LCD -------------------------------------------------------------------------
#define CONT_DDR    DDRB
#define CONT_PORT   PORTB
#define CONT_E      2   // Enable (fallende Flanke)
#define CONT_RS     0   // L:Befehl / H:Daten
#define CONT_RW     1   // H:Read / L:Write
#define DATA_DDR    DDRC
#define DATA_PORT   PORTC

// EOF -------------------------------------------------------------------------
#endif /*M32_LCD_H_*/
Und hier die Source:
m32_lcd.c
Code:
#include <avr/io.h>
#include "m32_lcd.h"
#include "bit.h"

// delay -----------------------------------------------------------------------
void _delay_loop_1(uint8_t __count)
{
  __asm__ volatile (
    "1: dec %0" "\n\t"
    "brne 1b"
    : "=r" (__count)
    : "0" (__count)
  );
}

void _delay_loop_2(uint16_t __count)
{
  __asm__ volatile (
    "1: sbiw %0,1" "\n\t"
    "brne 1b"
    : "=w" (__count)
    : "0" (__count)
  );
}

void _delay_us(double __us)//max: 768us / F_CPU in Mhz
{
  uint8_t __ticks;
  double __tmp = ((F_CPU) / 3e6) * __us;
  if (__tmp < 1.0)
    __ticks = 1;
  else if (__tmp > 255)
    __ticks = 0;  // i.e. 256
  else
    __ticks = (uint8_t)__tmp;
  _delay_loop_1(__ticks);
}

void _delay_ms(double __ms) //max: 260ms / F_CPU in Mhz
{
  uint16_t __ticks;
  double __tmp = ((F_CPU) / 4e3) * __ms;
  if (__tmp < 1.0)
    __ticks = 1;
  else if (__tmp > 65535)
    __ticks = 0;  // i.e. 65536 
  else
    __ticks = (uint16_t)__tmp;
  _delay_loop_2(__ticks);
}

// testing ---------------------------------------------------------------------
void init(void)
{
  b_setH(CONT_DDR,CONT_E);
  b_setH(CONT_DDR,CONT_RS);
//  b_setH(CONT_DDR,CONT_RW);    

  b_setL(CONT_PORT,CONT_E);     // E nicht setzen
  b_setL(CONT_PORT,CONT_RS);    // RS nicht setzen
//  b_setL(CONT_PORT,CONT_RW);  // RW nicht setzen  
  DATA_DDR = 0xff;  // Ausgänge
  DATA_PORT= 0x00;
}

// lcd -------------------------------------------------------------------------
void lcd_send(uint8_t data, uint8_t rs) //rs: L:Befehl / H:Daten
{
  DATA_PORT = data;
  if(rs)
    b_setH(CONT_PORT,CONT_RS);
  else
    b_setL(CONT_PORT,CONT_RS);
  _delay_us(45);  // kurze Verzögerung, wahrscheinlich überflüssig
  b_setH(CONT_PORT,CONT_E);
  _delay_us(45);
  b_setL(CONT_PORT,CONT_E);

  _delay_ms(10); // um Befehl auszuführen, wahrscheinlch viel zu lang
}

void lcd_init(void){
  lcd_send(0x34,0); // 8-Bit Datenlänge
  lcd_send(0x09,0); // 4 Zeilen Modus
  lcd_send(0x0F,0); // Display on, Cursor on, Blink on
  lcd_send(0x01,0); // Display löschen, Cursor 1. Spalte, 1. Zeile;
}

void lcd_writeC(uint8_t c, uint8_t z, uint8_t s) //c: char, z: Zeile., s: Spalte
{
  lcd_send(c,1);
}

// testing ---------------------------------------------------------------------
int main(void)
{
  init();
  lcd_init();

  lcd_send('a',1);

  return 0; 
}
Für die, die es noch intressiert, die bit.h
Code:
#ifndef BIT_H_
#define BIT_H_

// bit.h -----------------------------------------------------------------------
// n ist immer die Bit-Position von Rechts gezählt im Intervall [0..7]
#define b_maske(n)    (1 << n)    // generiert Make mit 1 bei n
#define b_ifset(b,n)  (b & (1 << n) // liefert true wenn n true, sonst false
#define b_setH(b,n)   b |= (1 << n) // setzt n auf 1
#define b_setL(b,n)   b &= ~(1 << n)  // setzt n auf 0
#define b_inv(b,n)    b ^= (1 << n) // invertiert n (1->0, 0->1)

// setzt r auf a jedoch mit dem bit n von b als bit n von r
#define b_qset(a,b,n) (a = (b & (1 << n)) | (a & ~(1 << n)))      //n = k
// setzt r auf a jedoch mit dem bit k von b als das bit n von r
#define b_qsetL(a,b,n,k)  ((b << (n-k)) & (1 << n)) | (a & ~(1 << n)) // n > k
#define b_qsetR(a,b,n,k)  ((b >> (k-n)) & (1 << n)) | (a & ~(1 << n)) // k > n

// rotiert a um ein bit
#define b_rotL(a)     b_qsetR((a << 1),a,0,7)
#define b_rotR(a)     b_qsetL((a >> 1),a,7,0)

// EOF -------------------------------------------------------------------------
#endif /*BIT_H_*/
Die delay-Funktionen habe ich aus der AVR-Lib-C kopiert.
Die Initialisierung habe ich aus dem Datenblatt des Displays abgeschrieben, ich hoffe die stimmt.

Leider sehe ich auf dem Display überhautp nichts. An der Kontrastspannung liget es nicht, das habe ich überprüft.
Hat jemand eine Idee, wieso, dass das nicht funktioniert?

Vielen Dank für eure Hilfe!

Grüsse cumi[/b]