Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] mikroC I2C Read / Write array code to check! Can it be improved?

Status
Not open for further replies.

Alloy

Advanced Member level 4
Joined
Apr 3, 2016
Messages
116
Helped
0
Reputation
0
Reaction score
0
Trophy points
16
Activity points
1,003
Hey
This is reading array from 24 EEPROMs (I2C protocol).
This code is working for me, but I'm asking how to improve it, well, could it be faster, or have some error checking?


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
char str[16];
 
void I2C_Read_Array(int devAdr, unsigned char *o, int s, unsigned char adr0)
{          
        int i;
        for(i = 0; i < s; i++)
        {
           I2C1_Start();              // issue I2C start signal
           I2C1_Wr(devAdr);             // send byte via I2C  (device address + W)
           I2C1_Wr(adr0+i);
           I2C1_Wr(0x00);  // second address part?
           I2C1_Repeated_Start();     // issue I2C signal repeated start
           I2C1_Wr(devAdr+1);             // send byte (device address + R)
           o[i] = I2C1_Rd(0u);       // Read the data (NO acknowledge)
           I2C1_Stop();               // issue I2C stop signal
          Delay_10ms();
        }
}
void I2C_Write_Array(int devAdr, unsigned char *o, int s, unsigned char adr0)
{
        int i;
        for(i = 0; i < s; i++)
        {
          I2C1_Start();              // issue I2C start signal
          I2C1_Wr(devAdr);             // send byte via I2C  (device address + W)
          I2C1_Wr(adr0+i);   /// adr lo
          I2C1_Wr(0x00);  // second address part?
          I2C1_Wr(o[i]);             // send data (data to be written)
          I2C1_Stop();               // issue I2C stop signal
          Delay_10ms();
        }
}
void I2C_Test_Array()
{
   unsigned char ar[4];
   int i;
   I2C_Read_Array(0xA2,ar,sizeof(ar),0);
   ar[0] += 1;
   ar[1] += 2;
   ar[2] += 3;
   ar[3] += 4;
   I2C_Write_Array(0xA2,ar,sizeof(ar),0);
   for(i = 0; i < sizeof(ar); i++)
   {
         IntToStr(ar[i],str);
         UART_Write_Text(str);
   }
   UART_Write_Text("...");
}

 

Hi,

I don´t see 24 EEPROMs...

could it be faster
--> We don´t see your I2C clock speed setup...

or have some error checking?
--> Yes, but it will slow down overall performance.

Klaus
 

It's 24LC64

Code C - [expand]
1
I2C1_Init(100000);         // initialize I2C communication


So how to do error checking?
 

You are using single byte read. Sure, it will be slower than sequential reading. The address counter register are self incremental. But only inside page size. For 24C64 memory page size have 32 bytes lenght. So, the auto incremental counter limited only with 5 bits. So, to make it works, you should take in accaunt this limitation. Basically, I recomend you to keep using this method. Sequential reading is too complicated you know...
 

Hi,

why not using 400kHz?
Why the 10ms delay after each read/write?

****
Error check: What you want:
* parity
* CRC
* hash
* ....

Klaus
 

This is my function that writes a data to I2C eeprom. As you can see, every page is loading one by one with delay needed to recharge hv capacitor inside chip.
You can take it as a reference and write the same for reading.
Code:
typedef struct
{
	/* Data */
	int Mem_adrs;
	char * buf;
	int size;
	
	/* Functions */
	char (*WritePage)(char I2C_Adrs, char * MemPos, char MemPosSize, char * buf, char size);
	char (*ReadPage) (char I2C_Adrs, char * MemPos, char MemPosSize, char * buf, char size);	
	void (*delay_func)(unsigned int ms);
	
	/* Settings */
	char I2C_Adrs;
	char PageSize;
	char PageWriteTime;
}EEPROM_StructTypeDef;
Code:
char EEPROM_Write (EEPROM_StructTypeDef * EEPROM)
{
	char Result = 0; 
	char	BytesToWrite;
	char m_adrs[2];
	m_adrs[0] = (char)EEPROM->Mem_adrs;
	m_adrs[1] = (char)(EEPROM->Mem_adrs >> 8);
	BytesToWrite = m_adrs[0] & (EEPROM->PageSize - 1);
	
	/* First piece of page if exist */
	if (BytesToWrite)
	{
		Result = EEPROM->WritePage(EEPROM->I2C_Adrs, m_adrs, 2, EEPROM->buf, BytesToWrite);
		EEPROM->delay_func(EEPROM->PageWriteTime);
		EEPROM->size -= BytesToWrite;
		EEPROM->Mem_adrs += BytesToWrite;
	}
	if (!EEPROM->size || Result) return Result; //nothing to write any more

	/* Writing all full pages */
	do
	{
		Result = EEPROM->WritePage(EEPROM->I2C_Adrs, m_adrs, 2, EEPROM->buf, EEPROM->PageSize);
		
		/* Calculate new offset */
		EEPROM->buf += EEPROM->PageSize;
		EEPROM->size -= EEPROM->PageSize;
		EEPROM->Mem_adrs += EEPROM->PageSize;
		m_adrs[0] = (char)EEPROM->Mem_adrs;
		m_adrs[1] = (char)(EEPROM->Mem_adrs >> 8);		
		EEPROM->delay_func(EEPROM->PageWriteTime);
	}while(EEPROM->size >= EEPROM->PageSize);
	
	if (!EEPROM->size) return Result; //nothing to write any more
	
	Result = EEPROM->WritePage(EEPROM->I2C_Adrs, m_adrs, 2, EEPROM->buf, EEPROM->size);
	EEPROM->delay_func(EEPROM->PageWriteTime);
	return Result;
}
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top