Andrew Hannay
Published © GPL3+

Pong Watch

A pong clock on your wrist

IntermediateFull instructions provided1,203
Pong Watch

Things used in this project

Hardware components

Monochrome OLED with I2C interface
×1
Microchip PIC 12F1840 8 pin
×1
Rechargeable Li-ion 052025 25mm x 20mm x 5mm
×1
TP4056 Lithium charger module
×1

Story

Read more

Code

pongwatch 2015-06-14.c

Plain text
/********************************************************/
/***                                                  ***/
/***                     12f1840                      ***/
/***                      _____                       ***/
/***                 Vdd [     ] GND                  ***/
/***      OLED SCK - RA5 [     ] RA0 - TL sw / PGD    ***/
/***      OLED SDA - RA4 [     ] RA1 - BL sw / PGD    ***/
/***          MCLR - RA3 [_____] RA2 - BR sw          ***/
/***                                                  ***/
/********************************************************/
// Source code for PongWatch written by Andrew M Hannay June 2015
// Compiled on MPLABX 

#include	<htc.h>

// PIC12F1840 Configuration Bit Settings
// 'C' source line config statements

#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

// Define CPU Frequency
#define _XTAL_FREQ   16000000      // Hz
#define FALSE	0
#define TRUE	!FALSE

// Define i2c pins
#define SDA			LATA4			// Data pin for i2c
#define SCK			LATA5			// Clock pin for i2c
#define SDA_DIR		TRISA4			// Data pin direction
#define SCK_DIR		TRISA5			// Clock pin direction

#define DataPinADCMask		ANS3	// It is attached on GP4(AN3) pin

// Define macros
#define Set_SDA_Low		SDA_DIR = 0
#define Set_SDA_High	SDA_DIR = 1
#define Set_SCK_Low		SCK_DIR = 0
#define Set_SCK_High	SCK_DIR = 1

#define OL_C	0x00
#define OL_D	0x40

#define OFFSET  0
#define SHORTD  10
#define GAMED   10
#define LONGD   30

#define TIMEMODE    0
#define TESTMODE    1
#define HRSADJUST   2
#define MINSADJUST  3

#define tp	0x0f	// 00001111
#define tm	0x3f	// 00111111
#define md	0x3c	// 00111100
#define bm	0xfc	// 11111100
#define bt	0xf0	// 11110000
#define fl	0xff	// 11111111
#define nn	0x00	// 00000000
static const unsigned char BIG[][9] =
{
 {fl,tp,fl,fl,nn,fl,fl,bt,fl}	// 0
,{nn,fl,nn,nn,fl,nn,nn,fl,nn}	// 1
,{tp,tp,fl,bm,md,tm,fl,bt,bt}	// 2
,{tp,tp,fl,md,md,fl,bt,bt,fl}	// 3
,{fl,nn,fl,tm,md,fl,nn,nn,fl}	// 4
,{fl,tp,tp,tm,md,bm,bt,bt,fl}	// 5
,{fl,tp,tp,fl,md,bm,fl,bt,fl}	// 6
,{tp,tp,fl,nn,nn,fl,nn,nn,fl}	// 7
,{fl,tp,fl,fl,md,fl,fl,bt,fl}	// 8
,{fl,tp,fl,tm,md,fl,bt,bt,fl}	// 9
};
static const unsigned char COLON[][10] =
{
 {nn,nn,nn,bt,bt,bt,bt,nn,nn,nn}
,{nn,nn,nn,nn,nn,nn,nn,nn,nn,nn}
,{nn,nn,nn,tp,tp,tp,tp,nn,nn,nn}
,{nn,nn,nn,bt,bt,bt,bt,nn,nn,nn}
,{nn,nn,nn,nn,nn,nn,nn,nn,nn,nn}
,{nn,nn,nn,tp,tp,tp,tp,nn,nn,nn}
,{nn,nn,nn,bt,bt,bt,bt,nn,nn,nn}
,{nn,nn,nn,nn,nn,nn,nn,nn,nn,nn}
};

