0
\$\begingroup\$

I've been trying to interface an i2c Oled display on pic18f26j50 microcontroller but i can't get it to work.

I'm using mikroC pro for pic.

#include "ssd1306.h"
#include "font.h"
#include "bitmap.h"

void main() {

 ANCON0 = 0x1F;
 ANCON1 = 0x1F;

 SSPSTAT=0x80;
 SSPADD=0x18;                                     //100khz baud rate
 SSPCON1=0x28;                                    // Master mode in I2c.
 SSPCON2=0x00;
 TRISB4_bit=1;
 TRISB5_bit=1;

 I2C1_Init(100000);

 Oled_Init();
 Oled_Fillscreen(0x00);
 Oled_Image(image,7,40,0,2);
}

I've used the exact same code(with obvious register value changes) on a pic18f2550... and it works like a charm....

as a last resort i've changed all of the code to work with software I2C... it works but its very slow. So obviously problem is not with the display but with the microcontroller code.

Can anyone point me to the right direction?

Oled_Init() consists of the following code.

void Oled_Init(void){
TRIS_RES = 0;
OLED_RES = 0;
Oled_Command(0xAE);                     // Set Display OFF
Oled_Command(0x81); Oled_Command(0xCF); // Set Contrast Control
Oled_Command(0xA4);                     // Entire Display ON
Oled_Command(0xA6);                     // Set Normal

Oled_Command(0x20); Oled_Command(0x02); // Set Memory Addressing Mode
Oled_Command(0x00);                     // Set Lower Column
Oled_Command(0x10);                     // Set Higher Column
Oled_Command(0xB0);                     // Set Page Start

Oled_Command(0x40);                     // Set Display Start Line
Oled_Command(0xA1);                     // Set Segment Re-map
Oled_Command(0xA8); Oled_Command(0x3F); // Set Multiplex Ratio
Oled_Command(0xC8);                     // Set COM Output
Oled_Command(0xD3); Oled_Command(0x00); // Set Display Offset
Oled_Command(0xDA); Oled_Command(0x12); // Set COM Pins Hardware Configuration

Oled_Command(0xD5); Oled_Command(0x80); // Set Display Clock
Oled_Command(0xD9); Oled_Command(0xF1); // Set Pre-charge Period
Oled_Command(0xDB); Oled_Command(0x40); // Set VCOMH Deselect Level
Oled_Command(0x8D); Oled_Command(0x14); // Charge Pump Setting

Oled_Command(0xAF);                     // Set Display ON
Oled_FillScreen(0x00);                  // Clear screen
}

and Oled_Command() function

void Oled_Command(uchar cmd){
I2C1_Start();
I2C1_Wr(OLED_12C_ADDRESS);
I2C1_Wr(0x00);  // Co = 0, D/C = 0
I2C1_Wr(cmd);
I2C1_Stop();
}
\$\endgroup\$
  • 1
    \$\begingroup\$ may I suggest using MPLAB Code Configurator to create an I2C library and you can use the generated code (header and source files) or simply check for differences in registers uses and values. You'll be done in minutes. \$\endgroup\$ – fhlb Sep 3 '16 at 11:26
  • \$\begingroup\$ @fhlb Forgot to mention... I'm using mikroc pro for pic \$\endgroup\$ – Suraj Bhawal Sep 3 '16 at 11:46
  • \$\begingroup\$ If your using MikroC then don't write into registers and use only I2C1_Init \$\endgroup\$ – fhlb Sep 3 '16 at 11:56
  • \$\begingroup\$ And make sure that the OLED can handle 100Khz. read the datasheet or simply try to lower the frequenct in I2C1_init \$\endgroup\$ – fhlb Sep 3 '16 at 12:00
  • 2
    \$\begingroup\$ It's not irrelevant because 'soft' bit-banged I2C is often much slower which allows for higher value pullups. I'd try 2k2 or even lower unless you've already put a 'scope on the line to check the rise time. \$\endgroup\$ – brhans Sep 3 '16 at 17:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.