CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

OLED 128x64 SSD1306 I2C PIC16F1788 driver

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
superfranz



Joined: 05 Sep 2014
Posts: 10
Location: Trieste, Italy

View user's profile Send private message Send e-mail

OLED 128x64 SSD1306 I2C PIC16F1788 driver
PostPosted: Sat Sep 06, 2014 5:05 pm     Reply with quote

Hi,
I'm glad to share with you a simple but working code i've wrote for use SSD1306 oled display 128x64 with ours pics.

I'm using PIC16f1788 and tested on 18f4525.

good for any pic with i2c and 1k and little more of RAM.

(line, circle, rect copied and adapted from glcd library)


Code:
#include <16F1788.h>
#device ADC=16
#FUSES NOWDT                   
#FUSES NOBROWNOUT             
#FUSES NOLVP                   
#use delay(internal=32000000)
#use i2c(Master,Fast=400000,sda=PIN_C4,scl=PIN_C3,force_sw) // maybe force_hw
#include <string.h>
#define OLED 0x78
#INCLUDE <stdlib.h>

const BYTE TEXT[51][5] =
{

   0x00, 0x00, 0x00, 0x00, 0x00, // SPACE
   0x00, 0x00, 0x5F, 0x00, 0x00, // !
   0x00, 0x03, 0x00, 0x03, 0x00, // "
   0x14, 0x3E, 0x14, 0x3E, 0x14, // #
   0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
   0x43, 0x33, 0x08, 0x66, 0x61, // %
   0x36, 0x49, 0x55, 0x22, 0x50, //&
   0x00, 0x05, 0x03, 0x00, 0x00, // '
   0x00, 0x1C, 0x22, 0x41, 0x00, // (
   0x00, 0x41, 0x22, 0x1C, 0x00, //)
   0x14, 0x08, 0x3E, 0x08, 0x14, // *
   0x08, 0x08, 0x3E, 0x08, 0x08, // +
   0x00, 0x50, 0x30, 0x00, 0x00, //,
   0x08, 0x08, 0x08, 0x08, 0x08, // -
   0x00, 0x60, 0x60, 0x00, 0x00, // .
   0x20, 0x10, 0x08, 0x04, 0x02, // /
   0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
   0x04, 0x02, 0x7F, 0x00, 0x00, // 1
   0x42, 0x61, 0x51, 0x49, 0x46, // 2
   0x22, 0x41, 0x49, 0x49, 0x36, // 3
   0x18, 0x14, 0x12, 0x7F, 0x10, // 4
   0x27, 0x45, 0x45, 0x45, 0x39, // 5
   0x3E, 0x49, 0x49, 0x49, 0x32, // 6
   0x01, 0x01, 0x71, 0x09, 0x07, // 7
   0x36, 0x49, 0x49, 0x49, 0x36, // 8
   0x26, 0x49, 0x49, 0x49, 0x3E, // 9
   0x00, 0x36, 0x36, 0x00, 0x00, // :
   0x00, 0x56, 0x36, 0x00, 0x00, //;

   0x08, 0x14, 0x22, 0x41, 0x00, // <
   0x14, 0x14, 0x14, 0x14, 0x14, // =
   0x00, 0x41, 0x22, 0x14, 0x08, // >
   0x02, 0x01, 0x51, 0x09, 0x06, // ?
   0x3E, 0x41, 0x59, 0x55, 0x5E, // @
   0x7E, 0x09, 0x09, 0x09, 0x7E, // A
   0x7F, 0x49, 0x49, 0x49, 0x36, // B
   0x3E, 0x41, 0x41, 0x41, 0x22, // C
   0x7F, 0x41, 0x41, 0x41, 0x3E, // D
   0x7F, 0x49, 0x49, 0x49, 0x41, // E
   0x7F, 0x09, 0x09, 0x09, 0x01, // F
   0x3E, 0x41, 0x41, 0x49, 0x3A, // G
   0x7F, 0x08, 0x08, 0x08, 0x7F, // H
   0x00, 0x41, 0x7F, 0x41, 0x00, // I
   0x30, 0x40, 0x40, 0x40, 0x3F, // J
   0x7F, 0x08, 0x14, 0x22, 0x41, // K
   0x7F, 0x40, 0x40, 0x40, 0x40, // L
   0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
   0x7F, 0x02, 0x04, 0x08, 0x7F, // N
   0x3E, 0x41, 0x41, 0x41, 0x3E, // O
   0x7F, 0x09, 0x09, 0x09, 0x06, // P
   0x1E, 0x21, 0x21, 0x21, 0x5E, // Q
   0x7F, 0x09, 0x09, 0x09, 0x76
}; // R

