lcd_puts und lcd_putc funktioniert nicht

Gast #28650
Lesenswert?

Hallo,

ich verwende den PIC16f877 und ein hd44780 kompatibles 4x20 LCD. Das 
Display ist funktionstüchtig und ich kann auch mit der routine 
lcd_cursor() den cursor bewegen.

Jedoch bekomme ich keinen Text auf das Display.

Hier sind die Routinen:

/* write a byte to the LCD in 4 bit mode */
void lcd_write(unsigned char c)
{  PORTB = (PORTB & 0xF0) |  (c >> 4);
  LCD_STROBE;
  PORTB = (PORTB & 0xF0) |  (c & 0x0F);
  LCD_STROBE;
  DelayUs(40);
}

/* write a string of chars to the LCD */
void lcd_puts(const char * s)
{
  LCD_RS = 1;  // write characters
  while(*s)
    lcd_write(*s++);
}

/* write one character to the LCD */
void lcd_putch(char c)
{  LCD_RS = 1;  // write characters
  PORTB = (PORTB & 0xF0) |  (c >> 4);
  LCD_STROBE;
  PORTB = (PORTB & 0xF0) |  (c & 0x0F);
  LCD_STROBE;
  DelayUs(40);
}


Hat jemand vielleicht einen Tip?
Vielen Dank
Holger
Gast #28653
Lesenswert?

Ich habe gerade bei deinem Source Code entdeckt, dass du den Enable Pin 
nicht auf 0 setzt.

Ich weiss auch nicht was unter LCD_STROBE steckt, aber versuch mal 
zuerst ENABLE Pin auf 0 bevor du die zum LCD-Controller schickst zum 
Schluss der Übertragung eines Nibbles setzt du ENABLE auf high , 
pausiert ein paar us und dann setzt du ihn auf low.
Dann müsste es vielleicht klappen.

MFG
Fernando
Gast #28664
Lesenswert?

Wenn du den PICSTART PLUS verwendest, ist dies kein Problem.
Denn es gibt ein Menüpunkt für den Programmierer.

Wenn du aber ein anderes Programmiergerät hast z.B. PONY,PBrenner,GALEP, 
usw., dann benutzt du die eigene Software vom jeweiligen 
Programmiergerät.

MPLAB brauchst du aber nicht unbedingt um das HEX-File in den PIC zu 
brennen.


MFG
Fernando
Gast #28665
Lesenswert?

Jetzt hab ich es endlich geschafft den Pic mit Deinem Hex code zu 
brennen. Und es funktioniert auch.
Gibt es von dem ccs compiler (den hast Du doch hierfür verwendet?) eine 
Demo-version oder eine free-version?

Dann kann ich versuchen, ob mein anderes Programm vielleicht von dem ccs 
compiler compiliert werden kann.
Kann man den ccs wie den Hi-Tech compiler auch in MPLAB einbinden?

Ansonsten muß ich den Fehler in meiner LCD-Ansteuerung finden.

Danke nochmal für Deine Mühen!
MFG
Holger
Gast #28666
Lesenswert?

Hi
Es gibt eine Version, die man downloaden kann, jedoch ist die begrenzt 
und kann nur für bestimmte PICs verwendet werden.
Und dein PIC ist leider nicht dabei.

CCS Compiler kann wie der HITECH in MPLAB integriert werden.

Also sieht es so aus , dass du dein Programm nach dem Fehler suchen 
musst.

Du kannst ja wenn du willst das Programm als Anhang hier posten, 
besonders den Teil der Initialisierung der Anzeige.

Dann schau ich mal rein.


MFG
Fernando
Gast #28668
Lesenswert?

Ich habe mir dein Programm angeschaut.
Deine Fehler liegen in der Initialisierung und im Schreiben der Anzeige. 
Denn die kleine Routine LCD_STROBE wird zu oft verwendet. Das Enable 
Signal wird immer nur beim Ende eines Schreibvorganges auf High und dann 
auf Low gesetzt.
Aber bei dir wird dies bei jedem Signal gemacht, das du der Anzeige 
schickst, so dass die Initialisierung fehlerhaft ist.

