Zápis a čítanie pamäte sa realizuje cez paralelný port s použitím I2C protokolu, ktorý je podrobnejšie popísaný nižšie na obrázku. Z paralelného portu sa využívajú nasledovné piny:
SDA (serial data line) – LPT pin 5 (DATA 3)
SCL (serial clock) – LPT pin 3 (DATA 1)
Pri zápise je potrebné nastaviť aj /WC (write control, write protect), ktorý slúži na ochranu pred nežiadúcim prepísaním údajov pamäte.
/WC – LPT pin 14 (CONTROL 1 – Auto Line Feed, hardvérovo invertovaný).
Na riadenie paralelného portu sa v zdrojovom kode využíva (volá) knižnica "inpout32.dll". LPT obsahuje tri registre DATA, STATUS, CONTROL. Port sa inicializuje s adresou 0x378h (base address), co je adresa dátového registra, ostatné registre sa potom inicializujú ako base adrress + 1 (status) a base address + 2 (control). Register DATA je štandardne nastavený ako výstupný (čize je možný iba zápis). Pre čitanie z registra je nutné nastaviť pin Enable Bi-Directional Port (CONTROL 5). Konkretnejší popis LPT pinov je uvedený na obrázku nižšie.
I2C protokol
Zápis bytov do M24C02

Čítanie bytov z M24C02
Paralelný port
Zdrojový kód:
using System;
using System.Threading;
namespace I2C
{
class I2CInterface
{
private int delay;
private int PB;
private int PC;
private int lptPort = 0x00;
public int DELAY_1ms
{
get
{
return delay;
}
set
{
delay = value;
}
}
public I2CInterface(int lptPort)
{
this.PB = ParallelPort.Input(lptPort);
this.PC = ParallelPort.Input(lptPort + 2);
this.PB |= 0x0A;
this.PC &= 0xDD;
this.lptPort = lptPort;
ParallelPort.Output(lptPort, this.PB);
ParallelPort.Output(lptPort + 2, this.PC);
}
public void SDAOut(bool value)
{
if (value == true)
{
this.PB |= 0x08;
}
else
{
this.PB &= 0xF7;
}
ParallelPort.Output(this.lptPort, this.PB);
}
public void WriteProtect(bool value)
{
if (value == true)
{
this.PC &= 0xFD;
}
else
{
this.PC |= 0x02;
}
ParallelPort.Output(this.lptPort + 2, this.PC);
}
public bool SDAIn()
{
this.PC |= 0x20;
ParallelPort.Output(this.lptPort + 2, this.PC);
int data = ParallelPort.Input(this.lptPort);
this.PC &= 0xDF;
ParallelPort.Output(this.lptPort + 2, this.PC);
return !((data & 0x08) == 0x08);
}
public void SCLOut(bool value)
{
if (value == true)
{
this.PB |= 0x02;
}
else
{
this.PB &= 0xFD;
}
ParallelPort.Output(this.lptPort, this.PB);
}
public void StartBit()
{
SDAOut(true);
SCLOut(true);
Thread.Sleep(delay);
SDAOut(false);
Thread.Sleep(delay);
SCLOut(false);
Thread.Sleep(delay);
}
public void StopBit()
{
SDAOut(false);
SCLOut(true);
Thread.Sleep(delay);
SDAOut(true);
Thread.Sleep(delay);
}
public void SendBit(bool value)
{
SDAOut(value);
Thread.Sleep(delay);
SCLOut(true);
Thread.Sleep(delay);
SCLOut(false);
Thread.Sleep(delay);
}
public bool ReadBit()
{
SDAOut(true);
Thread.Sleep(delay);
SCLOut(true);
Thread.Sleep(delay);
bool value = SDAIn();
SCLOut(false);
Thread.Sleep(delay);
return value;
}
public bool Ack()
{
SDAOut(true);
Thread.Sleep(delay);
SCLOut(true);
Thread.Sleep(delay);
bool value = SDAIn();
SCLOut(false);
Thread.Sleep(delay);
return value;
}
public void NonAck()
{
SDAOut(true);
Thread.Sleep(delay);
SCLOut(true);
Thread.Sleep(delay);
SCLOut(false);
Thread.Sleep(delay);
}
public void SendByte(int value, int bits, bool getAck, out bool ackValue)
{
for (int i = (int)Math.Pow(2, bits - 1); i > 0; i /= 2)
{
SendBit(((i & value) == i) ? true : false);
}
if (getAck == true)
{
ackValue = Ack();
}
else
{
ackValue = false;
NonAck();
}
}
public int ReadByte(int bits, bool ack)
{
int value = 0;
for (int i = 0; i < bits; i++)
{
value *= 2;
value += (ReadBit() == true) ? 0 : 1;
}
SendBit(!ack);
return value;
}
}
}
//Pridanie "inpout32.dll"
using System.Runtime.InteropServices;
namespace I2C
{
class ParallelPort
{
[DllImport("inpout32.dll", EntryPoint = "Out32")]
public static extern void Output(int address, int value);
[DllImport("inpout32.dll", EntryPoint = "Inp32")]
public static extern int Input(int address);
}
}