const BYTE TEXT2[44][5]=
{
   0x26, 0x49, 0x49, 0x49, 0x32, // S
   0x01, 0x01, 0x7F, 0x01, 0x01, // T
   0x3F, 0x40, 0x40, 0x40, 0x3F, // U
   0x1F, 0x20, 0x40, 0x20, 0x1F, // V
   0x7F, 0x20, 0x10, 0x20, 0x7F, // W
   0x41, 0x22, 0x1C, 0x22, 0x41, // X
   0x07, 0x08, 0x70, 0x08, 0x07, // Y
   0x61, 0x51, 0x49, 0x45, 0x43, // Z
   0x00, 0x7F, 0x41, 0x00, 0x00, // [
   0x02, 0x04, 0x08, 0x10, 0x20, // \
   0x00, 0x00, 0x41, 0x7F, 0x00, // ]
   0x04, 0x02, 0x01, 0x02, 0x04, // ^
   0x40, 0x40, 0x40, 0x40, 0x40, // _
   0x00, 0x01, 0x02, 0x04, 0x00, // `
   0x20, 0x54, 0x54, 0x54, 0x78, // a
   0x7F, 0x44, 0x44, 0x44, 0x38, // b
   0x38, 0x44, 0x44, 0x44, 0x44, // c
   0x38, 0x44, 0x44, 0x44, 0x7F, // d
   0x38, 0x54, 0x54, 0x54, 0x18, // e
   0x04, 0x04, 0x7E, 0x05, 0x05, // f
   0x08, 0x54, 0x54, 0x54, 0x3C, // g
   0x7F, 0x08, 0x04, 0x04, 0x78, // h
   0x00, 0x44, 0x7D, 0x40, 0x00, // i
   0x20, 0x40, 0x44, 0x3D, 0x00, // j
   0x7F, 0x10, 0x28, 0x44, 0x00, // k
   0x00, 0x41, 0x7F, 0x40, 0x00, // l
   0x7C, 0x04, 0x78, 0x04, 0x78, // m
   0x7C, 0x08, 0x04, 0x04, 0x78, // n
   0x38, 0x44, 0x44, 0x44, 0x38, // o
   0x7C, 0x14, 0x14, 0x14, 0x08, // p
   0x08, 0x14, 0x14, 0x14, 0x7C, // q
   0x00, 0x7C, 0x08, 0x04, 0x04, // r
   0x48, 0x54, 0x54, 0x54, 0x20, // s
   0x04, 0x04, 0x3F, 0x44, 0x44, // t
   0x3C, 0x40, 0x40, 0x20, 0x7C, // u
   0x1C, 0x20, 0x40, 0x20, 0x1C, // v
   0x3C, 0x40, 0x30, 0x40, 0x3C, // w
   0x44, 0x28, 0x10, 0x28, 0x44, // x
   0x0C, 0x50, 0x50, 0x50, 0x3C, // y
   0x44, 0x64, 0x54, 0x4C, 0x44, // z
   0x00, 0x08, 0x36, 0x41, 0x41, //
   {
      0x00, 0x00, 0x7F, 0x00, 0x00, //|
      0x41, 0x41, 0x36, 0x08, 0x00, //
   }

   0x02, 0x01, 0x02, 0x04, 0x02
}; // ~

