Pfiff
26.11.2005, 13:57
Hallo,
Ich habe von einen Freund einen fertig programmierten, funktionierenden LCD-Treiber bekommen. Dieser Treiber ist für den PORTB angepasst. Der PORTB hat leider als einziger Interrupt-Pins -und die brauch ich umbedingt...
Ich finde mich bei diesem Programm nur schwer zurecht und wollte fragen, ob mir jemand den Treiber auf folgende Belegung unprogrammieren könnt:
RC0: D1
RC1: D2
RC2: D3
RC3: D4
RB0: RS
RB1: E
RB2: R/W
Ich verwenden den PIC16C773 und den CCS-Compiler.
Das ist der Treiber:
============================
///////////////////////////////////////////////////////////////////////////
//// LCD_W.c / 2.12.2004 ////
//// Treiber für Standard LCDs ////
//// (WSH Demoversion) ////
//// ////
//// lcd_init() Muß einmal ganz zu Beginn aufgerufen werden ////
//// ////
//// lcd_putc(c) Zeigt c an der nächsten Position am LCD an. ////
//// Folgende Anweisungen haben Sonderfunktion: ////
//// \f Löscht Anzeige ////
//// \n Geht zum Anfang der nächsten Zeile ////
//// \b Rückschritt um eine Position ////
//// ////
//// lcd_gotoxy(x,y) Setzt Schreibposition (oben links ist 1,1) ////
//// ////
//// lcd_getc(x,y) Liest Zeichen an Pos. x,y vom LCD ////
//// ////
//// lcd_puts16(zeil_nr, zeil_inh) Gibt komplette 16-Zeichen-Zeile ////
//// aus, die als String-Adresse übergeben wird ////
//// ////
//// lcd_puts24(zeil_nr, zeil_inh) Gibt komplette 24-Zeichen-Zeile ////
//// aus, die als String-Adresse übergeben wird ////
//// ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
///////////////////////////////////////////////////////////////////////////
// As defined in the following structure the pin connection is as follows:
// B0 ENABLE
// B1 RS
// B2 R/W
// B4 D4
// B5 D5
// B6 D6
// B7 D7
//
// LCD pins D0-D3 are not used and PIC B3 is not used.
#define use_portb_lcd TRUE
struct lcd_pin_map { // This structure is overlayed
BOOLEAN enable; // on to an I/O port to gain
BOOLEAN rs; // access to the LCD pins.
BOOLEAN rw; // The bits are allocated from
BOOLEAN unused; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;
#byte lcd = 6
#define set_tris_lcd(x) set_tris_b(x)
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_lcd(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_lcd(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.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[i]);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}
/*----------------------------------------------------------------*/
/*- Eigene Funktionen -*/
/*----------------------------------------------------------------*/
//----------------------------------------------------------------
void lcd_puts16(int zeil_nr, char zeil_inh)
{
int counter;
lcd_gotoxy(1, zeil_nr); /* Cursor setzen */
for(counter=0; counter < 17; counter++)
{
lcd_putc(zeil_inh[counter]);
}
return;
}
//----------------------------------------------------------------
//----------------------------------------------------------------
void lcd_puts24(int zeil_nr, char zeil_inh)
{
int counter;
lcd_gotoxy(1, zeil_nr); /* Cursor setzen */
for(counter=0; counter < 25; counter++)
{
lcd_putc(zeil_inh[counter]);
}
return;
}
//----------------------------------------------------------------
===============================
Vielen Dank im Vorhinein!
fg Pfiff
Ich habe von einen Freund einen fertig programmierten, funktionierenden LCD-Treiber bekommen. Dieser Treiber ist für den PORTB angepasst. Der PORTB hat leider als einziger Interrupt-Pins -und die brauch ich umbedingt...
Ich finde mich bei diesem Programm nur schwer zurecht und wollte fragen, ob mir jemand den Treiber auf folgende Belegung unprogrammieren könnt:
RC0: D1
RC1: D2
RC2: D3
RC3: D4
RB0: RS
RB1: E
RB2: R/W
Ich verwenden den PIC16C773 und den CCS-Compiler.
Das ist der Treiber:
============================
///////////////////////////////////////////////////////////////////////////
//// LCD_W.c / 2.12.2004 ////
//// Treiber für Standard LCDs ////
//// (WSH Demoversion) ////
//// ////
//// lcd_init() Muß einmal ganz zu Beginn aufgerufen werden ////
//// ////
//// lcd_putc(c) Zeigt c an der nächsten Position am LCD an. ////
//// Folgende Anweisungen haben Sonderfunktion: ////
//// \f Löscht Anzeige ////
//// \n Geht zum Anfang der nächsten Zeile ////
//// \b Rückschritt um eine Position ////
//// ////
//// lcd_gotoxy(x,y) Setzt Schreibposition (oben links ist 1,1) ////
//// ////
//// lcd_getc(x,y) Liest Zeichen an Pos. x,y vom LCD ////
//// ////
//// lcd_puts16(zeil_nr, zeil_inh) Gibt komplette 16-Zeichen-Zeile ////
//// aus, die als String-Adresse übergeben wird ////
//// ////
//// lcd_puts24(zeil_nr, zeil_inh) Gibt komplette 24-Zeichen-Zeile ////
//// aus, die als String-Adresse übergeben wird ////
//// ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
///////////////////////////////////////////////////////////////////////////
// As defined in the following structure the pin connection is as follows:
// B0 ENABLE
// B1 RS
// B2 R/W
// B4 D4
// B5 D5
// B6 D6
// B7 D7
//
// LCD pins D0-D3 are not used and PIC B3 is not used.
#define use_portb_lcd TRUE
struct lcd_pin_map { // This structure is overlayed
BOOLEAN enable; // on to an I/O port to gain
BOOLEAN rs; // access to the LCD pins.
BOOLEAN rw; // The bits are allocated from
BOOLEAN unused; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;
#byte lcd = 6
#define set_tris_lcd(x) set_tris_b(x)
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_lcd(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_lcd(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.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[i]);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}
/*----------------------------------------------------------------*/
/*- Eigene Funktionen -*/
/*----------------------------------------------------------------*/
//----------------------------------------------------------------
void lcd_puts16(int zeil_nr, char zeil_inh)
{
int counter;
lcd_gotoxy(1, zeil_nr); /* Cursor setzen */
for(counter=0; counter < 17; counter++)
{
lcd_putc(zeil_inh[counter]);
}
return;
}
//----------------------------------------------------------------
//----------------------------------------------------------------
void lcd_puts24(int zeil_nr, char zeil_inh)
{
int counter;
lcd_gotoxy(1, zeil_nr); /* Cursor setzen */
for(counter=0; counter < 25; counter++)
{
lcd_putc(zeil_inh[counter]);
}
return;
}
//----------------------------------------------------------------
===============================
Vielen Dank im Vorhinein!
fg Pfiff