新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > I2C總線(xiàn)協(xié)議學(xué)習(xí)筆記

I2C總線(xiàn)協(xié)議學(xué)習(xí)筆記

作者: 時(shí)間:2016-12-15 來(lái)源:網(wǎng)絡(luò) 收藏
1.I2C協(xié)議
2條雙向串行線(xiàn),一條數(shù)據(jù)線(xiàn)SDA,一條時(shí)鐘線(xiàn)SCL。
SDA傳輸數(shù)據(jù)是大端傳輸,每次傳輸8bit,即一字節(jié)。
支持多主控(multimastering),任何時(shí)間點(diǎn)只能有一個(gè)主控。
總線(xiàn)上每個(gè)設(shè)備都有自己的一個(gè)addr,共7個(gè)bit,廣播地址全0.
系統(tǒng)中可能有多個(gè)同種芯片,為此addr分為固定部分和可編程部份,細(xì)節(jié)視芯片而定,看datasheet。

1.1 I2C位傳輸
數(shù)據(jù)傳輸:SCL為高電平時(shí),SDA線(xiàn)若保持穩(wěn)定,那么SDA上是在傳輸數(shù)據(jù)bit;
若SDA發(fā)生跳變,則用來(lái)表示一個(gè)會(huì)話(huà)的開(kāi)始或結(jié)束(后面講)
數(shù)據(jù)改變:SCL為低電平時(shí),SDA線(xiàn)才能改變傳輸?shù)腷it
1.2 I2C開(kāi)始和結(jié)束信號(hào)
開(kāi)始信號(hào):SCL為高電平時(shí),SDA由高電平向低電平跳變,開(kāi)始傳送數(shù)據(jù)。
結(jié)束信號(hào):SCL為高電平時(shí),SDA由低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)。

本文引用地址:http://m.butianyuan.cn/article/201612/330523.htm

1.3 I2C應(yīng)答信號(hào)

Master每發(fā)送完8bit數(shù)據(jù)后等待Slave的ACK。
即在第9個(gè)clock,若從IC發(fā)ACK,SDA會(huì)被拉低。
若沒(méi)有ACK,SDA會(huì)被置高,這會(huì)引起Master發(fā)生RESTART或STOP流程,如下所示:
1.4 I2C寫(xiě)流程
寫(xiě)寄存器的標(biāo)準(zhǔn)流程為:
1. Master發(fā)起START
2. Master發(fā)送I2C addr(7bit)和w操作0(1bit),等待ACK
3. Slave發(fā)送ACK
4. Master發(fā)送reg addr(8bit),等待ACK
5. Slave發(fā)送ACK
6. Master發(fā)送data(8bit),即要寫(xiě)入寄存器中的數(shù)據(jù),等待ACK
7. Slave發(fā)送ACK
8. 第6步和第7步可以重復(fù)多次,即順序?qū)懚鄠€(gè)寄存器
9. Master發(fā)起STOP

寫(xiě)一個(gè)寄存器
寫(xiě)多個(gè)寄存器
1.5 I2C讀流程

讀寄存器的標(biāo)準(zhǔn)流程為:
1. Master發(fā)送I2C addr(7bit)和w操作1(1bit),等待ACK
2. Slave發(fā)送ACK
3. Master發(fā)送reg addr(8bit),等待ACK
4. Slave發(fā)送ACK
5. Master發(fā)起START
6. Master發(fā)送I2C addr(7bit)和r操作1(1bit),等待ACK
7. Slave發(fā)送ACK
8. Slave發(fā)送data(8bit),即寄存器里的值
9. Master發(fā)送ACK
10. 第8步和第9步可以重復(fù)多次,即順序讀多個(gè)寄存器

讀一個(gè)寄存器
讀多個(gè)寄存器
2. PowerPC的I2C實(shí)現(xiàn)

Mpc8560的CCSR中控制I2C的寄存器共有6個(gè)。

2.1 I2CADR 地址寄存器

CPU也可以是I2C的Slave,CPU的I2C地址有 I2CADR指定
2.2 I2CFDR 頻率設(shè)置寄存器
The serial bit clock frequency of SCL is equal to the CCB clock divided by the divider.
用來(lái)設(shè)置I2C總線(xiàn)頻率

