Operácie

Zbernica i2c: EEPROM: Rozdiel medzi revíziami

Zo stránky SensorWiki

Balogh (diskusia | príspevky)
Balogh (diskusia | príspevky)
Bez shrnutí editace
Riadok 46: Riadok 46:
[[Súbor:i2c_address.png|400px|center]]
[[Súbor:i2c_address.png|400px|center]]


== '''Software''' ==
 
 
 
 
=== 3. Inicializácia ===




Pri tvorbe programu pre modul budeme využívať už hotovú knižnicu <code>i2cmaster</code> dostupnú odtiaľto http://senzor.robotika.sk/mmp/src/i2c/
Pri tvorbe programu pre modul budeme využívať už hotovú knižnicu <code>i2cmaster</code> dostupnú odtiaľto http://senzor.robotika.sk/mmp/src/i2c/
'''1. Inicializácia'''


Najprv je potrebné zbernicu inicializovať:
Najprv je potrebné zbernicu inicializovať:
Riadok 60: Riadok 62:
</source>
</source>


'''
2. Čítanie z A/D prevodníka'''


Potom môžeme prečítať hodnotu na analógovom vstupe č. 3, na ktorom je pripojený trimer:


<div style='text-align: center;'>
[[File:MIPS_8591_ReadValue.png]]<br>
''Postupnosť pre čítanie hodnoty z obvodu 8591.''
</div>


<source lang="c">
=== 4. Zápis ===
/*    value = AnlogRead-From-PCF8591(channel);  */


        i2c_start( PCF8591_ADDR << 1 | I2C_WRITE);        // set device address and write mode
[[Súbor:i2c_write.png|600px|center]]
        i2c_write(channel);                              // which channel want to read
        i2c_stop();
        i2c_rep_start(PCF8591_ADDR << 1 | I2C_READ);      // repeated start for reading
        i2c_readAck();                                    // read dummy byte
value = i2c_readNak();                                    // read Analog value
        i2c_stop();
</source>


Zápis je jednoduchší, preto ním začneme:


'''3. Zápis na analógový výstup'''
<source lang="c">


A napokon prečítanú hodnotu zapíšeme na analógový výstup, takže zmenu priamo uvidíme na pripojenej zelenej LED dióde.
      // zapis hodnotu  0x41 ('A') to EEPROM address 00 (Byte Write)


<div style='text-align: center;'>
    i2c_start_wait( (EEPROM_ADDR << 1) | I2C_WRITE);     // set device address and write mode
[[File:MIPS_8591_WriteValue.png]]<br>
    i2c_write(0x00);                                     // write address = 0
''Postupnosť pre zápis hodnoty do obvodu 8591.''
    i2c_write(0x41);                                     // write value 0x41 to EEPROM
</div>
    i2c_stop();                                         // set stop conditon = release bus
 
<source lang="c">
/*    AnalogWrite-To-PCF8591(value);  */
        i2c_start((PCF8591_ADDR << 1 | I2C_WRITE));       // set device address and write mode
        i2c_write(CONTROL BYTE);                         // set analog output active
        i2c_write(value);                                 // write the required Analog Output value (0-255)
        ...                                              // multiple write possible
        i2c_stop();                                       // set stop conditon = release bus                      


</source>
</source>


Program je samozrejme vhodné doplniť o zobrazovanie veličín buď na LCD displeji, alebo v termináli cez sériové rozhranie.  
             
<div style='text-align: center;'>
[[File:EEPROM_ReadValue.png]]<br>
''Postupnosť pre čítanie hodnoty z EEPROM pamäte.''
</div>


Pri vytváraní riadiaceho slova by vám mal napomôcť tento obrázok z datasheetu:


<div style='text-align: center;'>
<div style='text-align: center;'>
[[File:MIPS_8591_Register.png|500px]]<br>
[[File:EEPROM_WriteValue.png]]<br>
''Obsadenie riadiaceho registra obvodu 8591.''
''Postupnosť pre zápis hodnoty do obvodu 8591.''
</div>
</div>




=== 3. Zápis ===


[[Súbor:i2c_write.png|600px|center]]


=== 4. Čítanie ===
=== 5. Čítanie ===


[[Súbor:i2c_read.png|600px|center]]
[[Súbor:i2c_read.png|600px|center]]
Riadok 123: Riadok 103:
[[Súbor:i2c_readRandom.png|400px|center]]
[[Súbor:i2c_readRandom.png|400px|center]]


 
 
 
 
 
 
 


<source lang="c">
<source lang="c">


