He modificado la librería lcd.c para que pueda funcionar con cualquiera de los puertos.
Hazte con ella aqui ,modifica la estructura del mapa de pines según tu conexionado y prueba este programa a ver que tal:
Codigo:
#include <18F452.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#define use_porta_lcd TRUE
#include "lcd.c"
void main()
{
lcd_init();
printf(lcd_putc,"fhola");
lcd_gotoxy(1,2);
printf(lcd_putc,"mundo");
for(;;) {}
}
Supongo que tendrás el pin RW del lcd puesto a masa ¿no?
hola gente
yo tambien quiero colaborar un poco con un programa para el lcd. Lo unico es que los comentarios estan en aleman y no tuve tiempo de traducirlos. Cualquier cosa, lo hago el fin de semana. Otra cosa: el programa es para un 16F873 pero cambiando el include y poniendo los pines deseados tiene que funcionar como un relojito
.
Codigo:
#include <lcd.h> // Hier wird die Headerdatei des Hauptprogrammes eingebunden
#include <lcdanzeige.c> // Hier wird die Datei für die Routinen der LCD-Anzeige eingebunden
unsigned char wert; // eine Zählvariable
// Beginn des Hauptprogrammes
void main() {
set_tris_a(0); // Port A als Ausgang definieren
set_tris_b(0); // Port B als Ausgang definieren
set_tris_c(0); // Port C als Ausgang definieren
lcd_init(); // Initialisierung der LCD-Anzeige
LCD_BLANK();
lcd_gotoxy(1,1); // weitere Routine von lcd16x2.c, bewegt den Cursor zu den Koordinaten x,y
lcd_putc("cHallo Welt2"
; // Dieser Befehl gibt die Zeichen (Text) an das Display.
lcd_putc("Ein Test"
;
delay_ms(500); // pausiert 500ms
wert=0; // setzt Zählvariable auf 0
while (1) { // Endlosschleife
/* Mit dem Befehl "printf" wird die Variable in ASCII-Code umgewandelt und mit der Routine lcd_putc auf die Anzeige geschrieben. */
printf(lcd_putc,"fWert: %03u",wert);
wert++; // Zählvariable wird um 1 erhöht
delay_ms(200); // Pause200ms
} // Ende der Endlosschleife
} // Hauptprogramm Ende
Die Headerdatei vom Hauptprogramm (lcd.h):
#include <16F873.h> // Ein PIC-Typ wird ausgewählt
#use delay(clock=4000000) // Die Taktfrequenz beträgt 4 MHz
/* Watchdogtimer wird abgeschaltet und Oszillatoroption wird konfiguriert. Wenn man Pin RB3 am PIC16F873 als digital I/O verwenden möchte muss das LVP ausgeschaltet sein */
#fuses HS,NOWDT,NOLVP
/* Hier wird eine Struktur definiert, sie beeinhalten Port B
(Signal RW wird hier nicht mehr benötigt) */
struct port_b_layout
{
short unused; // freier Portpin
short rs; // LCD RS
short unused2; // freier Portpin ( war vorher Pin R/W)
short enable; // LCD ENABLE
int lcddata:4; // LCD-Daten D4...D7
} portb;
/* Hier wird portb als Byte mit der Zahl 5 definiert. Die Zahl zeigt nur die Adresse von Port B im Special Function Register des PICs.*/
#byte portb=5
/* Hier definiere ich einen NOP, und nehme dafür das NOP im Assembler. Es wird gebraucht um einige Pausen zwischen zwei Befehlen zu setzen.*/
#define NOP() { #asm nop #endasm }
Routinen für die LCD-Anzeige (lcdanzeige.c):
/* Hier kann der Typ der Anzeige definiert werden
( 0=5x7, 1=5x10, 2=2 lines )*/
#define lcd_type 2
/*verschiedene Eigenschaften der LCD-Anzeige
0x0C = Display an
0x01 = Display löschen
0x06 = Adresspointer inkrementieren und Displayinhalt nicht verschieben */
byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0x0C, 0x01, 6};
/* Diese Routine versendet jeweils ein Nibble an das Display.
Ein Nibble besteht immer aus 4 Bits. Bei einer Anzeige im 4-Bit Modus werden immer erst die hochwertigen Bits und danach niederwertigen Bits an das Display übertragen. */
void lcd_send_nibble( byte n )
{
portb.lcddata = n;
nop();
portb.enable = 1;
delay_us(4);
portb.enable = 0;
}
/* Hier wird das komplette Byte übertragen. Hier wird das BUSY-Flag nicht abgefragt, sondern pausiert 2ms bis dahin ist das Display wieder bereit. Danach wird das Byte getrennt und zwei Nibbles (Nibble=4 Bit) werden übertragen.*/
void lcd_send_byte( byte address, byte n ) {
portb.rs = 0;
delay_ms(2);
portb.rs = address;
nop();
portb.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
/* Initialisierung des LCD-Displays. Die verschiedenen Eigenschaften der Anzeige werden hier übertragen.*/
void lcd_init()
{
byte i;
portb.rs = 0;
portb.enable = 0;
delay_ms(15);
for (i=1;i<=3;++i)
{
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for (i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING);
}
/* Hier wird die Anzeige auf bestimmte Koordinaten gesetzt.
Die Routine ist auch für 4-Zeilen Display geeignet.*/
void lcd_gotoxy( byte x, byte y)
{
byte address;
if (y==1) address=0;
if (y==2) address=0x40;
if (y==3) address=0x10;
if (y==4) address=0x50;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
/* Hier wird der Text auf das Display geschrieben. Es wird auch überprüft ob bestimmte Spezialfunktionen angegeben sind. (Wichtig : Die Ausgabe die Variablen kann diese Routine nicht richtig ausgeben, weil die erst umgewandelt werden müssen. In der Variante 2 wird dies berücksichtigt) */
void lcd_putc( char f)
{
switch (f)
{
case "c" : lcd_send_byte(0,1);
delay_ms(2);
break;
case "1" : lcd_gotoxy(1,1); break;
case "2" : lcd_gotoxy(1,2); break;
case "3" : lcd_gotoxy(1,3); break;
case "4" : lcd_gotoxy(1,4); break;
default : lcd_send_byte(1,f); break;
}
}