i am using the eb083 combo/development board, all parts are function using the testing Hex files provide by matrix, but when i come to program the LCD alone it will not work with my code when using a PIC16F1937 but it does when using a PIC16F877A. the same code using the PIC16F1937 works with another LCD i wired up on a protoboard and plugged into portC. also with the PIC16F1937 flowcode can work the LCD perfectly. i've stared at data sheets for 2 days and cant find anything wrong with my code, so what is the problem (probably my code).
Code: Select all
/*******************************************************************************
INFO
*******************************************************************************/
// LCD Driver module
// LCD module is connected as follows:
// RB0 - RB3 -> DB4 - DB7
// RB4 -> RS
// RB5 -> E
/*******************************************************************************
DEFINITIONS
*******************************************************************************/
#define RS PORTB.B4 // RS control line is bit 4 of port B
#define E PORTB.B5 // E control line is bit 5 of port B
#define LCD_INIT 0x33 // command to initialise LCD display
#define FOUR_BIT_MODE 0x32 // command to make the LCD transfer instructions and data in 4 bit chunks rather than 8
#define TWO_LINE_MODE 0x2c // command to put the LCD in two-line mode
#define MOVE_AFTER_WRITE 0x06 // command to increment cursor position automatically
#define DISPLAY_INIT 0x0c // command to turn display on, switch off the cursor and stop it blinking
#define WRITE_DELAY 1000 // constant used to set write delay time (50 us required)
#define BIT_DELAY 40 // constant used to set pulse duration (a few us required)
#define INST_DELAY 31000 // constant used to det instruction delay (1.53 ms required)
/*******************************************************************************
LCD DISPLAY FUNCTIONS
*******************************************************************************/
/*******************************************************************************
LCD SETUP FUNCTIONS
*******************************************************************************/
//********************************SETUP LCD***********************************//
void LCD_setup(void){
unsigned int counter;
// INITIALISE LCD
LCD_write(LCD_INIT, 0); // command to initialise LCD display, (RS = 0)
for (counter = 0; counter < INST_DELAY*Fratio; counter++); // call function to wait until LCD has completed instruction
// Set LCD for 4-bit mode
LCD_write(FOUR_BIT_MODE, 0); // command to set LCD in 4-bit mode, (RS = 0)
for (counter = 0; counter < INST_DELAY*Fratio; counter++); // call function to wait until LCD has completed instruction
// set LCD in up for two lines
LCD_write(TWO_LINE_MODE, 0); // command to set LCD for two lines, (RS = 0)
for (counter = 0; counter < INST_DELAY*Fratio; counter++); // call function to wait until LCD has completed instruction
// Select move after write
LCD_write(MOVE_AFTER_WRITE, 0); // command to set LCD to increment cursor pos. automatically (RS = 0)
for (counter = 0; counter < INST_DELAY*Fratio; counter++); // call function to wait until LCD has completed instruction
// Configure display & cursor
LCD_write(DISPLAY_INIT, 0); // command to configure display, (RS = 0)
for (counter = 0; counter < INST_DELAY*Fratio; counter++); // call function to wait until LCD has completed instruction
LCD_clear();
}
//*****************************END OF FUNCTION********************************//
//*****************************CLEAR LCD AND HOME******************************/
//LCD_clear() function is an instruction to clear all data from LCD display and return cursor to beginning of display
void LCD_clear(void){
unsigned int counter;
LCD_write(1, 0); // call basic write function with instruction 1, (clear display) and RS 0, (write instruction)
for (counter = 0; counter < INST_DELAY*Fratio; counter++); // Call function to wait until LCD has completed instruction
LCD_write(2, 0); // call basic write function with instruction 2, (cursor home) and RS = 0, (write instruction)
for (counter = 0; counter < INST_DELAY*Fratio; counter++); // call function to wait until LCD has completed instruction
}
//*****************************END OF FUNCTION********************************//
/*******************************************************************************
LCD WRITE FUNCTIONS
*******************************************************************************/
//*****************************LCD WRITE SUBROUTINE***************************//
void LCD_write(unsigned char c, unsigned char rs){
// LCD_write() function is a basic write subroutine that could be an instruction or data
// Note: PORTB interrupts are not available during execution of this function
unsigned char temp; // temporary variable to hold ms 4 bits of c
unsigned char RSmask = 0; // used to set or reset bit 4 of PORTB
unsigned char TRISB_BAK; // Current status of port B data direction register
unsigned char INTCON_BAK;
//unsigned char PORTB_BAK;
// INITIALISATION
TRISB_BAK = TRISB; // Get current state of TRISB register
TRISB = 0x00; // Set PORTB bits 0 - 7 as outputs
INTCON_BAK = INTCON; // Get current state of INTCON reg.
INTCON = INTCON & 0xE7; // Disable RB0/INT and RBI interrupts (stops write operation on PORTB triggering them)
if (rs == 1) RSmask = 0x10; // set up bit mask for RS line
// set MS 4 bits of c up on RB0 - RB3
temp = c;
PORTB = (temp >> 4) | RSmask; // shift MS 4 bits into LS 4 bits, set/rst RS and present on PORTB
// pulse E high then low
pulse_E(); // call function to strobe data to LCD module
// set LS 4 bits up on RB0 - RB3
PORTB = (c & 0x0F) | RSmask; // present LS 4 bits on RB0 - RB3 and set/rst RS line
// pulse E high then low
pulse_E(); // Call function to strobe data to LCD module
PORTB = 0x10; // set E high again to avoid annoying LED flicker
TRISB = TRISB_BAK; // Restore state of TRISB register
temp = PORTB; // Read PORTB avoid retriggering RBIF
//RBIF=0; // Clear RBIF interrupt flag to avoid false trigger on exit
INTCON.B0 = 0;
//INTF=0; // Clear RBIF interrupt flag to avoid false trigger on exit
INTCON.B1 = 0;
INTCON = INTCON_BAK; // Restore state of INTCON register
}
//*****************************END OF FUNCTION********************************//
//**************************LCD WRITE CHARACTER*******************************//
void LCD_putch(unsigned char c){
unsigned int counter;
LCD_write(c, 1); // call basic LCD write routine with RS high (send data)
for (counter = 0; counter < WRITE_DELAY*Fratio; counter++); // call function to wait until LCD has completed write operation
}
//*****************************END OF FUNCTION********************************//
//*************************LCD WRITE CHARACTER STRING*************************//
void LCD_puts(unsigned char *s){
unsigned char c = 255;
unsigned char i = 0;
while ((c > 0) && (i < 16)){ //16 is the maximum length of the string
c = s[i];
if (c != 0) LCD_putch(c);
i++;
}
}
//*****************************END OF FUNCTION********************************//
/*******************************************************************************
LCD CURSOR FUNCTIONS
*******************************************************************************/
//********************PULSE E PIN HIGH/LOW FOR FEW uSECS**********************//
void pulse_E(void){
unsigned int counter;
// set E high and wait a bit
E = 1; // set E line high
for (counter = 0; counter < BIT_DELAY*Fratio; counter++); // pulse delay for E
// set E low and wait a bit
E = 0; // set E line low
for (counter = 0; counter < BIT_DELAY*Fratio; counter++); // pulse delay for E
}
//*****************************END OF FUNCTION********************************//
//******************************END OF SOUCRE*********************************//