EB083 LCD Programming Problem

For E-blocks user to discuss using E-blocks and programming for them.

Moderators: Benj, Mods

Post Reply
lordgarth6
Posts: 2
Joined: Fri Apr 18, 2014 2:17 am
Has thanked: 2 times
Contact:

EB083 LCD Programming Problem

Post by lordgarth6 »

Hello,
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*********************************//

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: EB083 LCD Programming Problem

Post by Benj »

Hello,

Flowcode automatically adds these commands to the start of main for the 16F1937 device to setup all the I/O into digital mode, maybe adding these to your program would help.

Code: Select all

ansela = 0x00;
anselb = 0x00;
anseld = 0x00;
ansele = 0x00;

option_reg = 0xC0;

User avatar
LeighM
Matrix Staff
Posts: 2178
Joined: Tue Jan 17, 2012 10:07 am
Has thanked: 481 times
Been thanked: 699 times
Contact:

Re: EB083 LCD Programming Problem

Post by LeighM »

Also might be worth changing your E and RS macros (defines) to use LATB rather than PORTB

lordgarth6
Posts: 2
Joined: Fri Apr 18, 2014 2:17 am
Has thanked: 2 times
Contact:

Re: EB083 LCD Programming Problem

Post by lordgarth6 »

Benj wrote:Hello,

Flowcode automatically adds these commands to the start of main for the 16F1937 device to setup all the I/O into digital mode, maybe adding these to your program would help.

Code: Select all

ansela = 0x00;
anselb = 0x00;
anseld = 0x00;
ansele = 0x00;

option_reg = 0xC0;

perfect cheers

Post Reply