Hier habe ich dir die folgenden Routine in der LCD.C geändert, dadurch 
müsste das Programm dann funktionieren:

/* write a byte to the LCD in 4 bit mode */
void
lcd_write(unsigned char c)
{
  LCD_RS=0;
        Delay_ms(2);
        LCD_RS=0;
        LCD_EN=0;
        PORTB = (PORTB & 0xF0) |  (c >> 4);
  //LCD_STROBE;
  PORTB = (PORTB & 0xF0) |  (c & 0x0F);
  LCD_STROBE;
  //DelayUs(40);
}

/* write one character to the LCD */
void
lcd_putch(char c)
{
  LCD_RS = 0;  // write characters
        Delay_ms(2);
  LCD_RS=1;
  LCD_EN=0;
  PORTB = (PORTB & 0xF0) |  (c >> 4);
  //LCD_STROBE;
  PORTB = (PORTB & 0xF0) |  (c & 0x0F);
  LCD_STROBE;
  DelayUs(40);
}


/* initialise the LCD - put into 4 bit mode */
void
lcd_init(void)
{
  LCD_RS = 0;  // write control bytes
  LCD_EN=0;
        DelayMs(15);  // power on delay
  PORTB = 0x3;  // attention!
        Delay_MS(5);
  //LCD_STROBE;
  PORTB = 0x3;
  //LCD_STROBE;
  DelayMs(5);
        PORTB = 0x3;
        DelayMs(5);
  //LCD_STROBE;
  //DelayUs(100);
  //LCD_STROBE;
  //DelayMs(5);
  PORTB = 0x2;  // set 4 bit mode
  //LCD_STROBE;
  DelayUs(40);
       lcd_write(0x28);  // 4 bit mode, 1/16 duty, 5x8 font
        lcd_write(0xC);  // display on, blink curson on
  lcd_write(1);    //Display löschen
  lcd_write(6);    //Adresspointer
}




Danach kannst du wie im Programm schon gemacht hast, die Zeichen mit 
LCD_PUTCH() ausgeben.

Ich hoffe es funktioniert.
Viel Spaß


MFG
Fernando
Gast #28669
Lesenswert?

Tut mir leid,
es funktioniert leider immernoch nicht!
Aber ich hab mir grad mal delay.c angeschaut und festgestellt, dass da 
nach XTAL abgefragt wird, jedoch verwende ich den RC OSC. Wenn das nicht 
stimmt funktionieren die Pausen nicht richtig.
Kann das das Problem sein?
Wenn ja, wie änder ich dann die Funktion?
P.S.:
Tschuldige, daß ich Dich immer mit vielen Fragen bombadier!
Gast #28670
Lesenswert?

Mir ist gerade eingefallen, woran es liegen könnte.
Diesen Fehler habe ich früher auch mal gehabt, bei den PIC16F8XX. Du 
musst den Modus LVP ausschalten. Denn Pin RB3 wird dafür reserviert und 
kann dann nicht als I/O -Pin benutzt werden.
Das heisst schalte den LVP aus (LVP_DISABLED ich weiss ob es eine 
Funktion im HITECH dafür gibt, aber im def.h ist sie drin), das wird es 
wunderbar funktionieren.

P.S. Wenn du dich für bestimmte "tipps und Tricks" oder häufige Fehler 
bei der Mikrocontrollerprogrammierung interessierst, dann schau mal bei 
mir rein unter der Rubrik "Tipps und Tricks":

        http://www.fernando-heitor.de



MFG
Fernando
Gast #28672
Lesenswert?

Ich hab grad gesehen, dass Du ausser nur Port A und B als Ausgang zu 
setzen auch noch andere Einstellungen gleich am Anfang von main() in 
lcd.c machst, muß ich da auch noch irgendwas einstellen?

