Forum: Mikrocontroller und Digitale Elektronik Problem bei Initialisierung eines LC-Displays


von Oliver (Gast)


Lesenswert?

Hi zusammen,

habe ein Problem mit meinem LC-Display 162C mit KS0070B-Controller.
Die Initialisierung funktioniert leider nicht. Das Display wird im 
4-Bit-Modus betrieben.

Ich verwende einen PIC16f819.
Hier mein Init-Code, könnt Ihr vielleicht einen Fehler entdecken??

#include "main.h"

//Pin_Setup
#define DB4 PIN_B1
#define DB5 PIN_B2
#define DB6 PIN_B4
#define DB7 PIN_B5
#define RS PIN_A7
#define RW PIN_B0
#define EN PIN_A6

//Display_Befehle
#define LCD_Set        0b00110000
#define LCD_CLEAR   0b00000001      //Löschen des Display, Cursor auf 
Home
#define LCD_FUNCTION  0b00101000      //4-Bitmodus
#define LCD_CONTROL   0b00001111      //Display ON, Cursor ON, Blinken 
ON
#define LCD_DISPLAY_OFF 0b00001000
#define LCD_ENTRY_INC   0b00000110
#define LCD_DISPLAY_ON   0b00001111


void display_enable (void);


void display_send(unsigned char send_byte)
{
   unsigned char high_nib;
   unsigned char low_nib;
   low_nib = send_byte&0b00001111;
   send_byte>>4;
   high_nib = send_byte&0b00001111;

   output_low(RS);
   output_low(RW);
   output_low (DB4);
   output_low (DB5);
   output_low (DB6);
   output_low (DB7);

   //High_Nibble senden
   if (high_nib & 0b0001) output_high(DB4);
   if (high_nib & 0b0010) output_high(DB5);
   if (high_nib & 0b0100) output_high(DB6);
   if (high_nib & 0b1000) output_high(DB7);
   display_enable();
   delay_us(100);

   output_low (DB4);
   output_low (DB5);
   output_low (DB6);
   output_low (DB7);

   //Low_Nibble senden
   if ( low_nib & 0b0001) output_high(DB4);
   if ( low_nib & 0b0010) output_high(DB5);
   if ( low_nib & 0b0100) output_high(DB6);
   if ( low_nib & 0b1000) output_high(DB7);
   display_enable();
   delay_us(100);
}

void display_enable(void)
{
   output_low(EN);
   output_high(EN);
   delay_us(100);
   output_low(EN);
}

void display_command(unsigned char command)
{
   output_low(RS);
   display_send(command);
   delay_us(2000);
}

void display_init(void)
{
   delay_ms(2000);

   output_low(DB4);
   output_low(DB5);
   output_low(DB6);
   output_low(DB7);
   output_low(RW);
   output_low(RS);
   output_low(EN);

   //Set1
   output_high(DB4);
   output_high(DB5);
   output_low(DB6);
   output_low(DB7);
   display_enable();
   delay_ms(5);

   //Set2
   output_low(DB4);
   output_low(DB5);
   output_low(DB6);
   output_low(DB7);
   output_low(DB4);
   output_high(DB5);
   display_enable();
   delay_us(120);

   //Set3
   output_low(DB4);
   output_low(DB5);
   output_low(DB6);
   output_low(DB7);
   output_high(DB7);
   output_high(DB6);
   display_enable();
   delay_us(1000);

   //4Bit Mode
   output_low(DB4);
   output_low(DB5);
   output_low(DB6);
   output_low(DB7);

   output_high(DB5);
   display_enable();
   delay_us(50);

   //Ab hier mit Funktion "display_command" arbeiten
   //teilt Byte in Hnib und Lnib

   //LCD Clear
   display_command(LCD_SET);
   display_command(LCD_CLEAR);
   display_command(LCD_FUNCTION);
   display_command(LCD_DISPLAY_OFF);
   display_command(LCD_ENTRY_INC);
   display_command(LCD_DISPLAY_ON);
   display_command(LCD_CLEAR);
}


void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_oscillator(OSC_8MHZ);


      display_init();

      while (1)
      {
         output_high(PIN_A2);
      }


}

Danke schon mal im Voraus.

