Forum: Mikrocontroller und Digitale Elektronik LCD-Ansteuerung über PIC 16F1829


von Stefan U. (unti)


Lesenswert?

Hallo miteinander

Ich habe folgendes Problem un zwar gibt meine LCD-Anzeige nichts aus. 
Initialisieren funktioniert allerdings perfekt.
Kann mir einer von euch dabei weiterhelfen??

MfG Unti

von T.roll (Gast)


Lesenswert?

Stefan Untner schrieb:
> Kann mir einer von euch dabei weiterhelfen??

Nein. Unsichtbaren Code kann hier keiner lesen. Möchtest du ihn in 
sichtbarer Version anhängen?

von Stefan U. (unti)


Lesenswert?

Sorry (ganz vergessn) hier hab ich main.c, Ausschnitte aus lcd.c und 
lcd.h

main.c:

#include <16F1829.H>
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include <lcd.h>

#fuses PUT,BROWNOUT,NOLVP, NOMCLR
#fuses INTRC_IO, NOWDT, NOPROTECT
#use delay(clock=16000000)

void main(void)
{
    char msg[]="hallo";
    set_tris_c(0x00);   //output

    LCD_reset();

  while(1) // endless loop
  {
    delay_ms(5);
    LCD_out(msg);
    }//end while
}//end main


lcd.c: (Ausschnitt)

void LCD_write4Bit(unsigned char zeichen)
{
    LCD_E=0;
    LCD_D7=zeichen &0x80;
    LCD_D6=zeichen &0x40;
    LCD_D5=zeichen &0x20;
    LCD_D4=zeichen &0x10;
  LCD_E=1;
  LCD_E=0;
  delay_us(50); //50µs warten
    LCD_D7=zeichen &0x08;
    LCD_D6=zeichen &0x04;
    LCD_D5=zeichen &0x02;
    LCD_D4=zeichen &0x01;
  LCD_E=1;
  LCD_E=0;
  delay_us(50); //50 µs warten
}
void LCD_out(char *text)
{
  LCD_RS=DAT;
    while(*text!='\0')
  {
  LCD_write4Bit(*text++); //string wird zeichen für zeichen ausgegeben 
bis '\0'
  }
}


lcd.h:

#ifndef H__LCD
#define H__LCD

#define REG 0 //Registerbefehl
#define DAT 1 //Datenbefehl

#byte PORT_C=0x0E
#bit LCD_E=PORT_C.0  //enable
#bit LCD_RS=PORT_C.1 //Registerselect
#bit LCD_D4=PORT_C.2
#bit LCD_D5=PORT_C.3
#bit LCD_D6=PORT_C.4
#bit LCD_D7=PORT_C.5

void LCD_write4Bit(unsigned char zeichen); //Einzelnes Zeichen wird 
ausgegeben
void LCD_init(); //LCD wird initialisiert
void LCD_del(); //LCD wird gelöscht
void LCD_pos1(); //Cursor wird auf Position 1,1 gesetzt
void LCD_on();//Display wird eingeschaltet, cursor ist inaktiv
void LCD_out(char *text);//string wird zeichenweise ausgegeben
void LCD_movexy(unsigned char row, unsigned char col);//cursor wird 
gesetzt
void LCD_enable();//negative flanke wird erzeugt
void DefineBarSigns(); //user RAM Character werden generiert
void DrawBar(unsigned char percent); //Balkenausgabe
void LCD_reset();

#endif

von holger (Gast)


Lesenswert?

>Ausschnitte aus lcd.c und lcd.h

Kannst auch gleich ne Wurstbrotschnitte hier posten;)
Ich bevorzuge vollständige Tiere;)

von Stefan U. (unti)


Angehängte Dateien:

Lesenswert?

Das gesamte lcd.c File ist im Anhang und lcd.h ist bereits vollständig 
im oberen Beitrag vorhanden.

von holger (Gast)


Lesenswert?

>  LCD_E=1;
>  LCD_E=0;
>  delay_us(50); //50 µs warten

Mach das mal so:

  LCD_E=1;
  delay_us(1); //1 µs warten
  LCD_E=0;

Exaktes Timing ist beim LCD alles.

von Stefan U. (unti)


Angehängte Dateien:

Lesenswert?

Danke für den guten Versuch aber es hat leider nicht funktioniert.
Im Anhang ist das veränderte lcd.c File.

von holger (Gast)


Lesenswert?

>Danke für den guten Versuch aber es hat leider nicht funktioniert.
>Im Anhang ist das veränderte lcd.c File.

Du sollst nicht deine langen Delays in den E Puls reinlegen,
sondern den E Puls 1us lang machen. Schau in das Datenblatt
des LCDs. Dann nimmst du die Bilder mit den Timing Diagrammen
und baust das 1:1 nach. Dann klappt das auch.

