Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC driving LCD with IIC protocol

Status
Not open for further replies.

junmab

New Member
I would like to use a PIC to drive a small LCD with IIC (the driver of LCD is SSD1306).
I'm usually using the 12F675 for all my applications, but i've been thinking to try a newer PIC that also has
a IIC capability.
Do you think it worth to write the IIC protocol manually for the 12F675, or it will be much easier to use
the built in protocol of the 16F1503 ?
 
It is easier once you've worked out the i2c module on the pic, getting it to work the first time can be tricky.
As far as I can remember the midrange series allthough they have i2c capability its only basic, you still need to do a lot of the work in software, its not just a case of dump a byte in a register and its sent.
The 18 series do have full implementation of i2c including general call and multi master, all within control of the i2c function block.
 
Using a PIC with I2C hardware, while there will still need to be some stuff done it software, is far easier than trying to bit bang I2C.

On a PIC with I2C hardware, you will need to create functions that send the start bits, ack/nack bits, and stop bits. On the I2C hardware is a control register with control bits that send these bits. If using a 16F887, this register is SSPCON2. If coding in C with the XC8 compiler, the code for sending the start bit would look something like this -

Code:
void i2cStartBit(void)
{
       SSPCON2bits.SEN = 1;                 //send start bit
       while(SSPCON2bits.SEN);           //wait for start bit send to complete
       PIR1bits.SSPIF = 0;                     //clear MSSP interrupt flag
}

You'll need to create similar functions for sending the stop bit, ack bit, nack bit, as well as sending the bytes -

Code:
void i2cStopBit(void)
{
       SSPCON2bits.PEN = 1;                 //send stop bit
       while(SSPCON2bits.PEN);           //wait for stop bit send to complete
       PIR1bits.SSPIF = 0;                     //clear MSSP interrupt flag
}

void i2cAckNackBit(void)
{
       SSPCON2bits.ACKEN = 1;                 //send ack/nack bit
       while(SSPCON2bits.ACKEN);           //wait for ack/nack bit send to complete
       PIR1bits.SSPIF = 0;                           //clear MSSP interrupt flag
}

void i2cAckBit(void)
{
       SSPCON2bits.ACKDT = 0;                 //set up for sending ack bit
       i2cAckNackBit();                                //send ack bit
}

void i2cNackBit(void)
{
       SSPCON2bits.ACKDT = 1;                 //set up for sending nack bit
       i2cAckNackBit();                                //send nack bit
}

void i2cSend(unsigned char a)
{
       SSPBUF = a;                                        //send byte
       while(!PIR1bits.SSPIF);                     //wait for send to complete
       PIR1bits.SSPIF = 0;                           //clear MSSP interrupt flag
}

unsigned char i2cReceive(void)
{
       SSPCON2bits.RCEN = 1;                 //enable I2C receive mode
       while(SSPCON2bits.RCEN);           //wait for receive to complete
       unsigned char a = SSPBUF;            //fetch received data from MSSP buffer
       PIR1bits.SSPIF = 0;                        //clear MSSP interrupt flag
       return a;                                          //return with received data
}

For some operations you may need to resend the start bit. Here's a function that does that -

Code:
void i2cRestartBit(void)
{
       SSPCON2bits.RSEN = 1;                   //resend start bit
       while(SSPCON2bits.RSEN);             //wait for resend to complete
       PIR1bits.SSPIF = 0;                          //clear MSSP interrupt flag
}

Then you would need to create functions that use the above functions to communicate with the LCD.

i2cSend

When using i2cSend(), you would place the byte to be sent in the parenthesis. For instance, if you wanted to send the character A, you would do -

Code:
i2cSend('A');

i2cReceive
When receiving a byte from the I2C device, you would first declare a variable, then equate it to this function -

Code:
unsigned char rxdata = i2cReceive();

Then the I2C module would receive a byte, then place it in the variable rxdata.

If I knew which LCD you planned to use, I could type out some C code that would get you up and running.
 
So here is what i did:
I figured that the first step should be writing to an EEPROM, so i connected 12F675 to 24C02 with 2 wires.
I wrote the functions for the I2C communication and now i can write data to the 24C02.
Now as i have learned how to make communication between 12F675 and an I2C module, it is about time
i'll learn how to control an I2C LCD, which is my final target.
I have this small graphical 128x64 LCD from EBAY. The controller is SSD1306, and i don't know where to find
the instructions set for it. Most of the stuff i found when i Google for SSD1306 is for Ardunio.
Has any one here made a SSD1306 working with PIC ?
Is there an instruction set for this type of display ?
 
Status
Not open for further replies.

Latest threads

Back
Top