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序列時鐘輸入管腳用於產生器件所有資料傳送或接收的時鐘,這...