I2C外掛程式eeprom的讀寫

2021-10-23 02:26:40 字數 3895 閱讀 5395

i2c簡介

i2c匯流排通訊是一種通訊協,用於連線微控制器及其外圍裝置,由兩根線組成,時鐘線sda和資料線scl。

如圖所示,外掛程式裝置接到相應的線上就可以被i2c識別到,另外關於scl,sda以怎麼樣的波形去傳送訊息,以及裝置的應答波紋就不在詳細介紹了,這個對於不是直接寫驅動的開發人員來說沒有必要了解,上層應用很少去以乙個乙個電位的形式發訊息,有需要的可以再找專業的文章了解;

eeprom

eeprom是一種掉電後資料不丟失的儲存器,常用來儲存一些配置資訊,以便系統重新上電的時候載入之。例如,可以寫mac、ip、使用者驗證資訊等。eeprom市場上提供的型別有許多,主要是記憶體大小的差異,有1k, 2k, 4k等容量,注意有些是以b為單位,有些是以b為單位,不過廠家為了顯大都會以b為單位,就像廠家的1m是以1000算的文不是1024。

如圖是某eeprom的引腳圖,我們只關注nc的引腳,一般廠商會提供相應的pdf說明,圖中的1,2, 3代表的是a0,a1,a2三個引腳,nc代表可變資料的意思,只有0和1兩個值,如果不是nc則代表固定值0,,這些值是用來尋找硬體位址的。按照協議定址的引數是8位,eeprom前4位是1010,這個是ieee規定的國際標準,如果你的不是這個,那相容性來說就比較差了。

8位資料是 1010(a0)(a1)(a2)(r/w) ,最後一位1為讀操作0為寫操作,實際上算的時候只會算前7位,比如1010000為0x50,這是掛載在iic上的硬體位址。a0,a1,a2的值取決於eeprom的大小,如果你的容量是2kb大小,那麼a0,a1只能是0,a3可取0和1,那麼會發現iic上顯示有0x50和0x51的位址被掛載,eeprom一塊儲存大小為256位元組。

i2c-tools

i2cdetect -l   檢測有幾條iic匯流排

圖中i2c-3, i2c-0的3和0就是該兩條匯流排的代號

i2cdetect -r -y 0 檢測匯流排上掛載的裝置位址

0是你要檢測的匯流排代號

i2cdump -f -y 0 0x50    0是匯流排代號,0x50是掛載位址

如圖預設值為0xff。最後一排01 01 是我修改的。

這樣你就可以看到eeprom裡面寫入的資料了,當然實際上沒有人會這麼直白的寫密碼賬號,通常都是一堆加密的資料,需要特定的演算法才可以得到正解。

##程式讀寫eeprom資料

讀寫的方式就比較多了,直接呼叫iic讀寫介面讀寫,自己參考i2c-tool工具的源**進行讀寫,我是用檔案的形式來讀寫。

畢竟是在linux平台上進行操作,那麼對於linux的概念來說一切皆檔案。下面就放**吧,具體注釋就不給了,相信大家還是可以看懂的。

void _alpu_delay_ms(unsigned int i)  

//dev-name 裝置名 linux上的"/dev/i2c-0"

//device_addr 資料塊位址0x50 到.....

//sub_addr 塊中位址名 0x00到0xff

//buff 寫入資料

//byteno 寫入資料長度

int i2c_write(char *dev_name,unsigned char device_addr, unsigned char sub_addr, unsigned char *buff, int byteno)

i2c_data.nmsgs = 1;

i2c_data.msgs = (struct i2c_msg *)malloc(i2c_data.nmsgs *sizeof(struct i2c_msg));

if (i2c_data.msgs == null)

ioctl(fd, i2c_timeout, 1);

ioctl(fd, i2c_retries, 2);

memset(buftmp, 0, 32);

buftmp[0] = sub_addr;

memcpy(buftmp + 1, buff, byteno);

i2c_data.msgs[0].len = byteno + 1;;

i2c_data.msgs[0].addr = device_addr;

i2c_data.msgs[0].flags = 0;     // 0: write 1:read

i2c_data.msgs[0].buf = buftmp;

ret = ioctl(fd, i2c_rdwr, (unsigned long)&i2c_data);

if (ret < 0)

free(i2c_data.msgs);

close(fd);

#if 0

int i;

printf("i2c_write 0x%02x:",buftmp[0]);

for(i=0; i

printf("\n");

#endif

_alpu_delay_ms(100);

return 0;

}int i2c_read(char *dev_name, unsigned char device_addr, unsigned char sub_addr, unsigned char *buff, int byteno)

i2c_data.nmsgs = 2;

i2c_data.msgs = (struct i2c_msg *)malloc(i2c_data.nmsgs *sizeof(struct i2c_msg));

if (i2c_data.msgs == null)

ioctl(fd, i2c_timeout, 1);

ioctl(fd, i2c_retries, 2);

//write reg

memset(buftmp, 0, 32);

buftmp[0] = sub_addr;

i2c_data.msgs[0].len = 1;

i2c_data.msgs[0].addr = device_addr;

i2c_data.msgs[0].flags = 0;     // 0: write 1:read

i2c_data.msgs[0].buf = buftmp;

//read data

i2c_data.msgs[1].len = byteno;

i2c_data.msgs[1].addr = device_addr;

i2c_data.msgs[1].flags = 1;     // 0: write 1:read

i2c_data.msgs[1].buf = buff;

ret = ioctl(fd, i2c_rdwr, (unsigned long)&i2c_data);

if (ret < 0)

free(i2c_data.msgs);

close(fd);

#if 0

int i;

printf("i2c__read 0x%02x:",buftmp[0]);

for (i = 0; i < byteno; i++)

printf("\n");

#endif

return 0;

I2C驅動(2) 讀寫eeprom

include include include include include include include include include static unsigned short ignore static unsigned short normal addr 位址值是7位 改為0x60的話...

I2C讀寫問題

a.完全不能進行讀寫 1 通訊協議不正確 有很多的i2c裝置,並不支援所有的i2c協議,同時也不是乙個比較標準的i2c裝置 軟體的通訊時序不正確。2 i2c裝置位址不正確 有很多的i2c裝置的位址是可以通過硬體設定的 也有器件資料提供的資料是錯誤的。3 i2c通訊線上沒有加上拉電阻 由於i2c的從裝...

I2C匯流排結構的EEPROM

常用晶元at24c02 at24c02是乙個2k位序列cmos e2prom,內部含有256個8位位元組。at24c02有乙個8位元組頁寫緩衝器。該器件通過iic匯流排介面進行操作,有乙個專門的寫保護功能 引腳 scl 序列時鐘 at24c02序列時鐘輸入管腳用於產生器件所有資料傳送或接收的時鐘,這...