HD44100H/HD44780A00

Gast #3156446
Lesenswert?

Hallo,

ich habe einen Atmega 16 Mikrocontroller und einen LC-Display mit
dem 2 Chips darauf HD44100H/HD44780A00
Ich bin nicht der beste Programmierer und noch Anfänger. Ich bin gerade 
dabei in C ein Programm zu schreiben.
Richtig angeschlossen habe ich ihn, er zeigt zunächst nur schwarze
Balken in der 1. Zeile an.
Könnte mir jemand eine kleine Stütze geben. Das bisherige Programm habe
ich mal beigefügt. Bin für jede Hilfe dankbar!
Main.c:
#include <avr/io.h>
#include "Debug/led-routines.h"

int main(void)
{
  lcd_init();

  set_cursor(0,1);

  lcd_string("Hello World!");

  while(1)
  {
  }

  return 0;
}

led-routines.h:

// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
//
void lcd_data(unsigned char temp1);
void lcd_string(char *data);
void lcd_command(unsigned char temp1);
void lcd_enable(void);
void lcd_init(void);
void lcd_home(void);
void lcd_clear(void);
void set_cursor(uint8_t x, uint8_t y);

// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!

#define F_CPU 8000000

// LCD Befehle

#define CLEAR_DISPLAY 0x01
#define CURSOR_HOME   0x02

// Pinbelegung für das LCD, an verwendete Pins anpassen

#define LCD_PORT      PORTC
#define LCD_DDR       DDRC
#define LCD_RS        PC4
#define LCD_EN        PC5
// DB4 bis DB7 des LCD sind mit PC0 bis PC3 des AVR verbunden

led-routines.c:

// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
//
// Die Pinbelegung ist über defines in lcd-routines.h einstellbar

#include <avr/io.h>
#include "Debug/led-routines.h"
#include <util/delay.h>

// sendet ein Datenbyte an das LCD

void lcd_data(unsigned char temp1)
{
  unsigned char temp2 = temp1;

  LCD_PORT |= (1<<LCD_RS);        // RS auf 1 setzen

  temp1 = temp1 >> 4;
  temp1 = temp1 & 0x0F;
  LCD_PORT &= 0xF0;
  LCD_PORT |= temp1;               // setzen
  lcd_enable();

  temp2 = temp2 & 0x0F;
  LCD_PORT &= 0xF0;
  LCD_PORT |= temp2;               // setzen
  lcd_enable();

  _delay_us(42);
}

// sendet einen Befehl an das LCD

void lcd_command(unsigned char temp1)
{
  unsigned char temp2 = temp1;

  LCD_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen

  temp1 = temp1 >> 4;              // oberes Nibble holen
  temp1 = temp1 & 0x0F;            // maskieren
  LCD_PORT &= 0xF0;
  LCD_PORT |= temp1;               // setzen
  lcd_enable();

  temp2 = temp2 & 0x0F;            // unteres Nibble holen und maskieren
  LCD_PORT &= 0xF0;
  LCD_PORT |= temp2;               // setzen
  lcd_enable();

  _delay_us(42);
}

// erzeugt den Enable-Puls
void lcd_enable(void)
{
  // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
einfügen
  // Beitrag "Re: Bitte helft mir. Schon wieder AtMega16"
  LCD_PORT |= (1<<LCD_EN);
  _delay_us(1);                   // kurze Pause
  // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
verlängern
  // Beitrag "LCD -> Probleme mit Optimierungsgrad"
  LCD_PORT &= ~(1<<LCD_EN);
}

// Initialisierung:
// Muss ganz am Anfang des Programms aufgerufen werden.

void lcd_init(void)
{
  LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN);   // Port auf 
Ausgang schalten

  // muss 3mal hintereinander gesendet werden zur Initialisierung

  _delay_ms(15);
  LCD_PORT &= 0xF0;
  LCD_PORT |= 0x03;
  LCD_PORT &= ~(1<<LCD_RS);      // RS auf 0
  lcd_enable();

  _delay_ms(5);
  lcd_enable();

  _delay_ms(1);
  lcd_enable();
  _delay_ms(1);

  // 4 Bit Modus aktivieren
  LCD_PORT &= 0xF0;
  LCD_PORT |= 0x02;
  lcd_enable();
  _delay_ms(1);

  // 4Bit  2 Zeilen  5x7
  lcd_command(0x28);

  // Display ein  Cursor aus  kein Blinken
  lcd_command(0x0C);

  // inkrement / kein Scrollen
  lcd_command(0x06);

  lcd_clear();
}

// Sendet den Befehl zur Löschung des Displays

void lcd_clear(void)
{
  lcd_command(CLEAR_DISPLAY);
  _delay_ms(5);
}

// Sendet den Befehl: Cursor Home

void lcd_home(void)
{
  lcd_command(CURSOR_HOME);
  _delay_ms(5);
}

// setzt den Cursor in Zeile y (1..4) Spalte x (0..15)

void set_cursor(uint8_t x, uint8_t y)
{
  uint8_t tmp;

  switch (y) {
    case 1: tmp=0x80+0x00+x; break;    // 1. Zeile
    case 2: tmp=0x80+0x40+x; break;    // 2. Zeile
    case 3: tmp=0x80+0x10+x; break;    // 3. Zeile
    case 4: tmp=0x80+0x50+x; break;    // 4. Zeile
    default: return;                   // für den Fall einer falschen 
Zeile
  }
  lcd_command(tmp);
}

// Schreibt einen String auf das LCD

void lcd_string(char *data)
{
  while(*data) {
    lcd_data(*data);
    data++;
  }
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren