简体   繁体   中英

Interface M24512 EEPROM with Raspberry Pi on I2C: converting Python to C++

I have to intergace M24512 EEPROM IC with Raspberry pi on I2C bus.. It shows i2cdetect -y 1 at address 0x50

I got it working on python-smbus:

import smbus
import time
bus=smbus.SMBus(1)
bus.write_i2c_block_data(0x50, 0x00, [0x00, 50, 51, 52, 53, 54])
time.sleep(0.5)
bus.write_i2c_block_data(0x50, 0x00, [0x00])
time.sleep(0.5)
print bus.read_byte(0x50)
time.sleep(0.5)
print bus.read_byte(0x50)
time.sleep(0.5)
print bus.read_byte(0x50)
time.sleep(0.5)
print bus.read_byte(0x50)
time.sleep(0.5)
print bus.read_byte(0x50)
time.sleep(0.5)
print bus.read_byte(0x50)
time.sleep(0.5)
print bus.read_byte(0x50)
time.sleep(0.5)

Shows Output

50
51
52
53
54
255
255

It is perfect. But now I want to convert it to C++ using WiringPi lib.

#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
int temp=0;
int a=0;
wiringPiSetup();
int fd = wiringPiI2CSetup(0x50);
cout << "file descriptor " << fd << endl ;
wiringPiI2CWriteReg8(fd, 0x00, 0x00);
delayMicroseconds(500000);
cout << wiringPiI2CWrite(fd, 100);
delayMicroseconds(500000);
wiringPiI2CWriteReg8(fd, 0x00, 0x00);
delayMicroseconds(500000);
a=wiringPiI2CRead(fd);
delayMicroseconds(500000);
cout<<a<<endl;
a=wiringPiI2CRead(fd);
delayMicroseconds(500000);
cout<<a<<endl;
a=wiringPiI2CRead(fd);
delayMicroseconds(500000);
cout<<a<<endl;
a=wiringPiI2CRead(fd);
delayMicroseconds(500000);
cout<<a<<endl;
a=wiringPiI2CRead(fd);
delayMicroseconds(500000);
cout<<a<<endl;
a=wiringPiI2CRead(fd);
delayMicroseconds(500000);
cout<<a<<endl;
a=wiringPiI2CRead(fd);
delayMicroseconds(500000);
cout<<a<<endl;

EEPROM Reading is working properly using above code but write is not working.. Any suggestions !!

I Ran into a similar problem trying to write to an ON Semiconductor CAT24C32 over i2C on a raspberry pi. datasheet for reference . I was able to write a python script to read/write to the EEPROM using the smbus2 library gitub , but when I went to implement it in my c++ app I couldn't get the writes to write to the correct addresses (or at all) within the EEPROM.

My understanding for why wiringPi was an issue is because of 2 potential factors.

  1. the EEPROM has 2 address bytes to point to an address in memory. The requirement from the EEPROM to write a byte to an address is to send [SlaveAddr] -> [AddrHI] -> [AddrLOW] -> [Data] -> STOP.
  2. The byte order of the WiringPiI2CWriteReg16 seems to be backwards to what the EEPROM was expecting so the WiringPi Library would write an address to the EEPROM like [SlaveAddr] -> [AddrHI] -> [DataLOW] -> [DataHIGH].
  3. [Bonus!] WiringPi does not have a Block Write command to be able to write more than 1 byte at a time to the I2C device.

My work around was to split the address up and shift the [AddrLOW] into [DataHIGH]. This worked because the EEPROM only has 8bit registers so each databyte will only ever be 8bits.

#include "wiringPiI2C.h"
#include <chrono>
#include <thread>

void WriteDataToEEPROM(int devId, int reg, std::vector<int> data) {
    int fd = wiringPiI2CSetup(devId);

    wiringPiI2CWriteReg8(fd, reg, reg); // Set the internal addres point
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    uint8_t i = reg;
    for (const auto d : data) {
        uint8_t addr[2];
        addr[1] = i >> 8;
        addr[0] = i;
        int status = wiringPiI2CWriteReg16(fd, addr[1], (d << 8) | addr[0]);
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
        i++;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM