štvrtok, 24 máj 2012 09:42 Written by 5387 times
Rate this item
(4 votes)

C# - Zápis a čítanie EEPROM M24C02

Zápis a čítanie EEPROM M24C02 cez paralelný port s použitím I2C protokolu.

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

i2c 1

Zápis bytov do M24C02

i2c 2

 

Čítanie bytov z M24C02

i2c 3

 

Paralelný port

 i2c 4

 

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);
    }
}
Last modified on pondelok, 19 december 2016 21:25
Ing.Peter Šuba

Zakladateľ www.projectik.eu

It's time for another revolution

(Why so serious?)

Website: www.projectik.eu