Jump to content

Recommended Posts

Hello,

I am inexperienced with using LCD's to output data using PIC's. I have a devantech LCD03 that is capable of operating in serial or I2C mode. The LCD manufacturer website provides an example code using I2C compiled with HITECH - C. I am having trouble getting this thing to work. Ive read alot of articles on using I2C and serial but I cant get it to work with either mode. This is what I have so far:

 

 

CODE:

 

#include <system.h>

#define PIC16F877A

#pragma CLOCK_FREQ 20000000

#include "serial.h"

 

int main()

{

// Port configuration

 

adcon1 = 0x06; //all digital pins on PORTA

 

porta = 0;

portb = 0;

portc = 0x04;

 

trisa = 00000000b;

trisb = 00000000b;

trisc = 01000000b;

 

//option_reg = 01000101b;

 

serialInit(0x40);

serialSendChar(0x00);

serialSendChar(0x05);

serialSendChar(0x0C);

serialSendString("Test!");

 

return 0;

}

 

HEADER FILE

 

#ifndef _serial.h

#define _serial.h

 

void serialInit(char rateScaler); //Initialize serial port on PIC

void serialSendChar(char value); //Send a bye to serial port

char serialReceiveChar(); //Receive a char on serial port

void serialSendString(const char* text); //Send a string through serial port

 

#include <system.h>

#endif

#include <system.h>

 

/*Function that will initialize the serial port in the microcontroller by

writing to several registers */

 

void serialInit(char rateScaler)

{

spbrg = rateScaler; //baud rate init

txsta = 00100100b; //transmit init

rcsta = 10010000b; //receive init

}

 

/*Function that will send a byte through the serial port */

 

void serialSendChar(char value)

{

 

/*Wait until TRMT flag is set.

This is needed because we need

to ensure that output buffer

is not full*/

 

while((txsta & 1 << TRMT) == 0);

txreg = value; //Send byte to output buffer

}

 

 

 

 

/*Function that will receive a byte from the buffer */

 

char serialReceiveChar()

{

char temp;

 

/* Wait until RCIF flag set. This is

needed because we have to wait for

receive buffer to be full meaning

that the receive has successfully

completed in shifting the data

into the buffer */

 

while((pir1 & 00100000b) == 0);

temp = rcreg; //Read value in buffer

return temp; //Return received data

}

 

/*Function that will send a sequence of bytes out the serial port */

 

void serialSendString(const char* text)

{

char i = 0;

while(text != 0)

serialSendChar(text[i++]);

}

 

Any help to push me in the right direction will be greatly appreciated whether it is using I2C or Serial communication. Thanks in advance.

Link to post
Share on other sites

I recommend the usage of the i2c driver that comes along with the distribution. I assume that you have assembled the external pull-ups on the i2c bus. Here is how to use the i2c interface. Note: I did neither compile nor test the code below and I assumed that the your LCD does not need to be configured. Please check again that the #defines map the register names to the correct addresses of your PIC device. I have this i2c driver running on a different PIC device together with a different i2c LCD.

 

 

////////////////////////////////////////////////////////////////////////////
// i2c hardwareware implementation template arguments
////////////////////////////////////////////////////////////////////////////
#define i2c_ARGS	3, PORTC, TRISC, 4, PORTC, TRISC, e_SSPCON1, e_SSPCON2, \
				e_SSPSTAT, e_SSPBUF, e_SSPIF_BIT, e_SSPIF_PIR,			\
				e_BCLIF_BIT, e_BCLIF_PIR, 7, e_SSPADD, (i2c_reset_wdt | i2c_SMP |i2c_HW)

// variables cannot be passed as template arguments. The following constants map to
// the PIC registers and PIC's i2c register locations. These constants are
// then used by the templated functions. 
#define PORTC		0x07
#define TRISC		0x87
#define e_SSPCON1	0x14
#define e_SSPCON2	0x91
#define e_SSPSTAT	0x94
#define e_SSPADD	0x93
#define e_SSPBUF	0x13
#define e_SSPIF_PIR	0x0c
#define e_BCLIF_PIR	0x0d
#define e_SSPIF_BIT	3
#define e_BCLIF_BIT	3

#include "i2c_driver.h" 

main(void)
{
i2c_init0x00);

i2c_start();
i2c_write(0Xc6);
i2c_write('A');
i2c_stop();
}

Link to post
Share on other sites

I followed your advise and used the i2c driver that comes with distribution. However I am still having problems. When I turn on the LCD it only displays "LCDO3 REVISION7 I2C MODE @ 0XC6" but it doesnt clear the screen or write text to it. Am I missing something or doing something wrong? Any help is appreciated. Here is my code:

 

#include <system.h>
#define PIC16F877A
#pragma CLOCK_FREQ	20000000

#include <string.h>

#define i2c_ARGS	3, PORTC, TRISC, 4, PORTC, TRISC, e_SSPCON1, e_SSPCON2, \
				e_SSPSTAT, e_SSPBUF, e_SSPIF_BIT, e_SSPIF_PIR,			\
				e_BCLIF_BIT, e_BCLIF_PIR, 7, e_SSPADD, (i2c_reset_wdt | i2c_SMP |i2c_HW)

//#define PORTC		0x07		//commented out because of illegal redefinition
//#define TRISC		0x87		//commented out because of illegal redefinition
#define e_SSPCON1	0x14
#define e_SSPCON2	0x91
#define e_SSPSTAT	0x94
#define e_SSPADD	0x93
#define e_SSPBUF	0x13
#define e_SSPIF_PIR	0x0C
#define e_BCLIF_PIR	0x0D
#define e_SSPIF_BIT	3
#define e_BCLIF_BIT	3

