I just bought an AT24C256 EEPROM recently, the capacity is 32K Byte, the data address width is 16Bit, it supports IIC 1M (5V) 400K (2.7V) speed mode, and the AVR M16 on-chip IIC can read data stably at high speed! After debugging, share with you prawns.


The procedure is as follows: (winavr)

#include

#include

#include

#include

#define FREQ 8

#include

#include

#include

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long

//pin definition

#define pinSCL 0 //PC0 SCL

#define pinSDA 1 //PC1 SDA

//For the sake of insurance, it is best to connect an external pull-up resistor of 1~10K to VCC on SCL/SDA.

#define fSCL 1000000 //TWI clock is 1000KHz

//Prescale factor=1 (TWPS=0)

#if F_CPU < fSCL*36

#define TWBR_SET 2; //TWBR must be greater than or equal to 10

#else

#define TWBR_SET (F_CPU/fSCL-16)/2; //Calculate TWBR value

#endif

#define TW_ACT (1 "//TWCR can only be IN/OUT, direct assignment is more space-saving than logical operations (|= &=)

#define SLA_24CXX 0xA0 //24Cxx series manufacturer device address (higher four bits)

#define ADDR_24C256 0x00

// AT24C256's address lines A2/1/0 are all grounded, SAW=0xA0+0x00 "<1+0x00, SLAR=0xA0+0x00<<1+0x01

//TWI_operation status

#define TW_BUSY 0

#define TW_OK 1

#define TW_FAIL 2

//TWI_Read and write command status

#define OP_BUSY 0

#define OP_RUN 1

//TWI public steps for read and write operations

#define ST_FAIL 0 //Error status

#define ST_START 1 //START status check

#define ST_SLAW 2 //SLAW status check

#define ST_WADDR_H 3 //ADDR status check

#define ST_WADDR_L 4 //ADDR status check

//TWI read operation steps

#define ST_RESTART 5 //RESTART status check

#define ST_SLAR 6 //SLAR status check

#define ST_RDATA 7 //Read data status check, loop n bytes

//TWI write operation steps

#define ST_WDATA 8 //Write data status check, loop n bytes

#define FAIL_MAX 1 //Maximum number of retries

void delay_nms(uint ms)//Several milliseconds delay