Grüsse
Oliver

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Hallo,

der Code sieht aus, als sollte er für einen CCS Compiler sein. Der 
Compiler kann solche Displays meines Wissens direkt mittels einer 
Bibliothek ansprechen, such einfach mal im Manual.

Deine Lösung mit dem sequentiellen Setzen der einzelnen Bits an den 
Ports ist sehr ineffizient. Wenn es dir irgendwie möglich ist, würde ich 
zudem einen 8bit Betrieb bevorzugen, damit kann man direkt ASCII Zeichen 
an einen Port anlegen, die Senderoutine fällt dann auf 3 Zeilen 
zusammen.

Grüße,

Peter

von Oliver (Gast)


Lesenswert?

Hallo,

Danke für den Tip.

Aus "Platzgründen ist nur die Ansteuerung per 4-Bit möglich. Ebenfalls 
aus Anwendungsgründen, muss die Pinbelegung wie oben gezeigt beibehalten 
werden. Ein Display per 8-Bit Variante einzurichten und zu betreiben ist 
kein Problem, das stimmt! Brauche für meine Anwendung jedoch das 4-Bit 
Interface.

Vielleicht noch einen Tip was an meinem Code falsch sein könnte?

Ich habe folgende konkrete Fragen:

Muss beim Initialisieren, der Enable_PIN nach jedem Befehl gesetzt 
(fallende Flanke) werden?
Macht die Funktion "display_command" was sie soll --> Byte in High_Nib 
und Low_Nib teilen und diese jeweils an den uc senden? Sind die 
Bit-Operationen richtig?
Ist die Reihenfolge meiner Initialisierungsbefehle richtig?
Was ist an der Initialisierung falsch ;-) ?

Danke!
Oliver

von Oliver (Gast)


Lesenswert?

Hi zusammen,

Problem gelöst!!!

Jetzt kommt was zum schmunzeln!!!

Der Fehler war folgender:

Als Enable-Pin, wurde der PIN_A6 gewählt, der bei dem verwendetetn 
uCrontroller einer der beiden OSC-Ein/Ausgänge ist. PIN_A6 hat als 
einziger der beiden OSC-Ein/Ausgänge die Funktion CLKOUT, welche durch 
setzen einer FUSE aktiviert oder deaktiviert werden kann. Leider habe 
ich die Option nicht deaktiviert, somit hatte ich am Enable-Pin einen 
ständigen Takt von 2 MHz :-)
Das erklärt auch die Tatsache, warum die Initialisierung manchmal 
teilweise funktioniert hat, manchmal gar nicht ... Da der Enable-Pin 
dauerhaft getaktet wurde, hat das Diplay manchmal ein paar 
Initialisierungsbefehle erhalten, manchmal eben nicht.

Tja, ich hoffe einige von euch mit den Ausführungen vor NERVIGEN Fehlern 
zu bewahren, im einfachsten Fall immer PORTB-Pins nehmen und dann sollte 
das schon passen (oder einfach nachdenken).

Es klappt übrigens mit allen gängigen Tut's hier im Forum oder sonst so 
im Netz.

Folgendes Tut kann ich nur empfehlen, Sprut hat hier wie immer saubere 
Arbeit geleistet.
http://sprut.de/electronic/pic/programm/tastlcd/tastlcd.html

Grüsse
Oliver

von Jochen Adler (Gast)


Lesenswert?

Ich will auch dieses Display im 4-Bit-Modus betreiben. Ich verstehe aus 
dem Datenblatt nicht, wie man High- und Low-Nibble schreibt. Wie bemerkt 
denn das Display, dass das Nibble, das gerade anliegt, das High- oder 
das Low-Nibble ist?

Danke
Jochen

von Der wohl ahnungslose (Gast)


Lesenswert?

Das Display erwartet das entsprechende Nibble, mehr ist's nicht.
http://sprut.de/electronic/lcd/index.htm
Im unteren Drittel fängt das '4-Bit Interface' an.
Gesendet wird, im 4-Bit-Betrieb, erst das High-Nibble, dann das 
Low-Nibble.

von Jochen Adler (Gast)


Lesenswert?

Danke, genau das habe ich gesucht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.