C言語(SDCC)を使用して、今回はZ80+SIO+PIO+PCA9564PWでのI2Cデバイスを使用してI2C EEPROMの読み書きを行っていきたいと思います。

使用するI2CEEPROMは、24FC1025-I/P(秋月電子)で1MbitのEEPROMとなります。
この24FC1025-I/Pのパッケージには512Kbitのチップが2個入った形になります。

1Pin(A0)および2Pin(A1)をLow(GND)にすると、i2Cアドレスが0x50と0x54になります。
(3Pin(A2)はVCC)

これまで使用してきた i2c_init.rel、i2c_addr.rel、i2c_read.rel、i2c_write.relを使用することで、EEPROMにアクセスできます。

バイトライトは次のようになります。

コントロールバイト + バイトアドレスH + バイトアドレスL + 書き込みするデータ

コントロールバイトにはI2Cアドレス+Wを指定します。
例として、バイトアドレスHには 0x20 バイトアドレスLには 0x00 書き込みデータとして0xe5を指定しました。

バイト書き込み後は、なぜかNACKが帰ってくるので、NACK待ちをしました。

    //byte write

	printf("byte write \n");

	uint8_t byte_in[3];							//byte write buff
	uint8_t byte_out[3];
	
	byte_in[0]= 0x02;				// byte write address H
	byte_in[1]= 0x00;				// byte write address H
    
	byte_in[2]= 0xe5;				// byte data 
	printf("write address %2x%2x data=%2x \n",byte_in[0],byte_in[1],byte_in[2]);		
	uint16_t *byte_in_buff = byte_in;
	i2c_write(eeprom1_addr,3,byte_in_buff);
		while(i2c_addr(eeprom1_addr) == 0x20)   //nack
		{
			printf("*");
		}

バイトリードも同様に

コントロールバイト + バイトアドレスH + バイトアドレスL

になりますので、バイトアドレスHには 0x20 バイトアドレスLには 0x00を指定して読み込みを行います。

	//byte read

	printf("byte read \n");
	
	byte_in[0]= 0x02;				// byte write address H
	byte_in[1]= 0x00;				// byte write address H

	i2c_write(eeprom1_addr,2,byte_in_buff);


    uint16_t *byte_out_buff = byte_out;
	i2c_read(eeprom1_addr,1,byte_out_buff);

	printf("read address %2x%2x data=%2x \n",byte_in[0],byte_in[1],byte_out[0]);

ページライトは、このデバイスでは、1ページ、128ビットの連続書き込みができます。

コントロールバイト + バイトアドレスH + バイトアドレスL + 

    書き込みするデータn + 書き込みするデータn+1 +・・・ 

     ・・・ +書き込みするデータn+127

ここでは書き込みデータとして、 0~ 0x7fの配列データを書き込みすることにします。

一気に書き込みするので、書き込み後、NACKが帰ってくるので、NACK待ちします。

	//page write
 
	printf("page write\n");
    
	for (i=0;i <= 128;i++){
		in_buff[i+2]= i;
	}
	
	for (i=0;i <= 7;i++){
		for (j=0 ;j <= 15;j++){
			printf("%2x ",in_buff[i*16+j+2]);
		}
		printf("\n");
	}
	printf("\n");
	
	in_buff[0]=0;				//write address H
	in_buff[1]=0;				//write address L

	uint16_t *buff_in = in_buff;	
	i2c_write(eeprom1_addr,130,buff_in);
	while(i2c_addr(eeprom1_addr) == 0x20)   //nack
		{
			printf("*");
		}

ページリードは、1ページ、128ビットのデータを一気読みします。

コントロールバイト + バイトアドレスH + バイトアドレスL を指定した後、

コントロールバイト + 1ページ(128bit)読み込みとなります。

	//page read
	
	printf("\npage read \n");
	
	uint8_t read_addr_h=0;
	uint8_t read_addr_l=0;
	i2c_write(eeprom1_addr,1,&read_addr_h);
	i2c_write(eeprom1_addr,1,&read_addr_l);	

	uint16_t *buff_out = out_buff;
	i2c_read(eeprom1_addr,128,buff_out);
	for (i=0;i <= 7;i++){
		for (j=0 ;j <= 15;j++){
		printf ("%2x ",out_buff[i*16+j]);
		}
		printf("\n");
	}

全体のプログラム

//  I2C(PCA9564) eeprom (Z80+SIO+PIO)]

#include <stdio.h>
#include <stdint.h>


extern  void    i2c_init(void);
extern  uint8_t i2c_read(uint8_t,uint8_t,uint16_t *);
extern  uint8_t i2c_write(uint8_t,uint8_t,uint16_t *);
extern	uint8_t i2c_addr(uint8_t);

 

int main(){

    uint8_t eeprom1_addr=0x50;				//eeprom 24FC1025
    uint8_t eeprom2_addr=0x54;				//eeprom 24FC1025   

    uint8_t in_buff[127+2];					// page write buff
    uint8_t out_buff[127];					// page read buff
    uint8_t i=0,j=0;
 
	// i2c init
	i2c_init();
    
    //byte write

	printf("byte write \n");

	uint8_t byte_in[3];							//byte write buff
	uint8_t byte_out[3];
	
	byte_in[0]= 0x02;				// byte write address H
	byte_in[1]= 0x00;				// byte write address H
    
	byte_in[2]= 0xe5;				// byte data 
	printf("write address %2x%2x data=%2x \n",byte_in[0],byte_in[1],byte_in[2]);		
	uint16_t *byte_in_buff = byte_in;
	i2c_write(eeprom1_addr,3,byte_in_buff);
		while(i2c_addr(eeprom1_addr) == 0x20)   //nack
		{
			printf("*");
		}

	printf("\n");
	
	//byte read

	printf("byte read \n");
	
	byte_in[0]= 0x02;				// byte write address H
	byte_in[1]= 0x00;				// byte write address H

	i2c_write(eeprom1_addr,2,byte_in_buff);


    uint16_t *byte_out_buff = byte_out;
	i2c_read(eeprom1_addr,1,byte_out_buff);

	printf("read address %2x%2x data=%2x \n",byte_in[0],byte_in[1],byte_out[0]);
	
	//page write
 
	printf("page write\n");
    
	for (i=0;i <= 128;i++){
		in_buff[i+2]= i;
	}
	
	for (i=0;i <= 7;i++){
		for (j=0 ;j <= 15;j++){
			printf("%2x ",in_buff[i*16+j+2]);
		}
		printf("\n");
	}
	printf("\n");
	
	in_buff[0]=0;				//write address H
	in_buff[1]=0;				//write address L

	uint16_t *buff_in = in_buff;	
	i2c_write(eeprom1_addr,130,buff_in);
	while(i2c_addr(eeprom1_addr) == 0x20)   //nack
		{
			printf("*");
		}
	

	//page read
	
	printf("\npage read \n");
	
	uint8_t read_addr_h=0;
	uint8_t read_addr_l=0;
	i2c_write(eeprom1_addr,1,&read_addr_h);
	i2c_write(eeprom1_addr,1,&read_addr_l);	

	uint16_t *buff_out = out_buff;
	i2c_read(eeprom1_addr,128,buff_out);
	for (i=0;i <= 7;i++){
		for (j=0 ;j <= 15;j++){
		printf ("%2x ",out_buff[i*16+j]);
		}
		printf("\n");
	}
	return(0x00);
}	

コンパイルします。

$ sdcc -mz80 --out-fmt-ihx --code-loc 0xa000 --no-std-crt0 -o i2c_eeprom_write_main.ihx mycrt0.rel i2c_eeprom_write_main.c i2c_init.rel i2c_addr.rel i2c_write.rel i2c_read.rel putchar.rel
Conflicting flags in area    _CODE
Conflicting flags in area    _DATA
Conflicting flags in area    _CODE
Conflicting flags in area    _DATA
Conflicting flags in area    _CODE
Conflicting flags in area    _DATA
Conflicting flags in area    _CODE
Conflicting flags in area    _DATA
Conflicting flags in area    _CODE
Conflicting flags in area    _DATA
Conflicting flags in area    _CODE
Conflicting flags in area    _DATA

実行します。モニタのlコマンドで i2c_eeprom_write_main.ihxを読み込みます。

>c a000 y:
byte write
write address  2 0 data=e5
********
byte read
read address  2 0 data=e5
page write
 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f

********
page read
 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f

>
おすすめの記事