Im Prinzip sind ja Deine Einstellungen richtig. Ich müsste also nur die 
gleichen machen und dann müsste es funktionieren.

MFG
Holger
Gast #28673
Lesenswert?

Die Sache mit dem Cursor liegt daran, dass die Option "Adresspointer 
inkrementieren und Displayinhalt nicht verschieben" nicht aktiviert war.

Tja bald weiss auch nicht mehr weiter.
Versuch mal meine Headerdateien lcd.h lcd16x2.h in dein Programm zu 
integrieren. Ausser der Spezial Funktionen #use , #fuses muss der HITECH 
die Routinen problemlos compilieren.

Die Einstellungen bei mir in main() sind nur bestimmte Vorkehrungen , 
die du hier aber nicht benötigst.
Das einzige worauf du achten musst, ist das du den LVP ausschaltest und 
den Port A definierst ( Standardzustand Port ist analog).

Das ist die einzige Möglichkeit, die ich sehe, ist dein Fehler in deinem 
zu suchen (habe selbst keinen mehr bei dir gefunden) oder du integrierst 
Stück für Stück mein Programm.

Sorry.


MFG
Fernando
Gast #28674
Lesenswert?

Hi,

hab grad versucht Deine Routinen zu verwenden, kommen jedoch jede Menge 
Fehler.
Z.B.: Bei  byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type 
<< 2),0xc, 1, 6};
kommt dieser Fehler
C:\PICCLITE\LCD.C: 29:missing basic type:int assumed (warning)
C:\PICCLITE\LCD.C: 29: , expected (error)
C:\PICCLITE\LCD.C: 29: , expected (error)

oder bei byte
kommt
C:\PICCLITE\LCD.C:44: argument redeclared: byte (error)

auch weiß ich nicht wie ich portb.lcddata=n ersetzen soll.



MFG
Holger
Gast #28675
Lesenswert?

Hi

Du kannst anstatt LCD_INIT_STRING, die Konstanten manuell angeben.
In der LCD_INIT() kannst du mit dem LCD_SEND_BYTE() die Werte angeben, 
z.B. LCD_SEND_BYTE(0,0x28) . Der Wert 0x28 ist diesem Beispiel das 
gleiche wie 0x20 | (lcd_type << 2)

Der Befehl #byte gibt es glaube ich nicht im HITECH.
Mit diesem Befehl (#byte portb=6) definiere den Port B mit Hardware 
Adresse 6. Im HITECH muss es sowas auch geben, vielleicht mit Zeigern 
oder so. Den struct Befehl muss HITECH können, ist ein ANSI C Befehl.


MFG
Fernando
Gast #28677
Lesenswert?

Du kannst doch den STRUCT-Befehl anwenden:


struct {
unsigned lcddata:4;  //PIN RB0-RB3
unsigned pinb4:1;
unsigned pinb5:1;
unsigned pinb6:1;
unsigned pinb7:1;
} portb;

Danach versuch entweder:

byte portb = 0x6

oder:

static unsigned char PORTB @ 0x6;
(Das muss vor dem struct-Befehl)

Dann wird es funktionieren, da bin ich mir sicher.


MFG
Fernando
Gast #28678
Lesenswert?

Juhu,
Juhu, jetzt klappt es endlich.
Ich musste noch ADCON1 richtig setzen.
Jetzt geht es auch mit meinem alten Programm.

Trotdem nett, wie Du Dich darum gekümmert hast.


Mein nächstes Problem ist es nun den Wert einer Variablen auszugeben.Mit 
der Funktion printf(putch,"\fWert= %03u", wert)
funktioniert das bei meinem Programm nicht. Und einfach mit putch(wert) 
funktioniert auch nicht. Du hast nicht zufällig auch da eine Lösung 
parat?

MFG
Holger

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