Operácie

Zbernica i2c: Rozdiel medzi revíziami

Zo stránky SensorWiki

Chamraz (diskusia | príspevky)
Bez shrnutí editace
Balogh (diskusia | príspevky)
Bez shrnutí editace
Riadok 14: Riadok 14:
<source lang="c">
<source lang="c">


#include <avr/interrupt.h> 
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include <util/twi.h>
#include <stdio.h>


#define Dev24C02  0xA2      // device address of EEPROM 24C02, see datasheet
//#include "lcd.h"
#include "Uart_ch.h"


int main(void)
unsigned char RD_EEprom(unsigned char adr_RAM);
{
void WR_EEprom(unsigned char adr_IC,unsigned char adr_pocitadlo);
    unsigned char ret;
void obsluha_Stav_Aut_I2C(void);


    state = i2c_init();                            // initialize I2C library
      if (state != 0) call_error(state);


    // read value from EEPROM address 5
    i2c_start_wait(Dev24C02+I2C_WRITE);    // set device address and write mode


    i2c_write(0x05);                        // write address = 5
#define ADR_IC_WR 0xA0  // EEPROM Adresa IC+WR
    i2c_rep_start(Dev24C02+I2C_READ);      // set device address and read mode
#define ADR_IC_RD 0xA1  // EEPROM Adresa IC+RD


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


    for(;;);
 
  }
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>
</source>




[[Category:DVPS]]
[[Category:DVPS]]

Verzia z 11:13, 6. december 2012

K. Zbernica i2c: EEPROM

Prečítajte obsah predloženej pamäti EEPROM a zobrazte na PC.

Literatúra:


#include <avr/interrupt.h>  
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include <util/twi.h>
#include <stdio.h>

//#include "lcd.h"
#include "Uart_ch.h"

unsigned char RD_EEprom(unsigned char adr_RAM);
void WR_EEprom(unsigned char adr_IC,unsigned char adr_pocitadlo);
void obsluha_Stav_Aut_I2C(void);



#define ADR_IC_WR		0xA0   	// EEPROM Adresa IC+WR
#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"
 
}