//Function Declarations
void DrawScore(unsigned char score1, unsigned char score2);
void ReDrawline(unsigned char line, unsigned char score1, unsigned char score2);
void Drawline(unsigned char line, unsigned char score1, unsigned char score2);
void DrawNet(void);
void DrawBall(unsigned char draw, unsigned char xcoord, unsigned char ycoord);
void DrawBat1(unsigned char draw, unsigned char ycoord, signed char dir);
void DrawBat2(unsigned char draw, unsigned char ycoord, signed char dir);
void OLFill(unsigned char data);
void i2c_write(unsigned char* i2c_data, int DataSz);
void OLWriteByte(unsigned char dc, unsigned char data);
void OLWriteData(unsigned char data, unsigned char length);
void OLInitialise(void);
void InitI2C(void);
void I2C_Start(void);
void I2C_Stop(void);
void I2C_Write_Byte(unsigned char);


/* Pin configuration
 * 
 * PORTA4 = SDA pin for i2c
 * PORTA5 = SCK pin for i2c
 */

unsigned char counter;
unsigned char tick;
unsigned char watchmode;
    
main()
{
	signed char ballx;
	signed char bally;
	signed char dirx;
	signed char diry;
    signed char bat1;
    signed char bat2;
    signed char bat1dir;
    signed char bat2dir;
    
    unsigned char miss;

    unsigned char count1sec;
    unsigned char hours;
    unsigned char minutes;
    unsigned char seconds;
    
    unsigned char Score1;
    unsigned char Score2;

    unsigned char RA0count;
    unsigned char RA1count;
    unsigned char RA2count;
    
    bat1 = 3;
    bat2 = 3;
    bat1dir = 0;
    bat2dir = 0;
    
	ballx = 0;
	bally = 0;
	dirx = 0;
	diry = 0;

    miss = TRUE;
    
    hours = 19;
    minutes = 17;
    seconds = 0;
    count1sec = 0;
    
    RA0count = 0;
    RA1count = 0;
    RA2count = 0;

    watchmode = TIMEMODE;
            
	CLRWDT();		//clear watchdog
	__delay_ms(100);

    //OSCCON = 0x6a;    //01101010      4MHz
    //OSCCON = 0x72;    //01110010      8MHz
    OSCCON = 0x7a;    //01111010      16MHz
    //OSCCON = 0xf0;      //11110000      32MHz
    
    //APFCON = 0x00;  //Alternate Pin Config Register
    //FVRCON = 0x00;  //00000000
    //SSP1CON1 = 0x00;
    //PSTR1CON = 0x00;
    //ADCON0 = 0x00;  //00000000
    OPTION_REG = 0x0f;
    ANSELA = 0x00;  //00000000
    WPUA = 0x0f;
    TRISA = 0x3f;	//00111111
    LATA = 0x00;	//00000000

    //TMR0IE = 1;     // Enable interrupt on TMR0 overflow
    T2CON = 0x4f;     //01001111
    TMR2 = 0;
    PR2 = 124;        //20ms interrupt
    TMR2IE = 1;
	GIE = 1;		// Global interrupt enable
    PEIE = 1;       //peripheral interrupt enable

	InitI2C();
	__delay_ms(100);
	OLInitialise();
	__delay_ms(100);
	OLFill(0x00);
	
	DrawBat1(0xff,bat1,0);
	DrawBat2(0xff,bat2,0);
    Score1 = hours;
    Score2 = minutes;
    DrawScore(Score1, Score2);
    DrawNet();
    while(1)
    {
	    if(tick == TRUE)
	    {
		    tick = FALSE;
            if (watchmode < HRSADJUST)
            {   //Update Clock
                count1sec++;
                if (count1sec == 10)    //1 second
                {
                    count1sec = 0;
                    seconds++;
                    if (watchmode == TIMEMODE)
                    {
                        if (seconds == 1)
                        {
                            miss = FALSE;
                            if (minutes == 59)
                            {
                                ballx = 0;
                                bally = bat1;
                                dirx = 1;
                                diry = 1;
                            }
                            else
                            {
                                ballx = 15;
                                bally = bat2;
                                dirx = -1;
                                diry = 1;
                            }
                        }
                        if (seconds == 59)
                        {
                            miss = TRUE;
                        }
                    }
                    if (seconds == 60)    //1 minute
                    {
                        seconds = 0;
                        minutes++;
                        if (minutes == 60)  //1 hour
                        {
                            minutes = 0;
                            hours++;
                            if (hours == 24)    //1 day (24 hours)
                            {
                                hours = 0;
                            }
                        }
                        if (watchmode == TIMEMODE)
                        {
                            Score1 = hours;
                            Score2 = minutes;
                            DrawScore(Score1, Score2);
                        }
                    }
                }
            }
            else
            {
                count1sec = 0;
                seconds = 0;
            }
            //Read switches
            if (RA0 == 1) RA0count = 0;
            if (RA1 == 1) RA1count = 0;
            if (RA2 == 1) RA2count = 0;
            if ((RA0count < 128) && (RA0 == 0)) RA0count++;
            if ((RA1count < 128) && (RA1 == 0)) RA1count++;
            if ((RA2count < 128) && (RA2 == 0)) RA2count++;
            bat1dir = 0;
            bat2dir = 0;

            if ((RA0count == 1) || (RA0count == SHORTD))
            {
                if (watchmode == HRSADJUST)
                {
                    hours++;
                    if (hours == 24) hours = 0;
                    Score1 = hours;
                    DrawScore(Score1, Score2);
                }
                else if (watchmode == MINSADJUST)
                {
                    minutes++;
                    if (minutes == 60) minutes = 0;
                    Score2 = minutes;
                    DrawScore(Score1, Score2);
                }
                if (RA0count == SHORTD) RA0count = SHORTD-1;
            }
            if ((RA1count == 1) || (RA1count == SHORTD))
            {
                if (watchmode == HRSADJUST)
                {
                    hours--;
                    if (hours == 0xff) hours = 23;
                    Score1 = hours;
                    DrawScore(Score1, Score2);
                }
                else if (watchmode == MINSADJUST)
                {
                    minutes--;
                    if (minutes == 0xff) minutes = 59;
                    Score2 = minutes;
                    DrawScore(Score1, Score2);
                }
                if (RA1count == SHORTD) RA1count = SHORTD-1;
            }
            if (RA2count == 1)
            {
				if (watchmode == HRSADJUST)
					watchmode = MINSADJUST;     //adjust minutes
				else
					watchmode = TIMEMODE;       //time adjust off
				Score1 = hours;
				Score2 = minutes;
				DrawScore(Score1, Score2);
				RA2count = 128;
            }
            if (RA2count == LONGD)
            {
                if (watchmode < HRSADJUST)
                    watchmode = HRSADJUST;         //adjust hours
                Score1 = hours;
                Score2 = minutes;
                DrawScore(Score1, Score2);
                miss = TRUE;
                RA2count = 128;
            }
            
            DrawBall(0x00,ballx*8,bally);//remove old ball
			if ((bally < 3) && ((ballx > 2) && (ballx < 13)))
                ReDrawline(bally, Score1, Score2);
            else if ((bally > 2) && ((ballx > 6) && (ballx < 9)))
                DrawNet();
			ballx = ballx + dirx;
			bally = bally + diry;
            if (dirx != 0) DrawBall(0xff,ballx*8,bally);//draw new ball
    
            if (watchmode == TIMEMODE)
            {
                if ((ballx < 8) && (dirx < 0))
                {
                    if (miss == FALSE)
                    {
                        if ((bat1 < bally) && (bat1 < 6)) bat1dir = 1;
                        else if ((bat1 > bally) && (bat1 > 1)) bat1dir = -1;
                    }
                    else if (bat1 < 6) bat1dir = 1;
                }
                else
                {
                    if (bat1 < 3) bat1dir = 1;
                    else if (bat1 > 4) bat1dir = -1;
                }
            }
            bat1 = bat1 + bat1dir;
            DrawBat1(0xff,bat1,bat1dir);
            
            if ((ballx > 7) && (dirx > 0))
            {
                if (miss == FALSE)
                {
                    if ((bat2 < bally) && (bat2 < 6)) bat2dir = 1;
                    else if ((bat2 > bally) && (bat2 > 1)) bat2dir = -1;
                }
                else if (bat2 < 6) bat2dir = 1;
            }
            else
            {
                if (bat2 < 3) bat2dir = 1;
                else if (bat2 > 4) bat2dir = -1;
            }
            bat2 = bat2 + bat2dir;
            DrawBat2(0xff,bat2,bat2dir);

            if (bally == 0) diry = 1;
            if (bally == 7) diry = -1;
            if (miss == FALSE)
            {
                if (ballx == 1) dirx = 1;	    
                if (ballx == 14) dirx = -1;	    
            }
            else
            {
                if((ballx == 0) || (ballx == 15))
                {
                    dirx = 0;
                    diry = 0;
                }
            }
		    //LATA2 = ~LATA2;
		} 
    }
}

static void interrupt isr(void)   //20ms interrupt
{
    //LATA1 = ~LATA1;
	if (++counter >= 5)		//20ms x 5 = 100ms
	{
        //LATA0 = ~LATA0;
		counter = 0;
		tick = TRUE;
	}
    TMR2IF = 0;
}

#define SIZE    5   //0x05
void DrawScore(unsigned char score1, unsigned char score2)
{
    unsigned char line;
    
    for (line = 0; line < 3; line++)
    {
        OLWriteByte(OL_C, 0x08 + OFFSET);    //24 = 0x18 0x08 0x11
        OLWriteByte(OL_C, 0x11);
        OLWriteByte(OL_C, line | 0xb0);
        I2C_Start();				//Send the Start Bit
        I2C_Write_Byte(0x78);		//write address and write
        I2C_Write_Byte(0x40);		//write data flag
        Drawline(line, score1, score2);
        I2C_Stop();//Send the Stop condition
    }
}

void ReDrawline(unsigned char line, unsigned char score1, unsigned char score2)
{
    OLWriteByte(OL_C, 0x08 + OFFSET);    //24 = 0x18 0x08 0x11
    OLWriteByte(OL_C, 0x11);
    OLWriteByte(OL_C, line | 0xb0);
    
	I2C_Start();				//Send the Start Bit
	I2C_Write_Byte(0x78);		//write address and write
	I2C_Write_Byte(0x40);		//write data flag
    Drawline(line, score1, score2);
	I2C_Stop();//Send the Stop condition
}