2.3 I2CCR 控制寄存器

MEN: Module Enable. 置1時(shí),I2C模塊使能
MIEN:Module Interrupt Enable. 置1時(shí),I2C中斷使能。
MSTA:Master/slave mode. 1 Master mode,0 Slave mode.
當(dāng)1->0時(shí),CPU發(fā)起STOP信號(hào)
當(dāng)0->1時(shí),CPU發(fā)起START信號(hào)
MTX:Transmit/receive mode select.0 Receive mode,1 Transmit mode
TXAK:Transfer acknowledge. 置1時(shí),CPU在9th clock發(fā)送ACK拉低SDA
RSTA:Repeat START. 置1時(shí),CPU發(fā)送REPEAT START
BCST:置1,CPU接收廣播信息(信息的slave addr為7個(gè)0)

2.4 I2CSR 狀態(tài)寄存器
MCF:0 Byte transfer is in process
1 Byte transfer is completed

MAAS:當(dāng)CPU作為Slave時(shí),若I2CDR與會(huì)話(huà)中Slaveaddr匹配,此bit被置1

MBB:0 I2C bus idle
1 I2C bus busy

MAL:若置1,表示仲裁失敗
BCSTM:若置1,表示接收到廣播信息

SRW:When MAAS is set, SRW indicates the value of the R/W command bit of the calling address, which is sent from the master.
0 Slave receive, master writing to slave
1 Slave transmit, master reading from slave

MIF:Module interrupt. The MIF bit is set when an interrupt is pending, causing a processor interrupt request(provided I2CCR[MIEN] is set)

RXAK:若置1,表示收到了ACK

2.5 I2CDR 數(shù)據(jù)寄存器

這個(gè)寄存器儲(chǔ)存CPU將要傳輸?shù)臄?shù)據(jù)。

3. PPC-Linux中I2C的實(shí)現(xiàn)

內(nèi)核代碼中,通過(guò)I2C總線(xiàn)存取寄存器的函數(shù)都在文件drivers/i2c/busses/i2c-mpc.c中
最重要的函數(shù)是mpc_xfer.

  1. static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)

  2. {

  3. struct i2c_msg *pmsg;

  4. int i;

  5. int ret = 0;

  6. unsigned long orig_jiffies = jiffies;

  7. struct mpc_i2c *i2c = i2c_get_adapdata(adap);


  8. mpc_i2c_start(i2c); // 設(shè)置I2CCR[MEN], 使能I2C module



  9. //一直讀I2CSR[MBB],等待I2C總線(xiàn)空閑下來(lái)

  10. while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) {

  11. if (signal_pending(current)) {

  12. pr_debug("I2C: Interruptedn");

  13. writeccr(i2c, 0);

  14. return -EINTR;

  15. }

  16. if (time_after(jiffies, orig_jiffies + HZ)) {

  17. pr_debug("I2C: timeoutn");

  18. if (readb(i2c->base + MPC_I2C_SR) ==

  19. (CSR_MCF | CSR_MBB | CSR_RXAK))

  20. mpc_i2c_fixup(i2c);

  21. return -EIO;

  22. }

  23. schedule();

  24. }


  25. for (i = 0; ret >= 0 && i < num; i++) {

  26. pmsg = &msgs[i];

  27. pr_debug("Doing %s %d bytes to 0xx - %d of %d messagesn",

  28. pmsg->flags & I2C_M_RD ? "read" : "write",

  29. pmsg->len, pmsg->addr, i + 1, num);
  30. //根據(jù)消息里的flag進(jìn)行讀操作或?qū)懖僮?/li>
  31. if (pmsg->flags & I2C_M_RD)

  32. ret = mpc_read(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);

  33. else

  34. ret = mpc_write(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);

  35. }

  36. mpc_i2c_stop(i2c); //保證為I2CCSR[MSTA]為0,保證能觸發(fā)STOP

  37. return (ret < 0) ? ret : num;

  38. }

上一頁(yè) 1 2 下一頁(yè)

評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