{

int i;

for(i=0;i{

_delay_loop_2(FREQ*250);

}

}

unsigned char TWI_RW(unsigned char sla, unsigned int addr, unsigned char *ptr, unsigned int len);

unsigned char BUFFER[256]; //buffer

void Test(void);

struct str_TWI //TWI data structure

{

volaTIle unsigned char STATUS; //TWI_operation status

unsigned char SLA; //device address of the slave device

unsigned char ADDR_H; //The data address of the slave device

unsigned char ADDR_L; //Data address of the slave device

unsigned char *pBUF; //Data buffer pointer

unsigned int DATALEN; //data length

unsigned char STATE; //TWI read and write operation steps

unsigned char FAILCNT; //Number of failed retries

};

struct str_TWI strTWI; //Data structure variable of TWI

//AT24C256 read and write functions (including random read, continuous read, byte write, page write)

/ / Determined according to the lowest bit of sla (judged by the interrupt program)

//bit0=1 TW_READ read

//bit0=0 TW_WRITE write

// sla device address (can't be wrong)

// addr EEPROM address (0~32767)

// *ptr read and write data buffer

// len read data length (1~32768), write data length (1 or 8 or 16 or 32 or 64)

// whether the return value can perform the current operation

unsigned char TWI_RW (unsigned char sla, unsigned int addr, unsigned char *ptr, unsigned int len)

{

// unsigned char i;

if (strTWI.STATUS==TW_BUSY)

{//TWI is busy and cannot operate

return OP_BUSY;

}

strTWI.STATUS=TW_BUSY;

strTWI.SLA=sla;

strTWI.ADDR_H=(unsigned char)((addr""8)&0xff);

strTWI.ADDR_L=(unsigned char)(addr&0xff);

strTWI.pBUF=ptr;

strTWI.DATALEN=len;

strTWI.STATE=ST_START;

strTWI.FAILCNT=0;

TWCR=(1" return OP_RUN;

}

SIGNAL (SIG_2WIRE_SERIAL)

{//IIC interrupt

unsigned char acTIon, state, status;

acTIon=strTWI.SLA&TW_READ; //Get the operation mode

state=strTWI.STATE;

status=TWSR&0xF8; //mask the prescaler bit

if ((status"=0x60)||(status==0x00))

{//Interrupt caused by bus error or slave mode, will not be processed

return;

}

switch(state)

{

case ST_START: //START status check

if(status==TW_START)

{//Successful sending start signal

TWDR=strTWI.SLA&0xFE; //Send device address to write SLAW

TWCR=TW_ACT; //Trigger the next action and clear the start sending flag at the same time

}

else

{//Error sending start signal

state=ST_FAIL;

}

break;

case ST_SLAW: //SLAW status check

if (status==TW_MT_SLA_ACK)

{//Successful sending device high address

TWDR=strTWI.ADDR_H; //Send eeprom address

TWCR=TW_ACT; //Trigger the next action

}

else

{//Error sending device address

state=ST_FAIL;

}

break;

case ST_WADDR_H: //ADDR status check

if (status==TW_MT_DATA_ACK)

{//Successful sending the low address of the device

TWDR=strTWI.ADDR_L; //Send eeprom address

TWCR=TW_ACT; //Trigger the next action

}

else

{//Error sending device address

state=ST_FAIL;

}

break;

case ST_WADDR_L: //ADDR status check

if (status==TW_MT_DATA_ACK)

{//Send eeprom address successfully

if (acTIon==TW_READ)

{//Read operation mode

TWCR = (1 " }

else

{//Write operation mode

TWDR=*strTWI.pBUF++; //write the first byte

strTWI.DATALEN--;

state=ST_WDATA-1; //The next step will jump to the WDATA branch

TWCR=TW_ACT; //Trigger the next action

}

}

else

{//Error sending eeprom address

state=ST_FAIL;

}

break;

case ST_RESTART: //RESTART status check, only read operation mode can jump here

if(status==TW_REP_START)

{//Send the restart signal successfully

TWDR=strTWI.SLA; //Send device address to read SLAR

TWCR=TW_ACT; //Trigger the next action and clear the start sending flag at the same time

}

else

{//Error in resending start signal

state=ST_FAIL;

}

break;

case ST_SLAR: //SLAR status check, only read operation mode can jump here

if (status==TW_MR_SLA_ACK)

{//Send device address successfully

if (strTWI.DATALEN--)

{//Multiple data

TWCR = (1 " }

else

{//There is only one data

TWCR=TW_ACT; //Set NAK to trigger the next action

}

}

else

{//Error sending device address

state=ST_FAIL;

}

break;

case ST_RDATA: //Read data status check, only read operation mode can jump here

state--; //loop until the specified length of data is read

if (status==TW_MR_DATA_ACK)

{//Read data successfully, but not the last data

*strTWI.pBUF++=TWDR;

if (strTWI.DATALEN--)

{//There are multiple data

TWCR = (1 " }

else

{//Ready to read the last data

TWCR=TW_ACT; //Set NAK to trigger the next action

}

}

else if (status==TW_MR_DATA_NACK)

{//The last data has been read

*strTWI.pBUF++=TWDR;

TWCR=(1" strTWI.STATUS=TW_OK;

}

else

{//Error reading data

state=ST_FAIL;

}

break;

case ST_WDATA: //Write data status check, only write operation mode can jump here

state--; //loop until the specified length of data is written

if (status==TW_MT_DATA_ACK)

{//Write data successfully

if (strTWI.DATALEN)

{// also write

TWDR=*strTWI.pBUF++;

strTWI.DATALEN--;

TWCR=TW_ACT; //Trigger the next action

}

else

{// write enough

TWCR=(1" strTWI.STATUS=TW_OK;

//It takes 10ms (maximum) programming time to actually record the data after starting the write command

//The device does not respond to any commands during programming

}

}

else

{//Failed to write data

state=ST_FAIL;

}

break;

default:

//error status

state=ST_FAIL;

break;

}

P03 Series Push Wire Connectors

Smaller size, space saving

Fast connection

111

Push-In Cable Connector,Dual Poles Quick Wire Connectors,fast connection cable connectors,cable managing connectors

Jiangmen Krealux Electrical Appliances Co.,Ltd. , https://www.krealux-online.com