void Drawline(unsigned char line, unsigned char score1, unsigned char score2)
{
	unsigned char index;
	unsigned char sizec;
    unsigned char number;
    unsigned char mask;
    unsigned char num[4];

    num[0] = score1/10;
    num[1] = score1%10;
    num[2] = score2/10;
    num[3] = score2%10;
    
    for (number = 0; number < 4; number++)
    {
        mask = 0xff;    //mask for time adjust indicator
        if (((watchmode == MINSADJUST) && (number < 2)) || ((watchmode == HRSADJUST) && (number > 1))) mask = 0x55; 
        for(index = 0; index < 3; index++)
        {
            for (sizec = 0; sizec < SIZE; sizec++)
            {
                I2C_Write_Byte((BIG[num[number]][index + line*3]) & mask);
            }
        }
        if ((number == 0) || (number == 2)) //small gap
        {
            for (sizec = 0; sizec < 5; sizec++)
            {   
                I2C_Write_Byte(0);
            }
        }
        else if (number == 1)               //large gap
        {
            for (sizec = 0; sizec < 10; sizec++)
            {   
                I2C_Write_Byte(COLON[line][sizec]);
            }
        }
    }
}

#define NETX 62 + OFFSET
void DrawNet(void)
{
    OLWriteByte(OL_C, NETX & 0x0f);
    OLWriteByte(OL_C, (NETX >> 4) | 0x10);
    OLWriteByte(OL_C, 0xb3);
    OLWriteData(bt, 4);
    OLWriteByte(OL_C, NETX & 0x0f);
    OLWriteByte(OL_C, (NETX >> 4) | 0x10);
    OLWriteByte(OL_C, 0xb5);
    OLWriteData(tp, 4);
    OLWriteByte(OL_C, NETX & 0x0f);
    OLWriteByte(OL_C, (NETX >> 4) | 0x10);
    OLWriteByte(OL_C, 0xb6);
    OLWriteData(bt, 4);
}

void DrawBall(unsigned char draw, unsigned char xcoord, unsigned char ycoord)
{
    xcoord = xcoord  + OFFSET;
    OLWriteByte(OL_C, xcoord & 0x0f);
    OLWriteByte(OL_C, (xcoord >> 4) | 0x10);
    OLWriteByte(OL_C, ycoord | 0xb0);
    OLWriteData(draw, 8);
}
	
