60 nap alatt Arduino #30-#31 - IIC busz és az EEPROM

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10032
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. augusztus 29. szerda, 12:53

Ez megvan. De ezen kívül?
Hardware kódos/ én általam választhatott címek?
IC típus:
- óra/eeprom/Teletext...
- melyik hól szólal meg...

Avatar
muszer
Biztosítékgyilkos
Hozzászólások: 50
Csatlakozott: 2009. december 28. hétfő, 7:00

HozzászólásSzerző: muszer » 2012. augusztus 29. szerda, 15:09

Én a DS1307 RTC-t használom. (1101000)

http://datasheets.maxim-ic.com/en/ds/DS1307.pdf

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

HozzászólásSzerző: macsek » 2012. augusztus 29. szerda, 15:52

Robert írta:Az általam eddig használt órachipek:
...
R5S372 - ??
MCP4v411 - ?


Biztos vagy a típusukban? Csak mert a gugli nem ismeri egyiket sem.

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

EEPROM írás vagy olvasás hiba

HozzászólásSzerző: macsek » 2012. szeptember 1. szombat, 22:24

Kérlek segítsetek megfogni, mi lehet a hiba a programomban.
A soros eepromba kétféleképpen írok és kétféleképpen olvasok. Az egyik rutin-párral egy bájtot, a másikkal egy menetben többet.
A blokkos írás-olvasás konzekvensen az elvárásnak megfelelően működik, tehát feltehetőleg hardver hibánk nincs. Érdekes módon a bájtonkénti írás/olvasás közül valamelyik nincs a helyzet magaslatán, néha nem csinálják meg a dolgukat, ilyenkor 255-nek olvasható a memória tartalma.

Miért?

/* i2c eeprom iras/olvasas*/
/* Macsek, 2012.08.31 */
#include "Wire.h" //I2C, azaz TWI miatt kell

#define I2C_EEPROM_CIM 0x50
#define EEPROM_LAPMERET 64  // 64 bajt 1 lap, ez a belso puffermeret is
#define EEPROM_MERET (32U*1024) //24LC256 = 32kB
#define EEPROM_IRAS_LAPATLEPES_HIBA -1
#define EEPROM_OLVASAS_HIBA -2

void setup(void)
{
  byte b;
  byte tarolo[64]; //
  unsigned int i;

  Serial.begin(9600);
  Serial.println("EEPROM teszt, Macsek");

  Wire.begin();

  //teszt
#define TESZT_CIM 300

  b = read_eeprom(TESZT_CIM);
  Serial.print("olvasott bajt:");
  Serial.println(b);

  write_eeprom(TESZT_CIM, b+1);

  b = read_eeprom(TESZT_CIM);
  Serial.print("Iras utan olvasott bajt:");
  Serial.println(b);

  //// blokkokkal ugyanez

#define TESZT_BLOKK_CIM (2*EEPROM_MERET)
#define TESZT_BLOKK_MERET 10

  Serial.println("eeprom blokk olvasas");
  read_eeprom_tobbet(TESZT_BLOKK_CIM, tarolo, TESZT_BLOKK_MERET);
  for(i=0; i<TESZT_BLOKK_MERET; i++)
  {
    Serial.print(tarolo[i]);
    if (i<TESZT_BLOKK_MERET-1)
      Serial.print(", ");
    else
      Serial.println("");
  }

  for(i=0; i<TESZT_BLOKK_MERET; i++)
    if(tarolo[i])
      //tarolo[i] *= i+2;
      tarolo[i]++;
    else
      tarolo[i]=millis(); // ha nulla volt tegyunk bele valami ertelmeset

  write_eeprom_lap(TESZT_BLOKK_CIM, tarolo, TESZT_BLOKK_MERET);

  Serial.println("eeprom blokk iras utani ujraolvasas");
  read_eeprom_tobbet(TESZT_BLOKK_CIM, tarolo, TESZT_BLOKK_MERET);
  for(i=0; i<TESZT_BLOKK_MERET; i++)
  {
    Serial.print(tarolo[i]);
    if (i<TESZT_BLOKK_MERET-1)
      Serial.print(", ");
    else
      Serial.println("\n");
  }

  ;
}