#include "I2C_Driver_mod.h"

main(void)
{
//trisc = 00000000b;
//portc = 0;

char text[20];
int max, j;

i2c_init(0x00);
i2c_start();				//set i2c to start condition
i2c_write(0xC6);			//send lcd address
i2c_write(0x00);				//write to register 0
i2c_write(0x05);		 	//cursor type: underline
i2c_write(0x0C);		 		//clears screen and sets cursor to home position
strcpy(text,"Greetings");
max=strlen(text);				//find the length of string to be sent
for(j=0; j<=max; j++)
{
	i2c_write(text[j-1]);			//send character at a time to LCD
}
i2c_stop();
}



HEADER FILE

////////////////////////////////////////////////////////////////////////////
// I2C Communications Library for I2C MASTER
////////////////////////////////////////////////////////////////////////////
// Author(s): Andrew Smallridge
// Date 15 November 2004
//
// Copyright(C) 2004-2006 Andrew Smallridge
// Copyright(C) 2004-2007 Pavel Baranov
// Copyright(C) 2004-2007 David Hobday
// Existing constants predefined for i2c hardware driver and i2s software
// emulation for the PIC 18F2xx and 18F4xx processors. For hardware support
// on other PICs the constants must be mapped to the corresponding register
// map of the target device
////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
//	The following three sections should be copied to the user's program:
//		i2c master hardware / software mode definition
//		i2c software implementation template arguments and variables
// 		i2c hardwareware implementation template arguments
////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
// i2c master hardware / software mode definition
//
// For i2c hardware support comment out the #define use_ic2_SW line
////////////////////////////////////////////////////////////////////////////
//#define use_i2c_SW

#if defined use_i2c_SW
////////////////////////////////////////////////////////////////////////////
// i2c software implementation template arguments and variables
////////////////////////////////////////////////////////////////////////////
#define i2c_ARGS	3, PORTC, TRISC, 4, PORTC, TRISC, e_SSPCON1, e_SSPCON2, \
				e_SSPSTAT, e_SSPBUF, e_SSPIF_BIT, e_SSPIF_PIR,			\
				e_BCLIF_BIT, e_BCLIF_PIR, 7, e_SSPADD, (i2c_reset_wdt | i2c_SMP)

//RAM used by the software i2c driver to emulate the equivalent i2c hardware registers					
unsigned short swi2c_SSPCON1@0x14;	// define location for the emulated SSPCON1
unsigned short swi2c_SSPCON2@0x91;	// define location for the emulated SSPCON2
unsigned short swi2c_SSPSTAT@0x94;	// define location for the emulated SSPSTAT
unsigned short swi2c_SSPBUF@0x13;	// define location for the emulated SSPBUF
unsigned short swi2c_SSPIF_PIR@0x0C;// define location for the emulated SSPIF_PIR
unsigned short swi2c_BCLIF_PIR@0x0D;// define location for the emulated BCLIF_PIR
unsigned short swi2c_SSPADD@0x93;	// define location for the emulated SSPADD

#define e_SSPCON1	0x14
#define e_SSPCON2	0x91
#define e_SSPSTAT	0x94
#define e_SSPADD	0x93
#define e_SSPBUF	0x13
#define e_SSPIF_PIR	0x0C
#define e_BCLIF_PIR	0x0D
#define e_SSPIF_BIT	3
#define e_BCLIF_BIT	3

#else
////////////////////////////////////////////////////////////////////////////
// i2c hardwareware implementation template arguments
////////////////////////////////////////////////////////////////////////////
#define i2c_ARGS	3, PORTC, TRISC, 4, PORTC, TRISC, e_SSPCON1, e_SSPCON2, \
				e_SSPSTAT, e_SSPBUF, e_SSPIF_BIT, e_SSPIF_PIR,			\
				e_BCLIF_BIT, e_BCLIF_PIR, 7, e_SSPADD, (i2c_reset_wdt | i2c_SMP |i2c_HW)

//#define PORTC		0x07		//commented out because of illegal redefinition
//#define TRISC		0x87		//commented out because of illegal redefinition
#define e_SSPCON1	0x14
#define e_SSPCON2	0x91
#define e_SSPSTAT	0x94
#define e_SSPADD	0x93
#define e_SSPBUF	0x13
#define e_SSPIF_PIR	0x0C
#define e_BCLIF_PIR	0x0D
#define e_SSPIF_BIT	3
#define e_BCLIF_BIT	3

#endif

.....so on

Link to post
Share on other sites

In the HITECH code for the LCD the initialization is different and there is a for-loop after the init. Try doing something similar. Can you operate the PIC at 4MHz as the example code does?

 

void setup(void)
{
unsigned long x;

TRISC = 0xff;
PORTC = 0xff;

SSPSTAT = 0x80;
SSPCON = 0x38;
SSPCON2 = 0x00;
SSPADD = 10;				// SCL = 91khz with 4Mhz Osc

for(x=0; x<60000; x++);		// wait for LCD03 to initialise

}

 

If you have an oscilloscope or a logic analyzer, check if the i2c communication is acknowledged: SDA line should be low (=ack) during 9th clock pulse. If you don't have a scope, try reading the version (register 0x03) of the LCD. This should give you the feedback if the LCD understands the i2c. You can send the read value to the RS232 and display it on the PC with a terminal program (e.g. hterm). Or connect an LED to one GPIO pin and visualize the bits of the read value serially.

 

Regards

manuel123

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...