void DrawBat1(unsigned char draw, unsigned char ycoord, signed char dir)
{
    if (dir < 0)
    {
        OLWriteByte(OL_C, 0x00 + OFFSET);
        OLWriteByte(OL_C, 0x10);
        OLWriteByte(OL_C, ycoord-1 | 0xb0);
        OLWriteData(draw, 8);
        OLWriteByte(OL_C, 0x00 + OFFSET);
        OLWriteByte(OL_C, 0x10);
        OLWriteByte(OL_C, ycoord+2 | 0xb0);
        OLWriteData(0, 8);
    }
    else if (dir > 0)
    {
        OLWriteByte(OL_C, 0x00 + OFFSET);
        OLWriteByte(OL_C, 0x10);
        OLWriteByte(OL_C, ycoord+1 | 0xb0);
        OLWriteData(draw, 8);
        OLWriteByte(OL_C, 0x00 + OFFSET);
        OLWriteByte(OL_C, 0x10);
        OLWriteByte(OL_C, ycoord-2 | 0xb0);
        OLWriteData(0, 8);
    }
    else
    {
        OLWriteByte(OL_C, 0x00 + OFFSET);
        OLWriteByte(OL_C, 0x10);
        OLWriteByte(OL_C, ycoord-1 | 0xb0);
        OLWriteData(draw, 8);
        OLWriteByte(OL_C, 0x00 + OFFSET);
        OLWriteByte(OL_C, 0x10);
        OLWriteByte(OL_C, ycoord | 0xb0);
        OLWriteData(draw, 8);
        OLWriteByte(OL_C, 0x00 + OFFSET);
        OLWriteByte(OL_C, 0x10);
        OLWriteByte(OL_C, ycoord+1 | 0xb0);
        OLWriteData(draw, 8);
    }
}	
	
void DrawBat2(unsigned char draw, unsigned char ycoord, signed char dir)
{
    if (dir < 0)
    {
        OLWriteByte(OL_C, 0x08 + OFFSET);
        OLWriteByte(OL_C, 0x17);
        OLWriteByte(OL_C, ycoord-1 | 0xb0);
        OLWriteData(draw, 8);
        OLWriteByte(OL_C, 0x08 + OFFSET);
        OLWriteByte(OL_C, 0x17);
        OLWriteByte(OL_C, ycoord+2 | 0xb0);
        OLWriteData(0, 8);
    }
    else if (dir > 0)
    {
        OLWriteByte(OL_C, 0x08 + OFFSET);
        OLWriteByte(OL_C, 0x17);
        OLWriteByte(OL_C, ycoord+1 | 0xb0);
        OLWriteData(draw, 8);
        OLWriteByte(OL_C, 0x08 + OFFSET);
        OLWriteByte(OL_C, 0x17);
        OLWriteByte(OL_C, ycoord-2 | 0xb0);
        OLWriteData(0, 8);
    }
    else
    {
        OLWriteByte(OL_C, 0x08 + OFFSET);
        OLWriteByte(OL_C, 0x17);
        OLWriteByte(OL_C, ycoord-1 | 0xb0);
        OLWriteData(draw, 8);
        OLWriteByte(OL_C, 0x08 + OFFSET);
        OLWriteByte(OL_C, 0x17);
        OLWriteByte(OL_C, ycoord | 0xb0);
        OLWriteData(draw, 8);
        OLWriteByte(OL_C, 0x08 + OFFSET);
        OLWriteByte(OL_C, 0x17);
        OLWriteByte(OL_C, ycoord+1 | 0xb0);
        OLWriteData(draw, 8);
    }
}	
	
void OLFill(unsigned char data)
{
	unsigned char col;
    unsigned char line;
    
    for (line = 0; line < 8; line++)
    {
        OLWriteByte(OL_C, line | 0xb0);
        OLWriteByte(OL_C, 0x00);
        OLWriteByte(OL_C, 0x10);
        
        I2C_Start();				//Send the Start Bit
        I2C_Write_Byte(0x78);		//write address and write
        I2C_Write_Byte(0x40);		//write data flag

        for(col=0;col<128 + OFFSET + OFFSET;col++)
        {
            I2C_Write_Byte(data);
        }
        I2C_Stop();//Send the Stop condition
    }
}

void i2c_write(unsigned char* i2c_data, int DataSz)
{
	I2C_Start();//Send the Start Bit
	while( DataSz )
	{
		I2C_Write_Byte(*i2c_data++);
		DataSz--;
	}
	I2C_Stop();//Send the Stop condition
}

void OLWriteByte(unsigned char dc, unsigned char data)
{
	//write = 0, read = 1
	char i2cData[3];
	
	i2cData[0] = 0x78;	//slave address of display, write
	i2cData[1] = 0x80 | dc;
	i2cData[2] = data;
	
	i2c_write(i2cData, 3);
}	