void loop(void)
{
  ;
}


byte read_eeprom(unsigned int cim)
{
  byte valaszkod;

  Wire.beginTransmission(I2C_EEPROM_CIM);
  Wire.write(cim>>8);
  Wire.write(cim&0xff);
  valaszkod = Wire.endTransmission();
  if(valaszkod != 0) // hiba
    ;

  Wire.requestFrom(I2C_EEPROM_CIM, 1);
  for(int i=0; i<10 && !Wire.available(); i++)
    delay(1);

  // hibakezeles??
  return( Wire.read() );
}



byte write_eeprom(unsigned int cim, byte kiirando)
{
  byte valaszkod;

  Wire.beginTransmission(I2C_EEPROM_CIM);
  Wire.write(cim>>8);
  Wire.write(cim&0xff);
  Wire.write(kiirando);

  valaszkod = Wire.endTransmission();
  if(valaszkod != 0) // hiba
    ;
  else
    delay(5);

  return valaszkod;
}

// ha 0 db-ot ker, akkor igy jart, beolvassuk a teljes eepromot, tobbszor.
// mint Chuck Norris, aki elszamolt a vegtelenig. Ketszer.
byte read_eeprom_tobbet(unsigned int cim, byte *beolvasohely, unsigned int olvasando_db)
{
  byte valaszkod;
  unsigned int i;

  Wire.beginTransmission(I2C_EEPROM_CIM);
  Wire.write(cim>>8);
  Wire.write(cim&0xff);
  valaszkod = Wire.endTransmission();
  if(valaszkod != 0 ) // hiba
    ;
  else if(valaszkod=Wire.available())
  {
    Wire.requestFrom(I2C_EEPROM_CIM, olvasando_db);
    for(i=0; i<10 && !Wire.available(); i++)
      delay(1);
    for(i=0; i<olvasando_db; i++)
      beolvasohely[i] = Wire.read(); // beolvasas bajtonkent
    //// le tudom irni C nyelven is :-)
    // do
    // *beolvasohely++ = Wire.read(); // beolvasas bajtonkent
    // while(--olvasando_db);
  }
  else
    valaszkod = EEPROM_OLVASAS_HIBA;

  // hibakezeles??
  return( valaszkod );
}

// max 64 byte kiirasa egy lapra (64 bajtos lapon belul)
byte write_eeprom_lap(unsigned int cim, byte *kiirandok, byte kiirando_db)
{
  byte valaszkod;
  unsigned int i;

#define EEPROM_LAPMASK (0xffff - EEPROM_LAPMERET +1) // azaz (-EEPROM_LAPMERET)
  if(cim&EEPROM_LAPMASK == (cim+kiirando_db)&EEPROM_LAPMASK) // Lapon belul marad
  {  
    Wire.beginTransmission(I2C_EEPROM_CIM);
    Wire.write(cim>>8);
    Wire.write(cim&0xff);

    // do
    // Wire.write(*kiirandok++); // kiirandok altal mutatott
    // while(--kiirando_db);
    //// Na jo, rendes leszek es ezt is leirom olvashatoan :-)

    for(i=0; i<kiirando_db; i++)
      Wire.write(kiirandok[i]);
    //?? hibakezeles?

    valaszkod = Wire.endTransmission();
    if(valaszkod != 0) // hiba
      ;
    else
      delay(5); // 5ms a max lap kiirasi ido
  }
  else
    valaszkod = EEPROM_IRAS_LAPATLEPES_HIBA;  //HIBA

    return valaszkod;
}



Íme pár futtatás eredménye (reset-et nyomtam meg párszor) :


Kód: Egész kijelölése