const INT LOGOS [1024] =
{
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0xBE, 0xB6, 0xF6, 0xE6, 0x00, 0x00, 0xFE, 0xFE, 0x80,
   0x80, 0x80, 0xFE, 0xFE, 0x00, 0x00, 0xFE, 0xFE, 0x84, 0x86, 0x86, 0xFE, 0xFC, 0x00, 0x00, 0xFC,
   0xFE, 0x96, 0x96, 0x96, 0x9E, 0xDC, 0x00, 0x00, 0xFE, 0xFE, 0x0C, 0x06, 0x06, 0x00, 0x9C, 0xBE,
   0xB6, 0xF6, 0xE6, 0x00, 0x00, 0xFE, 0xFE, 0x80, 0x80, 0x80, 0xFE, 0xFE, 0x00, 0x00, 0xFE, 0xFE,
   0x84, 0x86, 0x86, 0xFE, 0xFC, 0x00, 0x00, 0xFC, 0xFE, 0x96, 0x96, 0x96, 0x9E, 0xDC, 0x00, 0x00,
   0xFE, 0xFE, 0x0C, 0x06, 0x06, 0x06, 0xFF, 0xFF, 0x06, 0x06, 0x00, 0xFE, 0xFE, 0x0C, 0x06, 0x06,
   0x00, 0xEC, 0xF6, 0x96, 0x96, 0xFE, 0xFC, 0x00, 0x00, 0xFE, 0xFE, 0x0C, 0x06, 0x06, 0xFE, 0xFC,
   0x00, 0x00, 0xC6, 0xE6, 0xB6, 0x9E, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
   0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
   0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x0F, 0x0F,
   0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01,
   0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0x30, 0xB0, 0xD8, 0xD8, 0xD8, 0xD8, 0x18,
   0x30, 0xF0, 0xC0, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 0x80,
   0xC0, 0xC0, 0xC0, 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0xC0,
   0x80, 0x00, 0x00, 0xD8, 0xD8, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00,
   0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x7F, 0x60, 0xCF, 0xDF, 0xD8, 0xCC, 0xDF, 0xDB, 0x18,
   0x1C, 0x0F, 0x07, 0x00, 0x00, 0xDB, 0xFF, 0xB6, 0xB6, 0xB7, 0xF3, 0xE0, 0x00, 0x3F, 0x3F, 0x01,
   0x00, 0x00, 0x3F, 0x3F, 0x01, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x1D, 0x3E, 0x32, 0x12, 0x3F,
   0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00,
   0x1F, 0x3F, 0x30, 0x30, 0x30, 0x19, 0x00, 0x1F, 0x3F, 0x30, 0x30, 0x30, 0x3F, 0x1F, 0x00, 0x00,
   0x3F, 0x3F, 0x01, 0x00, 0x00, 0x3F, 0x3F, 0x01, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x06, 0x06, 0x06, 0xFE, 0xFE, 0x06, 0x06, 0x06, 0x00, 0xF0, 0xF0, 0x60, 0x30, 0x30, 0x00,
   0xF6, 0xF6, 0x00, 0x00, 0xE0, 0xF0, 0xB0, 0xB0, 0xB0, 0xF0, 0xE0, 0x00, 0x00, 0xE0, 0xF0, 0xB0,
   0xB0, 0x30, 0x00, 0x30, 0xFC, 0xFC, 0x30, 0x30, 0x00, 0x00, 0xE0, 0xF0, 0xB0, 0xB0, 0xB0, 0xF0,
   0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0xF6, 0x00, 0x30, 0xFC,
   0xFC, 0x30, 0x30, 0x00, 0x00, 0x60, 0xB0, 0xB0, 0xB0, 0xF0, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x00,
   0x30, 0xF0, 0xC0, 0x00, 0x00, 0xC0, 0xF0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
   0x0F, 0x0F, 0x00, 0x00, 0x07, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x06, 0x00, 0x00, 0x0C, 0x0D, 0x0D,
   0x0F, 0x07, 0x00, 0x00, 0x07, 0x0F, 0x0C, 0x0C, 0x00, 0x00, 0x07, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C,
   0x06, 0x00, 0x20, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x07,
   0x0F, 0x0C, 0x0C, 0x00, 0x00, 0x07, 0x0F, 0x0C, 0x04, 0x0F, 0x0F, 0x00, 0x00, 0x0F, 0x0F, 0x00,
   0x00, 0x01, 0x67, 0x7E, 0x1E, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

int DISPLAY [1024];

void OLED_command(INT ind, int com)
{
   i2c_start ();
   i2c_write (ind);
   i2c_write (0x00);
   i2c_write (com);
   i2c_stop ();
}

void OLED_write(INT ind)
{
   LONG i;
   OLED_command (ind, 0x21) ;
   OLED_command (ind, 0x00);
   OLED_command (ind, 127);
   OLED_command (ind, 0x22) ;
   OLED_command (ind, 0x00);
   OLED_command (ind, 7);
   i2c_start ();
   i2c_write (ind) ;
   i2c_write (0x40) ;
   FOR (i = 0; i < 1024; i++)
   {
     
      i2c_write (DISPLAY[i]) ;
   }

   i2c_stop ();
}

void  OLED_init(INT add)
{
   OLED_command (add, 0xae) ;
   OLED_command (add, 0xa8);
   OLED_command (add, 0x3f);
   OLED_command (add, 0xd3);
   OLED_command (add, 0x00);
   OLED_command (add, 0x40);
   
   OLED_command (add, 0xa0);
   OLED_command (add, 0xa1);
   OLED_command (add, 0xc0);
   
   OLED_command (add, 0xc8);
   OLED_command (add, 0xda);
   OLED_command (add, 0x12);
   OLED_command (add, 0x81);
   OLED_command (add, 0xfF);
   OLED_command (add, 0xa4);
   OLED_command (add, 0xa6) ;
   OLED_command (add, 0xd5);
   OLED_command (add, 0x80);
   OLED_command (add, 0x8d);
   OLED_command (add, 0x14) ;
   OLED_command (add, 0xAF) ;
   OLED_command (add, 0x20) ;
   OLED_command (add, 0x00) ;
}

void OLED_pixel(LONG x,long y)
{
   LONG nt;
   LONG pagina;
   LONG bit;
   pagina = y /8;
   bit= y-(pagina*8);
   nt= DISPLAY[pagina*128+x];
   nt |= 1 << bit;
   DISPLAY[pagina*128+x] = nt;
}

   VOID OLED_line (int x1, int y1, int x2, int y2)
{
      SIGNED int x, y, addx, addy, dx, dy;
      SIGNED long P;
      INT i;
      dx = abs ( (SIGNED int) (x2 - x1));
      dy = abs ( (SIGNED int) (y2 - y1));
      x = x1;
      y = y1;

      IF (x1 > x2)
         addx = -1;

      ELSE
      addx = 1;

      IF (y1 > y2)
         addy = -1;

      ELSE
      addy = 1;

      IF (dx >= dy)
      {
         P = 2 * dy - dx;
         FOR (i = 0; i< = dx;  ++i)
         {
            OLED_pixel (x, y);

            IF (P < 0)
            {
               P += 2*dy;
               x += addx;
            }

            ELSE
            {
               P += 2*dy - 2 * dx;
               x += addx;
               y += addy;
            }
         }
      }

      ELSE
      {
         P = 2 * dx - dy;
         FOR (i = 0; i< = dy;  ++i)
         {
            OLED_pixel (x, y);

            IF (P < 0)
            {
               P += 2*dx;
               y += addy;
            }

            ELSE
            {
               P += 2*dx - 2 * dy;
               x += addx;
               y += addy;
            }
         }
      }
}

   VOID OLED_circle(int x, int y, int radius, int1 riemp)
   {
      SIGNED int a, b, P;
      a = 0;
      b = radius;
      P = 1 - radius;

      DO
      {
         IF (riemp)
         {
            OLED_line (x - a, y+b, x + a, y + b);
            OLED_line (x - a, y-b, x + a, y - b);
            OLED_line (x - b, y+a, x + b, y + a);
            OLED_line (x - b, y-a, x + b, y - a);
         }

         ELSE
         {
            OLED_pixel (a + x, b+y);
            OLED_pixel (b + x, a+y);
            OLED_pixel (x - a, b+y);
            OLED_pixel (x - b, a+y);
            OLED_pixel (b + x, y-a);
            OLED_pixel (a + x, y-b);
            OLED_pixel (x - a, y-b);
            OLED_pixel (x - b, y-a);
         }

         IF (P < 0)
            P += 3 + 2 * a++;

         ELSE
         P += 5 + 2 * (a++ - b--);
      } WHILE (a <= b);
   }

   VOID OLED_text(int x, int y, char* textptr, int size)
   {
      INT i, j, k, l, m;     // Loop counters
      BYTE pixelData[5];     // Stores character data
      FOR (i = 0; textptr[i] != '\0'; ++i, ++x) // Loop through the passed string
      {
         IF (textptr[i] < 'S') // Checks if the letter is in the first text array
            memcpy (pixelData, TEXT[textptr[i] - ' '], 5) ;

         else IF (textptr[i] <= '~') // Check if the letter is in the second array
            memcpy (pixelData, TEXT2[textptr[i] - 'S'], 5) ;

         ELSE
         memcpy (pixelData, TEXT[0], 5); // DEFAULT to space
         IF (x + 5 * size >= 128)  // Performs character wrapping
         {
            x = 0;       // Set x at far left position
            y += 7*size + 1;    // Set y at next position down
         }

         FOR (j = 0; j<5; ++j, x += size)  // Loop through character byte data
         {
            FOR (k = 0; k<7 * size; ++k)  // Loop through the vertical pixels
            {
               IF (bit_test (pixelData[j], k)) // Check if the pixel should be set
               {
                  FOR (l = 0; l<size; ++l) // The next two loops change the
                  {
                     // character's size
                     FOR (m = 0; m<size; ++m)
                     {
                        OLED_pixel (x + m, y+k * size + l); // Draws the pixel
                     }
                  }
               }
            }
         }
      }
   }

   VOID OLED_rect(int x1, int y1, int x2, int y2, int riemp)
   {
      IF (riemp)
      {
         INT y, ymax;      // Find the y min and max
         IF (y1 < y2)
         {
            y = y1;
            ymax = y2;
         }

         ELSE
         {
            y = y2;
            ymax = y1;
         }

         FOR (; y <= ymax; ++y)     // Draw lines to fill the rectangle
            OLED_line (x1, y, x2, y);
      }

      ELSE
      {
         OLED_line (x1, y1, x2, y1); // Draw the 4 sides
         OLED_line (x1, y2, x2, y2);
         OLED_line (x1, y1, x1, y2);
         OLED_line (x2, y1, x2, y2);
      }
   }

   VOID logo()
   {
      LONG x;
      INT c;
      FOR (x = 0; x < 1024; x++)
      {
         c= LOGOS[x];
         DISPLAY[x] = c;
      }
   }

   VOID OLED_clear()
   {
      LONG x;
      FOR (x = 0; x < 1024; x++)
      {
         DISPLAY[x] = 0x00;
      }
   }

   VOID main()
   {
      CHAR txt[100];
      OLED_init(OLED);

      WHILE (1)
      {
         
         OLED_clear();
         logo();
         OLED_write(OLED);
         delay_ms(3000);
         OLED_clear();
         sprintf(txt,"superfranz!");
         OLED_text(0,0,txt,2);
         OLED_circle(15,40,15,0);
         OLED_rect(35,25,65,55,1);
         OLED_circle(80,40,15,1);
         OLED_rect(90,25,120,55,0);
         OLED_write(OLED);
         delay_ms(3000);
      }
   }


Simple, but the only (or the first) working posted in this and others forums.


SuperFranz

from Trieste (Italy)


Last edited by superfranz on Mon Sep 08, 2014 12:37 pm; edited 1 time in total
superfranz



Joined: 05 Sep 2014
Posts: 10
Location: Trieste, Italy

View user's profile Send private message Send e-mail

splash logo
PostPosted: Sat Sep 06, 2014 5:18 pm     Reply with quote

...the splash logo "const int LOGOS[1024]" it's made with LCDAssistant.exe, downloaded somewhere, starting from 128x64 bitmap b/W, with default options (vertical, 8pix/byte). export to txt, open it and copy and paste values.

the rest it's self-explained i hope, or ask me.

bye bye
SuperFranz
miskol



Joined: 01 Feb 2011
Posts: 16

View user's profile Send private message

PostPosted: Mon Sep 22, 2014 8:39 pm     Reply with quote

would you help advice what should i do for use with 128x32 SPI OLED?

i already have my OLED working nicely, but i dont have a working library to support with.

i guess for the SPI part it should be easily replace with the I2C protocols, hope you can help with the difference of 128x32 pixels i'm using.

please help, TQ!
fkl



Joined: 20 Nov 2010
Posts: 40

View user's profile Send private message

Re: OLED 128x64 SSD1306 I2C PIC16F1788 driver
PostPosted: Wed Oct 01, 2014 6:35 am     Reply with quote

superfranz wrote:
1k and little more of RAM.


possible to modify the code to remove this restriction?
to 0.5k
qr_shot



Joined: 28 Nov 2014
Posts: 1

View user's profile Send private message

code gives errors
PostPosted: Fri Nov 28, 2014 4:30 pm     Reply with quote

hi..
im using 16f877a
i edited somewhere but code gave errors.
i need help...
thanks now
amanver



Joined: 06 May 2015
Posts: 4
Location: bonab

View user's profile Send private message

PostPosted: Wed May 06, 2015 8:24 pm     Reply with quote

hi all.
i am working on this project.
compiler ccs4.130
uc :18f452

my question is that where connect " D/C" pin in uc?
tnx
Jhonny



Joined: 30 Jan 2011
Posts: 16

View user's profile Send private message

PostPosted: Tue Jun 09, 2015 7:10 am     Reply with quote

Thank you for the source code! How can displayed with variable (or constant) to a value?
for example:
Code:
unsigned int16 value = 1234;
OLED_text (0,0, value, 2); // Here should be the solution ...

Embarassed
PCM programmer



Joined: 06 Sep 2003
Posts: 20100

View user's profile Send private message

PostPosted: Tue Jun 09, 2015 6:09 pm     Reply with quote

Use sprintf() to convert the int16 value to an ASCII string in a buffer.
Then give OLED_text() the address of the buffer.
PCM programmer



Joined: 06 Sep 2003
Posts: 20100

View user's profile Send private message

PostPosted: Tue Jun 09, 2015 6:14 pm     Reply with quote

amanver wrote:
my question is that where connect " D/C" pin in uc?

The answer is in the following line of code. The i2c data pin is pin C4, and
the clock is on pin C3.
Code:
#use i2c(Master,Fast=400000,sda=PIN_C4,scl=PIN_C3,force_sw)
Jhonny



Joined: 30 Jan 2011
Posts: 16

View user's profile Send private message

PostPosted: Wed Jun 10, 2015 6:35 am     Reply with quote

Dear PCM programmer!
Thank you very much! This is a good solution, it works! Very Happy
scanan



Joined: 13 Aug 2004
Posts: 57
Location: Turkey

View user's profile Send private message Visit poster's website

ssd1306 get it work
PostPosted: Mon Jun 15, 2015 4:20 pm     Reply with quote

I tried your driver.
I get it work on PIC18F6310 and CCS 4.135
but I've been able to use almost half the screen area because of the RAM limitation, good job.
_________________
Dr Suleyman CANAN
R&D Electronic Engineer
https://suleymancanan.wordpress.com

Do whatever you do with amateur spirit -
But always feel professional.


Last edited by scanan on Mon Jun 22, 2015 4:04 am; edited 1 time in total
TimC



Joined: 12 Nov 2005
Posts: 5

View user's profile Send private message

Init issues
PostPosted: Sat Jun 20, 2015 8:45 pm     Reply with quote

This driver is Great it really got me started.
I have 2 different 128x64 displays. Both around $4us on Ebay from China. One worked and the other did not.
Took a look at the OLED_init() procedure and it made no sense to me after looking at the (really terrible) spec sheet. I came up with a simpler OLED_init(). command2() is only different because it allows for 2 commands instead of one.

Code:

void SSD1306_init() {
   //OLED_command(0xAE);     //display off   reset default = 0xAE
   //OLED_command2(0xD5,0x80); // set osc division = Recommneded resistor ratio 0x80    reset value is good
   //OLED_command2(0xA8,0x3F); // Multiplex ratio 16-64Mux, (reset default = 128x64=0x3F)  128x32=0x1F
   //OLED_command2(0xD3,0x00); //set display offset  = 0         reset default = 0
   //OLED_command(0x40); //set start line = 0 or 0x40,   range= 0x40-0x7f  reset default = 0x40 or 0 
   OLED_command2(0x8D,0x14); //set charge pump disable=0x10, enable=0x14   reset default = 0x10  Causes alignment problem with big display  Needed for little display!!
   OLED_command2(0x20,0x00); //set Addressing Mode Horizontal like KS108=0x00,  or Page Mode = 0x10  reselt default = 0x10
   OLED_command(0xA1); //set segment remap SEG0 to start @ column 127.  reset default = 0xA0.  Causes mirror display if not sent
   OLED_command(0xC8); //Com scan direction. reset default = 0xC0.   Causes mirror display if not sent
   //OLED_command2(0xDA,0x12); //set alt COM pins left right remap.  reset default = 0x12   = 128x64=0x12   (128x32=0x02)
   //OLED_command2(0x81,0x7F); //contrast control  0x01 to 0xFF   resets default = 0x7F
   //OLED_command2(0xD9,0x1F); //set pre-charge periods for phase 1 and 2.  resets default = 0x22 or 2 periods for each phase.
   //OLED_command2(0xDB,0x40); //Adjusts regulator output VCOMH   reset default = 0x20
   //OLED_command(0xA4); // Set Display All On Resume. reset default = 0xA4  (turn on all pixels = A5. Regular mode A4)
   //OLED_command(0xA6); //Set Normal Display =0xA6, reset default = 0xA6  (colored background black letters or Inverted Display =0xA7)
   OLED_command(0xAF); //Turn Display On. If display does not show random pixels then hardware or software is NOT working
}


One of my displays needs the charge pump turned on the other does not. I guess it's due to added capacitors or hardware differences.

Anyway it would be interesting if others get the same results relying on the defaults.

Regards
Tim
mglsoft



Joined: 18 Feb 2008
Posts: 48

View user's profile Send private message

PostPosted: Thu Mar 03, 2016 3:53 pm     Reply with quote

Thanks !!
_________________
MGLSOFT
cbarberis



Joined: 01 Oct 2003
Posts: 132
Location: Punta Gorda, Florida USA

View user's profile Send private message Send e-mail

PmodOLED 128X32 module using SSD1306
PostPosted: Thu Oct 13, 2016 2:41 pm     Reply with quote

Hi,
I have been trying to use your code with a PmodOLED 128X32 module which uses the SSD1306 display controller, but I notice that there is a series of other signals required such as RESET, VBAT and VDD (which works separate to VCC) there is a start-up sequence of how these signals have to behave in order for this thing to work. I notice that your code does not address any of these and was wondering as to how you got this to work? Also wondering if anyone in this forum has ever used this commercially available module?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group