von T.roll (Gast)


Lesenswert?

Stefan Untner schrieb:
> Initialisieren funktioniert allerdings perfekt.
Sicher? Ich seh keinen Funktionsaufruf LCD_init(), nur ein LCD_reset().

Stimmt außerdem LCD_RS?

von Stefan U. (unti)


Angehängte Dateien:

Lesenswert?

[holger]
Hab ich danach auch gemacht. Das Display ist fix auf eine selbstgebaute 
Platine gelötet, deswegen kann ich nicht herausfinden welches Display 
das ist. Ich vermute allerdings, dass es sich um ein LCD mit 
Standartchip ist.

von Stefan U. (unti)


Angehängte Dateien:

Lesenswert?

[T.roll]
Ich bin mir sicher, dass es funktioniert.
LCD_RS stimmt, ich habs mit LCD_RS=1; und mit LCD_RS=DAT; 
ausprobiert.... kein Unterschied.

von holger (Gast)


Lesenswert?

>Hab ich danach auch gemacht.

Ja, und dann in lcd_reset die langen delays weggemacht.
Och man ey...

von Stefan U. (unti)


Lesenswert?

Hab in LCD_reset wieder die langen delays reingetan.
Funktioniert trotzdem leider nicht.

von T.roll (Gast)


Lesenswert?

Schalt mal das Cursorblinken in der init ein und schau ob er auch 
blinkt:

LCD_write4Bit(0x0f); //00001111
statt
LCD_write4Bit(0x0c); //00001100

von holger (Gast)


Lesenswert?

>Hab in LCD_reset wieder die langen delays reingetan.
>Funktioniert trotzdem leider nicht.

Und den Code nicht gepostet.

Das sieht doch schon mal alles nicht so ganz verkehrt aus.
Einige Sachen sind ja schon drin, nur nutzt du sie nicht.
Zum Beispiel:
1
void LCD_enable()
2
{
3
  LCD_E=1;//negative Flanke wird erzeugt
4
  delay_us(1);
5
  LCD_E=0;
6
}

mach das
1
void LCD_enable()
2
{
3
  LCD_E=1;//negative Flanke wird erzeugt
4
  delay_us(1);
5
  LCD_E=0;
6
  delay_us(1);
7
}

und der Enable Puls wird immer passen.

So, dann noch
1
void LCD_reset()
2
{  
3
  delay_ms(50); // Power on reset abwarten
4
  LCD_E=0;
5
    LCD_RS=REG;
6
    LCD_D7=0;
7
  LCD_D6=0;
8
  LCD_D5=1;
9
  LCD_D4=1;
10
  LCD_enable();
11
  delay_ms(50);
12
  LCD_D7=0;
13
  LCD_D6=0;
14
  LCD_D5=1;
15
  LCD_D4=1;
16
  LCD_enable();
17
  delay_ms(50);
18
  LCD_D7=0;
19
  LCD_D6=0;
20
  LCD_D5=1;
21
  LCD_D4=1;
22
  LCD_enable();
23
  delay_ms(50);
24
}

Nutze den Kram der schon geht. Sonst machst du nur Fehler.

Weiter:

void LCD_write4Bit(unsigned char zeichen)

Bau da LCD_Enable() ein.
1
void LCD_write4Bit(unsigned char zeichen)
2
{
3
    LCD_D7=zeichen &0x80;
4
    LCD_D6=zeichen &0x40;
5
    LCD_D5=zeichen &0x20;
6
    LCD_D4=zeichen &0x10;
7
  LCD_enable();
8
    LCD_D7=zeichen &0x08;
9
    LCD_D6=zeichen &0x04;
10
    LCD_D5=zeichen &0x02;
11
    LCD_D4=zeichen &0x01;
12
  LCD_enable();
13
}

In void LCD_out(char *text)

hast du Mist gebaut

nach   LCD_write4Bit();
brauchst du ein delay. Bau es dort ein!
1
void LCD_write4Bit(unsigned char zeichen)
2
{
3
    LCD_D7=zeichen &0x80;
4
    LCD_D6=zeichen &0x40;
5
    LCD_D5=zeichen &0x20;
6
    LCD_D4=zeichen &0x10;
7
  LCD_enable();
8
    LCD_D7=zeichen &0x08;
9
    LCD_D6=zeichen &0x04;
10
    LCD_D5=zeichen &0x02;
11
    LCD_D4=zeichen &0x01;
12
  LCD_enable();
13
  delay_us(50);
14
}

usw.

Vereinfache deinen Code.

Wenn du die genauen delays nicht kennst mach sie grösser.
1
void LCD_del()
2
{   
3
  LCD_RS=REG; //Registerbefehl
4
  LCD_write4Bit(0x01); //Daten werden gesendet
5
  delay_ms(5);//700µs warten
6
}

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.