EEPROM teszt, Macsek
olvasott bajt:255
Iras utan olvasott bajt:255
eeprom blokk olvasas
103, 123, 76, 46, 103, 183, 56, 78, 96, 221
eeprom blokk iras utani ujraolvasas
104, 124, 77, 47, 104, 184, 57, 79, 97, 222

EEPROM teszt, Macsek
olvasott bajt:255
Iras utan olvasott bajt:255
eeprom blokk olvasas
104, 124, 77, 47, 104, 184, 57, 79, 97, 222
eeprom blokk iras utani ujraolvasas
105, 125, 78, 48, 105, 185, 58, 80, 98, 223

EEPROM teszt, Macsek
olvasott bajt:255
Iras utan olvasott bajt:255
eeprom blokk olvasas
105, 125, 78, 48, 105, 185, 58, 80, 98, 223
eeprom blokk iras utani ujraolvasas
106, 126, 79, 49, 106, 186, 59, 81, 99, 224

EEPROM teszt, Macsek
olvasott bajt:255
Iras utan olvasott bajt:255
eeprom blokk olvasas
106, 126, 79, 49, 106, 186, 59, 81, 99, 224
eeprom blokk iras utani ujraolvasas
107, 127, 80, 50, 107, 187, 60, 82, 100, 225

EEPROM teszt, Macsek
olvasott bajt:3
Iras utan olvasott bajt:4
eeprom blokk olvasas
107, 127, 80, 50, 107, 187, 60, 82, 100, 225
eeprom blokk iras utani ujraolvasas
108, 128, 81, 51, 108, 188, 61, 83, 101, 226


Avatar
Robert
Elektronbűvölő
Hozzászólások: 10032
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. szeptember 1. szombat, 22:30

Szerintem nem írtál byte alapon semmit ki. Az üres IC tartalma 0xFF minden cellaban....

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

HozzászólásSzerző: macsek » 2012. szeptember 1. szombat, 22:34

Robert írta:Szerintem nem írtál byte alapon semmit ki. Az üres IC tartalma 0xFF minden cellaban....


Az utolsó futtatás eredménye viszont azt mutatja, h mégis írtam. Néha zsinórban többször is ír, máskor meg 255-nek látszik. Ez a fura számomra... :?

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

HozzászólásSzerző: macsek » 2012. szeptember 1. szombat, 22:36

EEPROM teszt, Macsek
olvasott bajt:4
Iras utan olvasott bajt:5
eeprom blokk olvasas
108, 128, 81, 51, 108, 188, 61, 83, 101, 226
eeprom blokk iras utani ujraolvasas
109, 129, 82, 52, 109, 189, 62, 84, 102, 227

EEPROM teszt, Macsek
olvasott bajt:255
Iras utan olvasott bajt:255
eeprom blokk olvasas
109, 129, 82, 52, 109, 189, 62, 84, 102, 227
eeprom blokk iras utani ujraolvasas
110, 130, 83, 53, 110, 190, 63, 85, 103, 228

EEPROM teszt, Macsek
olvasott bajt:255
Iras utan olvasott bajt:255
eeprom blokk olvasas
110, 130, 83, 53, 110, 190, 63, 85, 103, 228
eeprom blokk iras utani ujraolvasas
111, 131, 84, 54, 111, 191, 64, 86, 104, 229

EEPROM teszt, Macsek
olvasott bajt:5
Iras utan olvasott bajt:6
eeprom blokk olvasas
111, 131, 84, 54, 111, 191, 64, 86, 104, 229
eeprom blokk iras utani ujraolvasas
112, 132, 85, 55, 112, 192, 65, 87, 105, 230

Avatar
szegoj
SzínkódFestő
Hozzászólások: 92
Csatlakozott: 2010. február 4. csütörtök, 7:00
Tartózkodási hely: Budapest

HozzászólásSzerző: szegoj » 2012. szeptember 2. vasárnap, 7:43

Macsek, ez mi ?
Miért növeled (mindig) a tarolo[i] tartalmat ?

    /* i2c eeprom iras/olvasas*/
    /* Macsek, 2012.08.31 */
    ...

    void setup(void)
    {
    ...

    for(i=0; i<TESZT_BLOKK_MERET; i++)
    if(tarolo[i])
    //tarolo[i] *= i+2;
    tarolo[i]++;

    else
    tarolo[i]=millis(); // ha nulla volt tegyunk bele valami ertelmeset


Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

HozzászólásSzerző: macsek » 2012. szeptember 2. vasárnap, 9:10

szegoj írta:Macsek, ez mi ?
Miért növeled (mindig) a tarolo[i] tartalmat ?

    /* i2c eeprom iras/olvasas*/
    /* Macsek, 2012.08.31 */
    ...

    void setup(void)
    {
    ...

    for(i=0; i<TESZT_BLOKK_MERET; i++)
    if(tarolo[i])
    //tarolo[i] *= i+2;
    tarolo[i]++;

    else
    tarolo[i]=millis(); // ha nulla volt tegyunk bele valami ertelmeset



Beolvasok egy blokk adatot.
Megjelenítem, h mit olvastam.
Módosítom, h legközelebb mást olvasson ki onnan.
Visszaírom.
Ellenőrzésképpen megint beolvasom.
És megjelenítem, h mit olvastam vissza.

Ez az egész csak teszt, ami azt mutatja, h jól műxik-e. De sajnos vmi miatt nem. :( No ezt segítsetek lécci megtalálni, h miért.

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3348
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

HozzászólásSzerző: kapu48 » 2012. szeptember 2. vasárnap, 11:59

Így hirtelen bele kukkantva az adatlapba:

http://pdf1.alldatasheet.com/datasheet- ... LC256.html
11. oldal FIGURE 8-2: RANDOM READ

A cím elküldése után kel még 1 control Byte, utána van adat read!
:!:

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3348
Csatlakozott: 2008. augusztus 29. péntek, 6:00
Tartózkodási hely: Újkígyós

HozzászólásSzerző: kapu48 » 2012. szeptember 2. vasárnap, 12:46

Szóval le kelene zárni az adat olvasást:

Kód: Egész kijelölése

byte read_eeprom(unsigned int cim)
 {
   byte valaszkod;

   Wire.beginTransmission(I2C_EEPROM_CIM);
   Wire.write(cim>>8);
   Wire.write(cim&0xff);
   valaszkod = Wire.endTransmission();
   if(valaszkod != 0) // hiba
     ;

   Wire.requestFrom(I2C_EEPROM_CIM, 1);
   for(int i=0; i<10 && !Wire.available(); i++)
     delay(1);

   // hibakezeles??
   return( Wire.read() );
   Wire.endTransmission()   // lezárás
 }

Kód: Egész kijelölése

// ha 0 db-ot ker, akkor igy jart, beolvassuk a teljes eepromot, tobbszor.
// mint Chuck Norris, aki elszamolt a vegtelenig. Ketszer.
byte read_eeprom_tobbet(unsigned int cim, byte *beolvasohely, unsigned int olvasando_db)
 {
   byte valaszkod;
   unsigned int i;

   Wire.beginTransmission(I2C_EEPROM_CIM);
   Wire.write(cim>>8);
   Wire.write(cim&0xff);
   valaszkod = Wire.endTransmission();
   if(valaszkod != 0 ) // hiba
     ;
   else if(valaszkod=Wire.available())
   {
     Wire.requestFrom(I2C_EEPROM_CIM, olvasando_db);
     for(i=0; i<10 && !Wire.available(); i++)
       delay(1);
     for(i=0; i<olvasando_db; i++)
       beolvasohely[i] = Wire.read(); // beolvasas bajtonkent
       
     Wire.endTransmission()   // lezárás
     //// le tudom irni C nyelven is :-)
     // do
     // *beolvasohely++ = Wire.read(); // beolvasas bajtonkent
     // while(--olvasando_db);
   }
   else
     valaszkod = EEPROM_OLVASAS_HIBA;

   // hibakezeles??
   return( valaszkod );
 }

8)

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

HozzászólásSzerző: macsek » 2012. szeptember 2. vasárnap, 20:16

kapu48 írta:Így hirtelen bele kukkantva az adatlapba:

http://pdf1.alldatasheet.com/datasheet- ... LC256.html
11. oldal FIGURE 8-2: RANDOM READ

A cím elküldése után kel még 1 control Byte, utána van adat read!
:!:


Köszi a doksi linket és a tippet.


kapu48 írta:Szóval le kelene zárni az adat olvasást:
byte read_eeprom(unsigned int cim)
{
byte valaszkod;

Wire.beginTransmission(I2C_EEPROM_CIM);
Wire.write(cim>>8);
Wire.write(cim&0xff);
valaszkod = Wire.endTransmission();
if(valaszkod != 0) // hiba
;

Wire.requestFrom(I2C_EEPROM_CIM, 1);
for(int i=0; i<10 && !Wire.available(); i++)
delay(1);

// hibakezeles??
return( Wire.read() );
Wire.endTransmission() // lezárás
}

// ha 0 db-ot ker, akkor igy jart, beolvassuk a teljes eepromot, tobbszor.
// mint Chuck Norris, aki elszamolt a vegtelenig. Ketszer.
byte read_eeprom_tobbet(unsigned int cim, byte *beolvasohely, unsigned int olvasando_db)
{
byte valaszkod;
unsigned int i;

Wire.beginTransmission(I2C_EEPROM_CIM);
Wire.write(cim>>8);
Wire.write(cim&0xff);
valaszkod = Wire.endTransmission();
if(valaszkod != 0 ) // hiba
;
else if(valaszkod=Wire.available())
{
Wire.requestFrom(I2C_EEPROM_CIM, olvasando_db);
for(i=0; i<10 && !Wire.available(); i++)
delay(1);
for(i=0; i<olvasando_db; i++)
beolvasohely[i] = Wire.read(); // beolvasas bajtonkent

Wire.endTransmission() // lezárás
//// le tudom irni C nyelven is :-)
// do
// *beolvasohely++ = Wire.read(); // beolvasas bajtonkent
// while(--olvasando_db);
}
else
valaszkod = EEPROM_OLVASAS_HIBA;

// hibakezeles??
return( valaszkod );
}

8)


A kivastagított sorok úgy gondolom elküldik a következő kontrol bájtot.
A blokkos olvasás (read_eeprom_tobbet) egyébként jól működik, legalábbis a teszt szerint.

Ha van valami újabb ötleted (vagy vki másnak) akkor jöhet!
Köszi.

Közben nézegettem minta kódokat, ránézésre még rosszabbak, mint az enyém 8)

Kód: Egész kijelölése

byte readEEPROM(int deviceaddress, unsigned int eeaddress )
{
     byte rdata = 0xFF;

     Wire.beginTransmission(deviceaddress);
     Wire.send((int)(eeaddress >> 8));   // MSB
     Wire.send((int)(eeaddress & 0xFF)); // LSB
     Wire.endTransmission();

     Wire.requestFrom(deviceaddress,1);

     if (Wire.available()) rdata = Wire.receive();

     return rdata;
}

Ezt a furcsaságot lehet találni sokfelé. Ebben az a fura, h ha valamiért nincs meg a beérkező adat akkor simán FF-et ad vissza és kész. Ez korántsem korrekt.

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

TWI buffer

HozzászólásSzerző: macsek » 2012. szeptember 2. vasárnap, 20:47

macsek írta:az dereng, h 32 byte a Wire buffere


Megkerestem. Tényleg annyi.
c:\Program Files\Arduino\arduino-1.0.1\libraries\Wire\utility\twi.h

Kód: Egész kijelölése

  #ifndef TWI_BUFFER_LENGTH
  #define TWI_BUFFER_LENGTH 32
  #endif 


Ezek szerint az én blokkos írásomhoz ezt felül kell definiálni, még a Wire.h meghívása előtt, különben nem fog tudni 64 bájtot kiírni egy menetben. (?)

A TWI buffer méret még felülírható, de a Wire buffere hanyagabbul van definiálva, tehát nem ilyen egyszerű felülbírálni:

c:\Program Files\Arduino\arduino-1.0.1\libraries\Wire\Wire.h

Kód: Egész kijelölése

#define BUFFER_LENGTH 32


Ennek a cseréjéhez a teljes Wire.h tartalmát be kell írnunk egy "helyettesítő" header fájlba, mondjuk Wire64.h, ahol ezt az 1 értéket változtatjuk meg és aztán ezt a fájt használjuk. Nem túl szerencsés megoldás, bár működik.


Megnéztem a C++ forrást is.
c:\Program Files\Arduino\arduino-1.0.1\libraries\Wire\Wire.cpp

Kód: Egész kijelölése

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
{
  // clamp to buffer length
  if(quantity > BUFFER_LENGTH){
    quantity = BUFFER_LENGTH;
  }

Kód: Egész kijelölése

size_t TwoWire::write(uint8_t data)
{
  if(transmitting){
  // in master transmitter mode
    // don't bother if buffer is full
    if(txBufferLength >= BUFFER_LENGTH){
      setWriteError();
      return 0;
    }
    // put byte in tx buffer
    txBuffer[txBufferIndex] = data;
    ++txBufferIndex;


Tehát az olvasás sem lehetséges ennek a könyvtárnak a használatával úgy, ahogy az adatlap mondja, tehát egy olvasással akár a teljes tartalmát. Írni is és olvasni is max a BUFFER_LENGTH értéke által meghatározott, gyárilag 32 bájtot engedi.

Konklúzió:
Ha nagyon akarjuk megcsinálható saját, helyettesítő header fájl használatával, de a uC szűkös memóriájából csak azért odaadni a buffernek még 32 bájtot, hogy a lap egy menetben írható legyen, nem feltétlenül indokolt.

Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00
Tartózkodási hely: Bp

HozzászólásSzerző: macsek » 2012. szeptember 2. vasárnap, 23:06

Tovább nézegettem a Wire forrását.

Arduino.cc írta:Wire.requestFrom() ...
Returns
None


A kód szerint pedig megvárja a beolvasás végét és visszaadja a beolvasott bájtok számát:

Kód: Egész kijelölése

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
{
  // clamp to buffer length
  if(quantity > BUFFER_LENGTH){
    quantity = BUFFER_LENGTH;
  }
  // perform blocking read into buffer
  uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
  // set rx buffer iterator vars
  rxBufferIndex = 0;
  rxBufferLength = read;

  return read;
}


Kód: Egész kijelölése

/*
 * Function twi_readFrom
 * Desc     attempts to become twi bus master and read a
 *          series of bytes from a device on the bus
 * Input    address: 7bit i2c device address
 *          data: pointer to byte array
 *          length: number of bytes to read into array
 *          sendStop: Boolean indicating whether to send a stop at the end
 * Output   number of bytes read
 */
uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop)
{
  uint8_t i;

  // ensure data will fit into buffer
  if(TWI_BUFFER_LENGTH < length){
    return 0;
  }

  // wait until twi is ready, become master receiver
  while(TWI_READY != twi_state){
    continue;
  }
  twi_state = TWI_MRX;
  twi_sendStop = sendStop;
  // reset error state (0xFF.. no error occured)
  twi_error = 0xFF;

  // initialize buffer iteration vars
  twi_masterBufferIndex = 0;
  twi_masterBufferLength = length-1;  // This is not intuitive, read on...
  // On receive, the previously configured ACK/NACK setting is transmitted in
  // response to the received byte before the interrupt is signalled.
  // Therefor we must actually set NACK when the _next_ to last byte is
  // received, causing that NACK to be sent in response to receiving the last
  // expected byte of data.

  // build sla+w, slave device address + w bit
  twi_slarw = TW_READ;
  twi_slarw |= address << 1;

  if (true == twi_inRepStart) {
    // if we're in the repeated start state, then we've already sent the start,
    // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
    // We need to remove ourselves from the repeated start state before we enable interrupts,
    // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
    // up. Also, don't enable the START interrupt. There may be one pending from the
    // repeated start that we sent outselves, and that would really confuse things.
    twi_inRepStart = false;         // remember, we're dealing with an ASYNC ISR
    TWDR = twi_slarw;
    TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);   // enable INTs, but not START
  }
  else
    // send start condition
    TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);

  // wait for read operation to complete
  while(TWI_MRX == twi_state){
    continue;
  }

  if (twi_masterBufferIndex < length)
    length = twi_masterBufferIndex;

  // copy twi buffer to data
  for(i = 0; i < length; ++i){
    data[i] = twi_masterBuffer[i];
  }
   
  return length;
}


Ez azt jelenti, h nem szabad a visszaadott értéket felhasználni, mert nincs dokumentálva és emiatt elvileg bármikor megváltoztathatják egy újabb verzióban?


Kép


Kód: Egész kijelölése

// must be called in:
// slave rx event callback
// or after requestFrom(address, numBytes)
int TwoWire::available(void)
{
  return rxBufferLength - rxBufferIndex;
}
Ezt mi a francért kötelező meghívni? Semmit nem csinál csak visszaadja, h hány bájt van a bufferben.
Max akkor van értelme, ha addig nem olvasunk, míg nem adja azt, h van már beérkezett adatunk!

Így lenne korrekt az olvasás:

Kód: Egész kijelölése

Wire.requestFrom(80, 1);
  while(Wire.available()) {
      ;
  }
  num = Wire.receive();


----------

Sajnos a tanfolyami példaprogram sem működik :(
(az FF-et 99-re cseréltem, a send-eket meg write-re és a receive-eket read-re)
/*  IIC EEPROM byte alapu kezelese
 60 nap alatt arduino tanfolyam
 (c) TavIR http://avr.tavir.hu  */

//IIC buszt hasznalunk
#include "Wire.h"
//24LC256 chip cime
#define disk1 0x50

void setup(void)
{//Sorosport megnyitasa es IIC inicializalas
  Serial.begin(9600);
  Wire.begin();

  //Melyik cimre irjunk?
  unsigned int address = 99;
  //Ird be a ..., a ...cimre, a 123-as szamot
  writeEEPROM(disk1, address, 123);
  //Mi van a .. cimen a chipben? Ird ki sorosporton
  Serial.println(readEEPROM(disk1, address));
}

void loop(){
}

void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data )
{
  Wire.beginTransmission(deviceaddress);
  //Cim magas helyierteke
  Wire.write((int)(eeaddress >> 8));
  //Cim alacsony helyierteke
  Wire.write((int)(eeaddress & 0xFF));
  //Es a beirando adat
  Wire.write(data);
  Wire.endTransmission();
  delay(5);
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress )
{
  byte rdata = 99;
  Wire.beginTransmission(deviceaddress);
  //Magas helyiertek
  Wire.write((int)(eeaddress >> 8));
  //Alacsony helyiertek
  Wire.write((int)(eeaddress & 0xFF));
  Wire.endTransmission();

  //Egy byte olvasando
  Wire.requestFrom(deviceaddress,1);
  //Ha sikerult...
  if (Wire.available()){
    rdata = Wire.read();
  }

  return rdata;
}



Avatar
Robert
Elektronbűvölő
Hozzászólások: 10032
Csatlakozott: 2005. december 9. péntek, 7:00
Tartózkodási hely: Budapest
Kapcsolat:

HozzászólásSzerző: Robert » 2012. szeptember 3. hétfő, 5:13

Hibás chiped van.
Globális változónak használod az i-t, miközben mindenütt lokális lenne.


Vissza: “60 nap alatt Arduino - Házi feladatok”

Ki van itt

Jelenlévő fórumozók: nincs regisztrált felhasználó valamint 1 vendég