#include <avr/interrupt.h>  
  /* Precitame hodnotu zapisanu v predchadzajucom kroku z EEPROM addresy 0  */
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include <util/twi.h>
#include <stdio.h>


//#include "lcd.h"
    i2c_start_wait( (EEPROM_ADDR << 1) | I2C_WRITE);    // set device address and write mode
#include "Uart_ch.h"
    i2c_write(0x00);                        // write address = 5
    i2c_rep_start(Dev24C02+I2C_READ);      // set device address and read mode


unsigned char RD_EEprom(unsigned char adr_RAM);
    val = i2c_readNak();                   // read one byte from EEPROM
void WR_EEprom(unsigned char adr_IC,unsigned char adr_pocitadlo);
    i2c_stop();
void obsluha_Stav_Aut_I2C(void);


    for(;;);


</source>


#define ADR_IC_WR 0xA0  // EEPROM Adresa IC+WR
Program je samozrejme vhodné doplniť o zobrazenie prečítanej hodnoty v termináli cez sériové rozhranie.  
#define ADR_IC_RD 0xA1  // EEPROM Adresa IC+RD
 
 
 
volatile  unsigned char buffer_I2C[10]; // buffer pre obsluhu I2C
 
 
 
 
FILE mystdout_Uart = FDEV_SETUP_STREAM(sendchar, NULL, _FDEV_SETUP_WRITE);
 
 
void WR_EEprom(unsigned char adr_IC,unsigned char adr_pocitadlo)
{ // nastavenie globalnych premennych
 
buffer_I2C[0]=adr_IC; // Adr obvodu + wr
buffer_I2C[1]=adr_pocitadlo;     // Nastavenie Adresneho citaca 24LC04 , Adresa (z ktorej citam)/(do ktorej zapisujem)
// buffer_I2C[1]=<obsah>; // zapisovane data, byte,-ty
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); // send start condition
// a odovzdanie riadenia "preruseniu od I2C"
obsluha_Stav_Aut_I2C();
 
}
 
 
 
unsigned char RD_EEprom(unsigned char adr_RAM)
{
// nastavenie globalnych premennych
 
buffer_I2C[0]=ADR_IC_RD; // Adr obvodu + rd
buffer_I2C[1]=adr_RAM;     // Sem vrati obsah z nastavenej adresy 24LC04
 
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); // send start condition
// a odovzdanie riadenia "preruseniu od I2C"
obsluha_Stav_Aut_I2C();
return(buffer_I2C[1]);
}
 
// tato funkcia vyuziva globalne premenne
// buffer_I2C[x]
// Wr_data - tato premenna nadobuda vyznam az pri komunikacii s konkretnou premennou
//          vid. "instrukcny subor" I2C periferie
 
// implementovany instrukcny subor pre seriovu EEPROM max 256 byte
// S|adr_IO+wr|<AC>|P                -- nastavenie adresneho citaca pamate EEPROM
// {nie je implementova} S|adr_IO+wr|<AC>|data|P          -- zapisanie dat na nastavenu adresu pamate EEPROM
// S|adr_IO+rd|data|P                -- precitanie jedneho bytu z aktualne nastavenej adresy pamate EEPROM
//                                      obsah adresneho citaca sa inkrementne
 
void obsluha_Stav_Aut_I2C(void)
{ unsigned char pom_St_Aut=0;
nav:while ((TWCR & _BV(TWINT)) == 0);  /* wait for transmission */
 
    {  pom_St_Aut=TWSR & 0xf8; // precitaj stav
    printf(" %02x",pom_St_Aut);
switch(pom_St_Aut)
{ case TW_START:// = 0x08 // odvysielany start
  case TW_REP_START:// = 0x10 // odvysielany repeated start
                TWDR = buffer_I2C[0];// Adr+wr/rd, adresa IO
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  break;
 
  case TW_MT_SLA_ACK: //        0x18  Data byte has been tramsmitted and ACK received
                TWDR = buffer_I2C[1]; // tu konkretne, nastavenie Adreseho citaca pamate.
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  break;
 
  case TW_MT_DATA_ACK: //        0x28  Data byte has been tramsmitted and ACK received
  TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */
return; //  tento riadok v preruseni vypadne
  break;
 
  case TW_MR_SLA_ACK: //  0x40  // Data byte has been tramsmitted and NACK received
  TWCR = _BV(TWINT) | _BV(TWEN) ; // clear interrupt to start transmission
  break;
 
  case TW_MR_DATA_NACK: // 0x58  // Data byte has been tramsmitted and ACK received
      buffer_I2C[1]= TWDR;     // Vycitaj jeden byte z  24LC04.  Adresny citac sa posunie
      TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); // send stop condition
return; // tento riadok v preruseni vypadne
  break;
 
  default:
  TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */
return; // tento riadok v preruseni vypadne
  break;
}
}
goto nav; // toto v preruseni vypadne
}
 
 
 
 
int main(void)
{ unsigned char znak;
 
unsigned int i=0;
unsigned char poc_adresa_EEPROM=0;
 
 
inituart(); // inicializacia UARTU                      // inicializacia v 4-bitovom rezime
                   
 
//  sei();                    // Enable ALL interrupts                     
 
// ini I2C
 
  TWCR =  _BV(TWEN); /* send start condition */
  TWBR = 72; // fi2c= fosc/(16 +2(preddelic=00=> 1)(<TWBR>)) = 100kHz
  TWSR=1;
}
 
 
// TODO: to USART
/* ************************************************************ */
 
stdout = &mystdout_Uart;
 
 
printf("Nastavenie adresy EEPROM = %02x \n\r",poc_adresa_EEPROM);
WR_EEprom(ADR_IC_WR,poc_adresa_EEPROM);
 
 
printf("\n\r\rVypis EEPROM: \n\r");
 
// vypisme prvych 10 znakov
    while (i<10) //256)// kapacita pamate 256 znakov, bytov,
{
znak = RD_EEprom(ADR_IC_RD); // obsah adresneho citaca EEPROM sa automaticky inkrementuje
if(znak==0xff)i=256; // vymazane pametove miesto
{
printf("  %02d %02x %c\r",i++,znak,znak);
}
       
}
for(;;);  // a cakam napr. na  "RESET"
}
</source>




[[Category:DVPS]][[Category:AVR]][[Category:MMP]][[Category:I2C]][[Category:MIPS]]
[[Category:DVPS]][[Category:AVR]][[Category:MMP]][[Category:I2C]][[Category:MIPS]]

Verzia z 19:05, 13. apríl 2023

Oboznámenie so zbernicou i2c

Úlohy:

  1. Pripojte k procesoru pamäť podľa schémy zapojenia
  2. Schému upravte tak, aby adresa zariadenia bola ?? - určí cvičiaci
  3. Zapíšte na prvé pamäťové miesto (adresa 0x00) znak 'A'
  4. Prečítajte, či je znak správne zapísaný
  5. Prečítajte obsah celej pamäte a vypíšte ho na terminál PC
  6. Zapíšte do pamäte 10 bytov nejakej informácie a zistite, ako dlho trvá zápis jedného byte, t.j. aká veľká musí byť prestávka medzi jednotlivými zápismi.


Literatúra


Datasheets



1. Schéma zapojenia


Správnosť zapojenia si môžete vyskúšať programom Médiá:i2c_scan.ino - nájde všetky obvody pripojené na zbernici.

2. Device address



3. Inicializácia

Pri tvorbe programu pre modul budeme využívať už hotovú knižnicu i2cmaster dostupnú odtiaľto http://senzor.robotika.sk/mmp/src/i2c/

Najprv je potrebné zbernicu inicializovať:

         i2c_init();                                       // initialize I2C library



4. Zápis

Zápis je jednoduchší, preto ním začneme:

       // zapis hodnotu  0x41 ('A') to EEPROM address 00 (Byte Write) 

     i2c_start_wait( (EEPROM_ADDR << 1) | I2C_WRITE);     // set device address and write mode
     i2c_write(0x00);                                     // write address = 0
     i2c_write(0x41);                                     // write value 0x41 to EEPROM
     i2c_stop();                                          // set stop conditon = release bus


Súbor:EEPROM ReadValue.png
Postupnosť pre čítanie hodnoty z EEPROM pamäte.


Súbor:EEPROM WriteValue.png
Postupnosť pre zápis hodnoty do obvodu 8591.



5. Čítanie


  /*  Precitame hodnotu zapisanu v predchadzajucom kroku z EEPROM addresy 0   */

     i2c_start_wait( (EEPROM_ADDR << 1) | I2C_WRITE);     // set device address and write mode
 
     i2c_write(0x00);                        // write address = 5
     i2c_rep_start(Dev24C02+I2C_READ);       // set device address and read mode

     val = i2c_readNak();                    // read one byte from EEPROM
     i2c_stop();

     for(;;);

Program je samozrejme vhodné doplniť o zobrazenie prečítanej hodnoty v termináli cez sériové rozhranie.