/* * LCD interface example * Uses routines from delay.c * This code will interface to a standard LCD controller * like the Hitachi HD44780. It uses it in 4 bit mode, with * the hardware connected as follows (the standard 14 pin * LCD connector is used): * * PORTB bits 0-3 are connected to the LCD data bits 4-7 (high nibble) * PORTA bit 2 is connected to the LCD RS input (register select) * PORTA bit 3 is connected to the LCD EN bit (enable) * * To use these routines, set up the port I/O (TRISA, TRISB) then * call lcd_init(), then other routines as required. * * Copywrite Craig Lee 1998 * */ #include <pic.h> #include "lcd.h" #include "delay.h" #define LCD_RS RA5 // Register select #define LCD_EN RB4 // Enable #define LCD_D4 RB5 // Data bits #define LCD_D5 RC5 // Data bits #define LCD_D6 RC4 // Data bits #define LCD_D7 RC3 // Data bits #define LCD_STROBE ((LCD_EN = 1),(LCD_EN=0)) /* write a byte to the LCD in 4 bit mode */ void lcd_write(unsigned char c) { if(c & 0x80) LCD_D7=1; else LCD_D7=0; if(c & 0x40) LCD_D6=1; else LCD_D6=0; if(c & 0x20) LCD_D5=1; else LCD_D5=0; if(c & 0x10) LCD_D4=1; else LCD_D4=0; LCD_STROBE; if(c & 0x08) LCD_D7=1; else LCD_D7=0; if(c & 0x04) LCD_D6=1; else LCD_D6=0; if(c & 0x02) LCD_D5=1; else LCD_D5=0; if(c & 0x01) LCD_D4=1; else LCD_D4=0; LCD_STROBE; DelayUs(40); } /* * Clear and home the LCD */ void lcd_clear(void) { LCD_RS = 0; lcd_write(0x1); DelayMs(2); } /* 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(unsigned char c) { LCD_RS = 1; // write characters lcd_write(c); } /* * Go to the specified position */ void lcd_goto(unsigned char pos) { LCD_RS = 0; lcd_write(0x80 + pos); } /* initialise the LCD - put into 4 bit mode */ void lcd_init(void) { LCD_RS = 0; // write control bytes DelayMs(15);// power on delay LCD_D4 = 1; // init! LCD_D5 = 1; // LCD_STROBE; DelayMs(5); LCD_STROBE; // init! DelayUs(100); LCD_STROBE; // init! DelayMs(5); LCD_D4 = 0; // set 4 bit mode LCD_STROBE; DelayUs(40); lcd_write(0x28);// 4 bit mode, 1/16 duty, 5x8 font, 2lines lcd_write(0x0C);// display on lcd_write(0x06);// entry mode advance cursor lcd_write(0x01);// clear display and reset cursor }
Questions:
Hello, Has anyone had experience with driving a Laptop LCD display, I have a one from an old laptop as was wondering if a PIC could be used to drive it, It is a panasonic cf27 laptop and the dispaly is a standard 640x480 lcd, any ideas and or source code would be very appreciated. Best regards Nick
Code:
//**Project Name: VFD //**File Name : vfd0_3.c //**Version : 0.3 //**Date : 24/02/2002 //**Revision : 28/02/2002 added bit swap routine //** : 02/03/2002 fixed error in display routine and added delay to //** : WR_PIN strobe. //** : //** //**Processor :16F84/628 //** //** Copyright CDB. email bodgy1@optusnet.com.au // Program to display data on a Futoba M202SD08GL vacuum fluorescent display. // Using parallel mode. Data is on port B and control on port A. // Connections as follows // // Display Pins. 1 3 5 7 9 11 13 15 // Data Bits. 7 6 5 4 3 2 1 0 // // Control Pins. 20 18 17 16 8 // Signal Name. Busy SEL WR TEST RST // // Pins 2 4 6 +5v; 10 12 14 Gnd // Pic Pins B7 B6 B5 B4 B3 B2 B1 B0 // D0 D1 D2 D3 D4 D5 D6 D7 // // PortA A0 A1 A2 A3 A4 // WR SEL TEST RST BUSY // A0-A3 output A4 input. // // WR, SEL active low. data latched on WR 0->1; RST must be momentarily grounded // at start up to activate display. #define F628 #ifdef F628 #include <P16F628.h> #else #include <P16F84.h> #endif #include "uS_delay.c" #define CONTROL_PORT PORTA #define DATA_PORT PORTB #define WR_PIN PA.B0 #define SEL_PIN PA.B1 #define TEST_PIN PA.B2 #define RST_PIN PA.B3 #define BUSY_PIN PA.B4 #define HIGH 1 #define LOW 0 #define STROBE (PORTA^=1) #define MAX_ROW 20 #define LINES 2 // VFD Control Commands #define LF 0x0A //Line Feed #define CR 0x0D //Carriage Return #define CUROFF 0x14 //DC4 #define CURON 0x13 //DC3 #define DIMM 0x04 //Dimming uses vfd_command #define DIM2 0x20 //Dimm 20% #define DIM4 0x40 //Dimm 40% #define DIM8 0x80 //Dimm 80% #define DIMF 0xFF //Dimm 100% #define VTS 0x12 //DC2 Mode #define NORM 0x11 //DC1 Mode #define HTS 0x09 //Tab right one space #define BSP 0x09 //Backspace #define DP 0x10 //Display position uses vfd_command #define RST 0x1F //Soft reset #ifdef F628 # __config 0x3F61 //16F628 fuse #else # __config 0x3FF1 //16F84(a) fuse #endif //Prototypes void main(); void setup(); void reset_vfd(); void test_vfd(); void vfd_display(unsigned char *disp_string); void vfd_out(unsigned char *text); void vfd_ch(unsigned char ch); void vfd_command(unsigned char com, unsigned char action); void vfd_position(unsigned char line,unsigned char pos); void main() { setup(); big_delay(10); //settling time reset_vfd(); //Hard reset test_vfd(); //Run inbuilt test routine SEL_PIN=LOW; //Enable display for data big_delay(10); vfd_ch(CUROFF); vfd_display("Futoba VFD Display"); big_delay(3000); vfd_command(LF,CR); vfd_display("Dimming 20%"); vfd_command(DIMM,DIM2); //20% brightness big_delay(5000); vfd_command(DIMM,DIMF); //Full brightness vfd_ch(RST); // Clear display vfd_ch(CUROFF); vfd_command(CR,LF); vfd_display("pos"); vfd_position(2,5); vfd_display("2,5"); big_delay(5000); vfd_ch(VTS); vfd_display(" vertical tab"); big_delay(5000); vfd_ch(RST); vfd_ch(CUROFF); vfd_display("Futoba VFD Display"); vfd_position(2,5); vfd_display("End of Demo"); vfd_command(DIMM,DIM4); //40% brightness while(1) { } //forever! } // cmcon=(1<<CM2) |(1<<CM1) |(1<<CM0) void setup() { #ifdef F628 CMCON=0x07; // switch comparators off #endif CONTROL_PORT=0x0E; // RST=1 TEST=1 SEL=1 WR=0 DATA_PORT=0; TRISA=0x10; //PortA A4=in a4:a0 out TRISB=0x00; } void reset_vfd() { RST_PIN=LOW; //Take reset pin low to awake VFD small_delay(1); //12 microsecond settling time RST_PIN=HIGH; //Return reset pin to operating state } void test_vfd() { TEST_PIN=LOW; big_delay(28000); // delay 20 seconds approx TEST_PIN=HIGH; } void vfd_display(unsigned char *string) { while(*string) //while not end of string { vfd_out(string); *string++; //move to next character } } // Following routine only required due to pin out chosen. This was chosen from // a PCB perspective. // // D7 D6 D5 D4 D3 D2 D1 D0 -> D0 D1 D2 D3 D4 D5 D6 D7 // // Using the extra variable 'original1' saves 3 program words unsigned char buffer,original; void vfd_out(unsigned char *text) { const unsigned char table[16]= {0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07,0x0F}; unsigned char original1; original=*text; original1=original & 0x0f; // Mask off lower nibble buffer=table[original1]; //look up conversion pattern lower nibble #asmline swapf buffer,f ;swap places make it high nibble #asmline swapf original,f ;swap original byte around original&=0x0f; buffer|=table[original]; //look up pattern for new lower nibble //IOR with current contents DATA_PORT=buffer; //Bung it on to PORTB while (BUSY_PIN) { } STROBE; //Clock the data into the VFD small_delay(30); //100 microseconds STROBE; //Return pin low } void vfd_ch(unsigned char ch) { unsigned char *text; text=&ch; vfd_out(text); } void vfd_command(unsigned char com, unsigned char action) { vfd_ch(com); vfd_ch(action); } void vfd_position(unsigned char line,unsigned char pos) { if (line==LINES) { pos+=(MAX_ROW-1); } else { pos=-1; } vfd_command(DP,pos); }
Code for a vacuum flourescent display in C //**Project Name: VFD //**File Name : vfd0_3.c //**Version : 0.3 //**Date : 24/02/2002 //**Revision : 28/02/2002 added bit swap routine //** : 02/03/2002 fixed error in display routine and added delay to //** : WR_PIN strobe. //** : //** //**Processor :16F84/628 //** //** Copyright CDB. email bodgy1@optusnet.com.au // Program to display data on a Futoba M202SD08GL vacuum fluorescent display. // Using parallel mode. Data is on port B and control on port A. // Connections as follows // // Display Pins. 1 3 5 7 9 11 13 15 // Data Bits. 7 6 5 4 3 2 1 0 // // Control Pins. 20 18 17 16 8 // Signal Name. Busy SEL WR TEST RST // // Pins 2 4 6 +5v; 10 12 14 Gnd // Pic Pins B7 B6 B5 B4 B3 B2 B1 B0 // D0 D1 D2 D3 D4 D5 D6 D7 // // PortA A0 A1 A2 A3 A4 // WR SEL TEST RST BUSY // A0-A3 output A4 input. // // WR, SEL active low. data latched on WR 0->1; RST must be momentarily grounded // at start up to activate display. #define F628 #ifdef F628 #include <P16F628.h> #else #include <P16F84.h> #endif #include "uS_delay.c" #define CONTROL_PORT PORTA #define DATA_PORT PORTB #define WR_PIN PA.B0 #define SEL_PIN PA.B1 #define TEST_PIN PA.B2 #define RST_PIN PA.B3 #define BUSY_PIN PA.B4 #define HIGH 1 #define LOW 0 #define STROBE (PORTA^=1) #define MAX_ROW 20 #define LINES 2 // VFD Control Commands #define LF 0x0A //Line Feed #define CR 0x0D //Carriage Return #define CUROFF 0x14 //DC4 #define CURON 0x13 //DC3 #define DIMM 0x04 //Dimming uses vfd_command #define DIM2 0x20 //Dimm 20% #define DIM4 0x40 //Dimm 40% #define DIM8 0x80 //Dimm 80% #define DIMF 0xFF //Dimm 100% #define VTS 0x12 //DC2 Mode #define NORM 0x11 //DC1 Mode #define HTS 0x09 //Tab right one space #define BSP 0x09 //Backspace #define DP 0x10 //Display position uses vfd_command #define RST 0x1F //Soft reset #ifdef F628 # __config 0x3F61 //16F628 fuse #else # __config 0x3FF1 //16F84(a) fuse #endif //Prototypes void main(); void setup(); void reset_vfd(); void test_vfd(); void vfd_display(unsigned char *disp_string); void vfd_out(unsigned char *text); void vfd_ch(unsigned char ch); void vfd_command(unsigned char com, unsigned char action); void vfd_position(unsigned char line,unsigned char pos); void main() { setup(); big_delay(10); //settling time reset_vfd(); //Hard reset test_vfd(); //Run inbuilt test routine SEL_PIN=LOW; //Enable display for data big_delay(10); vfd_ch(CUROFF); vfd_display("Futoba VFD Display"); big_delay(3000); vfd_command(LF,CR); vfd_display("Dimming 20%"); vfd_command(DIMM,DIM2); //20% brightness big_delay(5000); vfd_command(DIMM,DIMF); //Full brightness vfd_ch(RST); // Clear display vfd_ch(CUROFF); vfd_command(CR,LF); vfd_display("pos"); vfd_position(2,5); vfd_display("2,5"); big_delay(5000); vfd_ch(VTS); vfd_display(" vertical tab"); big_delay(5000); vfd_ch(RST); vfd_ch(CUROFF); vfd_display("Futoba VFD Display"); vfd_position(2,5); vfd_display("End of Demo"); vfd_command(DIMM,DIM4); //40% brightness while(1) { } //forever! } // cmcon=(1<<CM2) |(1<<CM1) |(1<<CM0) void setup() { #ifdef F628 CMCON=0x07; // switch comparators off #endif CONTROL_PORT=0x0E; // RST=1 TEST=1 SEL=1 WR=0 DATA_PORT=0; TRISA=0x10; //PortA A4=in a4:a0 out TRISB=0x00; } void reset_vfd() { RST_PIN=LOW; //Take reset pin low to awake VFD small_delay(1); //12 microsecond settling time RST_PIN=HIGH; //Return reset pin to operating state } void test_vfd() { TEST_PIN=LOW; big_delay(28000); // delay 20 seconds approx TEST_PIN=HIGH; } void vfd_display(unsigned char *string) { while(*string) //while not end of string { vfd_out(string); *string++; //move to next character } } // Following routine only required due to pin out chosen. This was chosen from // a PCB perspective. // // D7 D6 D5 D4 D3 D2 D1 D0 -> D0 D1 D2 D3 D4 D5 D6 D7 // // Using the extra variable 'original1' saves 3 program words unsigned char buffer,original; void vfd_out(unsigned char *text) { const unsigned char table[16]= {0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07,0x0F}; unsigned char original1; original=*text; original1=original & 0x0f; // Mask off lower nibble buffer=table[original1]; //look up conversion pattern lower nibble #asmline swapf buffer,f ;swap places make it high nibble #asmline swapf original,f ;swap original byte around original&=0x0f; buffer|=table[original]; //look up pattern for new lower nibble //IOR with current contents DATA_PORT=buffer; //Bung it on to PORTB while (BUSY_PIN) { } STROBE; //Clock the data into the VFD small_delay(30); //100 microseconds STROBE; //Return pin low } void vfd_ch(unsigned char ch) { unsigned char *text; text=&ch; vfd_out(text); } void vfd_command(unsigned char com, unsigned char action) { vfd_ch(com); vfd_ch(action); } void vfd_position(unsigned char line,unsigned char pos) { if (line==LINES) { pos+=(MAX_ROW-1); } else { pos=-1; } vfd_command(DP,pos); }
Comments: