pic16f690 code
/*
* File: main.c
* Author: root
* Random numbers based on self blinking LEDS and comparators
* Created on 13 dec, 2023, 10:23 AM
* oled i2c
*/
// CONFIG
#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator:
// I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-Up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF // MCLR pin is digital I/O, MCLR internally tied to
// VDD)
#pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF // Code Protection bit (Program Memory code
// protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code
// protection is disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <htc.h>
#include "oled_font.c"
#define _XTAL_FREQ 4000000
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#define SCL RA0 // clock
#define SDA RA1 // data
//prototypes
void command( unsigned char comm);
void oled_init(void);
void clrScreen(void);
void sendData(unsigned char dataB);
void startBit(void);
void stopBit(void);
void clock(void);
void drawChar2(char fig, unsigned char y, unsigned char x);
unsigned char addr=0x78; //0b0111 1000
unsigned char num, digit_2,digit_3;
void main(void) {
ANSEL = 0x00; //disable all analog ports
ANSELH = 0x00;
CM1CON0 = 0x07; // comparator off
TRISA = 0x00; // all outputs
TRISC = 0xFF; // all inputs
PORTC = 0x00; // all low
//----------------------------------------------------
PORTAbits.RA0 = 1;
PORTAbits.RA1 = 1;
__delay_ms(200);
oled_init();
__delay_ms(200);
clrScreen(); // clear screen
while (1) {
drawChar2(11, 1, 3); //space
drawChar2(11, 1, 4);
drawChar2(11, 1, 5);
num = PORTC;
digit_2 = (num / 10) % 10; // 207 10 11 12 99 100
digit_3 = num % 10;
if (num > 199) { // 200-255
drawChar2(2, 1, 3);
drawChar2(digit_2, 1, 4);
} else if (num > 99) { // 100 -199
drawChar2(1, 1, 3);
drawChar2(digit_2, 1, 4);
} else if (num > 9) { // 10-99
drawChar2(digit_2, 1, 4);
}
drawChar2(digit_3, 1, 5);
__delay_ms(1800);
num = 0;
} //while
}
//size 2 chars
void drawChar2(char fig, unsigned char y, unsigned char x)
{
unsigned char i, line, btm, top; //
command(0x20); // vert mode
command(0x01);
command(0x21); //col addr
command(13 * x); //col start
command(13 * x + 9); //col end
command(0x22); //0x22
command(y); // Page start
command(y+1); // Page end
startBit();
sendData(addr); // address
sendData(0x40);
for (i = 0; i < 5; i++){
line=font[5*(fig)+i]; // font [5 x 5 + i] = 0x27, 0x45, 0x45, 0x45, 0x39
btm=0; top=0;
// 128x32 OLED has 4 pages (0-3) starting in column 0 and ending in column 127
// top = top page (page1 y) of 5 columns wide and 8 rows deep
// btm = bottom page (page2 y+1) of 5 columns wide and 8 rows deep
// when 1 byte is written the pointer moves to the next column automatically
// the 4 bits on the left determine the top page column
// the 4 bits on the right determine the bottom page column
// 0x93 means top page from top downwards white,white,white,black and bottom
//page white,black,black,white
if(line & 8) {top +=192;} //
if(line & 4) {top +=48;} //
if(line & 2) {top +=12;} //
if(line & 1) {top +=3;} //
if(line & 128) {btm +=192;} //
if(line & 64) {btm +=48;} //
if(line & 32) {btm +=12;} //
if(line & 16) {btm +=3;} //
/* original code
// expend char
if(line & 64) {btm +=192;} // line & 0100 bottom + 192
if(line & 32) {btm +=48;} // line & 0010 bottom + 48 -> 48
if(line & 16) {btm +=12;} // line & 0001 bottom + 12
if(line & 8) {btm +=3;} // line & 1000 bottom + 3
if(line & 4) {top +=192;} // line & 0100 top + 192 -> 252
if(line & 2) {top +=48;} // line & 0010 top + 48
if(line & 1) {top +=12;} // line & 0001 top + 12
*/
sendData(top); //top page (page 1)
sendData(btm); // page below top (page 2)
sendData(top); // top page, but next column
sendData(btm); // bottom page, but next column
// this means 1 byte for 2 columns in 2 pages (16 bits)
}
stopBit();
command(0x20); // horizontal mode
command(0x00);
}
void clrScreen() //fill screen with 0
{
unsigned char y, i;
for ( y = 0; y < 8; y++ ) {
command(0x21); //col addr
command(0); //col start
command(127); //col end
command(0x22); //0x22
command(y); // Page start
command(y+1); // Page end
startBit();
sendData(addr); // address
sendData(0x40);
for (i = 0; i < 128; i++){
sendData(0x00);
}
stopBit();
}
}
//Software I2C
void sendData(unsigned char dataB)
{
for(unsigned char b=0;b<8;b++){
SDA=(dataB >> (7-b)) % 2;
clock();
}
TRISAbits.TRISA1 = 1; //SDA input
clock();
__delay_us(5);
TRISAbits.TRISA1 =0; //SDA output
}
void clock(void)
{
__delay_us(1);
SCL=1;
__delay_us(5);
SCL=0;
__delay_us(1);
}
void startBit(void)
{
SDA=0;
__delay_us(5);
SCL=0;
}
void stopBit(void)
{
SCL=1;
__delay_us(5);
SDA=1;
}
void command( unsigned char comm){
startBit();
sendData(addr); // address
sendData(0x00);
sendData(comm); // command code
stopBit();
}
void oled_init() {
command(0xAE); // DISPLAYOFF
command(0x8D); // CHARGEPUMP *
command(0x14); //0x14-pump on
command(0x20); // MEMORYMODE
command(0x0); //0x0=horizontal, 0x01=vertical, 0x02=page
command(0xA1); //SEGREMAP * A0/A1=top/bottom
command(0xC8); //COMSCANDEC * C0/C8=left/right
command(0xDA); // SETCOMPINS *
command(0x22); //0x22=4rows, 0x12=8rows
command(0x81); // SETCONTRAST
command(0xFF); //0x8F
//next settings are set by default
// command(0xD5); //SETDISPLAYCLOCKDIV
// command(0x80);
// command(0xA8); // SETMULTIPLEX
// command(0x3F); //0x1F
// command(0xD3); // SETDISPLAYOFFSET
// command(0x0);
// command(0x40); // SETSTARTLINE
// command(0xD9); // SETPRECHARGE
// command(0xF1);
// command(0xDB); // SETVCOMDETECT
// command(0x40);
// command(0xA4); // DISPLAYALLON_RESUME
// command(0xA6); // NORMALDISPLAY
command(0xAF); //DISPLAYON
}
-----------------------------------------------
File "oled_font.c"
static const unsigned char font[] = {
0x7E,0xC1,0x81,0x83,0x7E, // zero
0x82,0x83,0xFF,0x80,0x80, // one
0xC2,0xA1,0x91,0x89,0x86, // two
0x42,0x81,0x89,0x89,0x7E, // three
0x18,0x14,0x92,0xFF,0x90, // four
0xC7,0x89,0x89,0x99,0x70, // five
0xFE,0x91,0x91,0x91,0xF0, // six
0x01,0xE1,0x19,0x05,0x03, // seven
0x76,0x99,0x99,0x99,0x76, // eight
0x1E,0x91,0x91,0x91,0xFE, // nine
0x0C,0x30,0xC0,0x30,0x0C, // v
0x00, 0x00, 0x00, 0x00, 0x00, // space
0x00,0xC0,0xC0,0xC0,0x00 // dot
};