void OLWriteData(unsigned char data, unsigned char length)
{
	unsigned char n;
	I2C_Start();				//Send the Start Bit
	I2C_Write_Byte(0x78);		//write address and write
	I2C_Write_Byte(0x40);		//write data flag

	for(n=0;n<length;n++)
	{
		I2C_Write_Byte(data);
	}
	I2C_Stop();//Send the Stop condition
}

void OLInitialise(void)
{
	//command = 0, data =1

	OLWriteByte(OL_C,0xaf);	//display on
	//OLWriteByte(OL_C,0xae);	//display off
	OLWriteByte(OL_C,0xa8);	// set multiplex ratio
	OLWriteByte(OL_C,0x3f);	// multiplex ratio = 64MUX
	//OLWriteByte(OL_C,0xd3);	// set display offset
	//OLWriteByte(OL_C,0x00);	// display offset = 0 (no vertical shift)
	OLWriteByte(OL_C,0x40);	// set display start line to 0
	OLWriteByte(OL_C,0xa1);	// set segment re-map to invert horizontally
	OLWriteByte(OL_C,0xc8);	// set COM scan direction to invert vertically
	OLWriteByte(OL_C,0xda);	// set COM pins hardware configuration
	OLWriteByte(OL_C,0x12);	// COM pins hardware configuration = alternative, no left/right remap
	OLWriteByte(OL_C,0x81);	// set contrast
	OLWriteByte(OL_C,0xbf);	// contrast = 75%
	OLWriteByte(OL_C,0xa4);	// disable entire display on
	OLWriteByte(OL_C,0xa6);	// set normal display
    OLWriteByte(OL_C,0xb0); // set page address
	OLWriteByte(OL_C,0xd5);	// set oscillator frequency
	OLWriteByte(OL_C,0x80);	// oscillator frequency = default
	OLWriteByte(OL_C,0x8d);	// set charge pump
	OLWriteByte(OL_C,0x14);	// charge pump = on
	//OLWriteByte(OL_C,0x20);	// set memory addressing mode
	//OLWriteByte(OL_C,0x00);	// memory addressing mode page
	//OLWriteByte(OL_C,0x21);	// Column address (Set up 128x64) display
	//OLWriteByte(OL_C,0x00);	// Column start
	//OLWriteByte(OL_C,0x7f);	// Column end
	//OLWriteByte(OL_C,0x22);	// Row address
	//OLWriteByte(OL_C,0x00);	// Row start
	//OLWriteByte(OL_C,0x07);	// Row end
	//OLWriteByte(OL_C,0x20);	// set memory addressing mode
	//OLWriteByte(OL_C,0x02);	// memory addressing mode page
}

// Function Purpose: Set initial values of SCK and SDA pins
void InitI2C(void)
{	
	//DataPinADCMask  = 1;	// Make analog output
	// Make SDA and SCK pins input initially
	SDA_DIR = 1;
	SCK_DIR = 1;
	// Write zero in output register of SDA and SCK pin
	SDA = 0;
	SCK = 0;
}


// Function Purpose: I2C_Start sends start bit sequence
void I2C_Start(void)
{
	SDA = 0;	// Write zero in output register 
	SCK = 0;	// of SDA and SCK pin
	Set_SCK_High;				// Make SCK pin high
	Set_SDA_High;				// Make SDA pin High
	Set_SDA_Low;				// Make SDA Low
}

//Function : I2C_Stop sends stop bit sequence
void I2C_Stop(void)
{
	Set_SCK_Low;				// Make SCK pin low
	Set_SDA_Low;				// Make SDA pin low
	Set_SCK_High;				// Make SCK pin high
	Set_SDA_High;				// Make SDA high
}

// Function Purpose: I2C_Write_Byte transfers one byte
void I2C_Write_Byte(unsigned char Byte)
{
	static bit ACK = 0;

	unsigned char i;		// Variable to be used in for loop
	
	for(i=0;i<8;i++)		// Repeat for every bit
	{
		Set_SCK_Low;		// Make SCK pin low
		if((Byte<<i)&0x80)  // Place data bit value on SDA pin
			Set_SDA_High;	// If bit is high, make SDA high
		else				// Data is transferred MSB first
			Set_SDA_Low;	// If bit is low, make SDA low
		Set_SCK_High;				// So that slave can
    }
		
	// Get ACK from slave
	Set_SCK_Low;
    Set_SDA_High;
    Set_SCK_High;
}

Credits

Andrew Hannay

Andrew Hannay

1 project • 0 followers
Electronics and Embedded software design Engineer

Comments