稼働中

Raspberry Pi Pico(d_12)AT24C32 EEPROM

AT24C32  (I2C)

前回のDS3231を搭載したリアルタイムクロック(RTC)モジュールの続きです。
RTCモジュールにはAT24C32 32Kビット(4Kバイト)のEEPROMが付いています。EEPROMの動作を確認しようと思います。
※micro:bitの記事e_19、e_49からRaspberry Pi Picoで使えるように追記、修正等をしました。
RTCモジュールの外観、接続例は記事d_11を参照ください。AT24C32(EEPROM)のスレーブアドレスは0x57(87)です。

AT24C32の説明

データシートから抜粋してAT24C32の説明します。
■ スレーブアドレス
スレーブアドレス(Device Address)はA0-A2で変更できます。そのため、同ラインで8個の識別が出来ます。
RTCモジュールにも後付けで変更できるようにA0-A2があります。
RTCモジュールのAT24C32のスレーブアドレスは0x57(‘0b1010111’)です。従って、A0-A2はすべて’H’になっているようです。
AT24C32 ピン配置
※ Atmel AT24C32のデータシートから抜粋
■ Write
EEPROMへの書込みは1byte単位で書込むbytewriteがあります。(下図)
AT24C32は4KバイトのEEPROMなのでアドレスの範囲は0x00~0xfffです。
アドレスをfirst word addressとsecond word addressで送ります。例えば、0x5f3ならfirstは0x05、secondは0xf3になります。
下方のスクリプトではdef word_adr(dat)の部分になります。
AT24C32 byte write
他に32byte単位で書込むpage writeがあります。詳細はデータシートを参照ください。
■ Read
EEPROMの読出しは読み出すアドレス(first/second word address)を送った後に指定したバイト単位で読出します。(下図)
下方のスクリプトでは以下のようにしています。
i2c.writeto(スレーブアドレス、word address) word addressはbytearray(2)
i2c.readfrom(スレーブアドレス,読み出すバイト数) 読み出すbytearrayデータが返ります
他にCURRENT ADDRESS READ、SEQUENTIAL READがあります。詳細はデータシートを参照ください。
AT24C32 read

スクリプト

AT24C32のスクリプトは以下のようにしました。
EEPROMのアドレス0xff0から16英数文字を保存、読出しなどをしています。
※開発環境はThonnyです。ThonnyでMicroPythonをRaspberry Pi Pico with RP2040にインストールして使っています。


pico_ds3231_02b_eeprom.py
#!/usr/bin/env python
# -*- coding: utf-8 -*
from machine import I2C,Pin
import time
# RTC DS3231 Module AT24C32 EEPROM 4k 0x00-0xfff
i2c=I2C(1, scl=Pin(11), sda=Pin(10), freq=100_000)
ep_adr=0x57     # AT24C32 slave address 0x50(80)~0x57(87) 

# word address first/second
def word_adr(dat):
    reg_adr=bytearray(2)
    reg_adr[0]= dat >>8             #first
    reg_adr[1]=(0x00ff & dat)       #second
    return reg_adr
   
## 英数字だけ
# write moji code to EEPROM
def m_write(moji,r_pos=0x00):
    reg_adr=word_adr(r_pos)     # word address
    m_dat=moji.encode()         # 英数字をエンコードする

    #write to EEPROM 
    buf=reg_adr+m_dat  #rom_address + moji_code_data
    i2c.writeto(ep_adr,buf)
    time.sleep_ms(10)           # 待機が必要 OSError: [Errno 5] EIO
    return

#read moji_code from EEPROM
def m_read(num,r_pos=0x00):
    reg_adr=word_adr(r_pos)  # word address
    i2c.writeto(ep_adr,reg_adr)
    a=i2c.readfrom(ep_adr,num)
    de_moji=""
    for i in range(num):        
        de_moji=de_moji+chr(a[i])
    print('moji=',de_moji)

#read all EEPROM 全データ
def read_EP():
    print('Reading--')
    seg=0   # used regi num
    reg_adr=bytearray(2) # EEPROM Address 0x00~0xfff
    for i in range(0x1000):
        reg_adr=word_adr(i) # word address
        #print(reg_adr)
        i2c.writeto(ep_adr,reg_adr)
        a=i2c.readfrom(ep_adr,1)
        if a != b'\xff':
            seg=seg+1
            #print(i,hex(i),reg_adr,a)
            print(i,hex(i),a) # 数、番地、値
    print('reg_count=',seg)       

#erase 0xff write 4k=1024*4 全消去
def erase_EP():
    print('Erasing--')
    erase_dat=bytearray(32)
    for i in range(32):
        erase_dat[i]=0xff       # 0xffを書込む(消去)

    reg_adr=bytearray(2)        # EEPROM Address 32*128=4096
    for i in range(128):
        reg_adr=word_adr(i*32)  # word address
        #print(reg_adr)
        buf=reg_adr+erase_dat   #rom_address + moji_code_data
        i2c.writeto(ep_adr,buf)
        time.sleep_ms(10)       # OSError: [Errno 5] EIO

## main
ep_pos=0xff0                        # regi-address
m_write('0123456789ABCDEF',ep_pos)  # 16_moji
m_read(16,ep_pos)                   #  0xff0から16データ読む
print("")

read_EP()       # 書込みのあるデータを表示
print("")

erase_EP()      # 全データを消去(0xffで埋める)
read_EP()       # 書込みのあるデータを表示

部分説明

■ m_write(moji,r_pos=0x00)
EEPROMにデータを保存します。
moji:書込む英数文字列
r_pos:書込むEEPROMの番地

■ m_read(num,r_pos=0x00)
EEPROMのデータ読出します。
num:読み出すデータのバイト数
r_pos:読み出すEEPROMの先頭番地

■ read_EP()
EEPROMの全データを読出します。データが0xff以外なら書き出します。

■ erase_EP()
EEPROMの全データを消去します。(0xffを書込む)

実行結果

結果は以下のようになりました。※Thonnyのshellに表示されます。


>>> %Run -c $EDITOR_CONTENT
moji= 0123456789ABCDEF          # 書込みを確認

Reading--                       # 全書込みを確認
4080 0xff0 b'0'
4081 0xff1 b'1'
4082 0xff2 b'2'
4083 0xff3 b'3'
4084 0xff4 b'4'
4085 0xff5 b'5'
4086 0xff6 b'6'
4087 0xff7 b'7'
4088 0xff8 b'8'
4089 0xff9 b'9'
4090 0xffa b'A'
4091 0xffb b'B'
4092 0xffc b'C'
4093 0xffd b'D'
4094 0xffe b'E'
4095 0xfff b'F'
reg_count= 16                   # 16dataを確認

Erasing--                       # 全消去
Reading--                       # 全書込みを確認
reg_count= 0                    # 全消去されている
>>> 

まとめ

Raspberry Pi PicoでRTCモジュールのAT24C32を使ってEEPROMの動作を確認しました。