IIC 總線接口
IIC 總線簡介
I IIC 總線接口特性
1.單片機串行接口的發(fā)送和接收一般都各用一條線,如的TXD 和RXD,而I 2.當某個器件向總線上發(fā)送信息時,它就是發(fā)送器(也叫主器件),而當其從總線上接收信息時,又成為接收器(也叫從器件)。 3.主器件用于啟動總線上傳送數據并產生時鐘以開放傳送的器件,此時任何被尋址的器件均被認為是從器件。I 4.總線上主和從(即發(fā)送和接收)的關系不是一成不變的,而是取決于此時數據傳送的方向。 5.I 6.在I 7.當所有器件的時鐘信號都上跳為高電平時,低電平期結束,SCL 線被釋放返回高電平,即所有的器件都同時開始它們的高電平期。其后,第一個結束高電平期的器件又將SCL 線拉成低電平。這樣就在SCL 線上產生一個同步時鐘??梢姡瑫r鐘低電平時間由時鐘低電平期最長的器件確定,而時鐘高電平時間由時鐘高電平期最短的器件確定。 8.在I 9.當時鐘線SCL 為高電平時,數據線SDA 由高電平跳變?yōu)榈碗娖蕉x為“開始”信號; 10.當SCL 線為高電平時,SDA 線發(fā)生低電平到高電平的跳變?yōu)?/SPAN>“結束”信號。 11.開始和結束信號都是由主器件產生。 12.在開始信號以后,總線即被認為處于忙狀態(tài);在結束信號以后的一段時間內,總線被認為是空閑的。 IIC 總線數據傳送格式
1.在I (1) 其中前7 位為地址碼; (2) 第8 位為方向位(R/W)。方向位為“ 2. 在I 為了完成一個字節(jié)的傳輸,接收方應該向發(fā)送方發(fā)送一個ACK位。ACK應該發(fā)生在SCL線的第九個脈沖期間。當接受到ACK信號時,發(fā)送方應該釋放SDA線使SDA線電平為高。接收方應該驅動SDA線為低在ACK脈沖過程中。因此,在第九個SCL脈沖的高電平期間SDA保持為低(因為信號是“與”的)。ACK的傳輸可以由軟件通過IICSTAT寄存器控制是否禁止,但它仍然是需要產生的。 IIC 總線數據傳送過程
1.每次都是先傳最高位,通常從器件在接收到每個字節(jié)后都會做出響應,即釋放SCL線返回高電平,準備接收下一個數據字節(jié),主器件可繼續(xù)傳送。 2.如果從器件正在處理一個實時事件而不能接收數據時,(例如正在處理一個內部中斷,在這個中斷處理完之前就不能接收I 讀寫操作
在發(fā)送模式下,當一個數據傳輸時,IIC總線接口將等待直到IICDS寄存器收到一個新數據。在一個新數據寫入IICDS寄存器前,SCL信號將保持為低。在數據被寫入之后,信號線被釋放(為高)。ARM需要保持中斷信號來辨別當前數據發(fā)送完成。在ARM接到一個中斷請求后,它將寫一個新的數據到IICDS。 在接收模式下,當一個數據接收時,IIC總線接口將等待直到IICDS寄存器數據被讀出。在新數據被讀出之前,SCL信號保持為低。在數據被讀出后,信號線被釋放(為高)。ARM應保持中斷信號以辨別接收數據操作完成。在ARM收到一個中斷請求時,它將從IICDS讀出數據。 IIC 總線競爭和仲裁機制
1. 總線上可能掛接有多個器件,有時會發(fā)生兩個或多個主器件同時想占用總線的情 況。 2. I 3. 其仲裁原則為:當多個主器件同時想占用總線時,如果某個主器件發(fā)送高電平, 而另一個主器件發(fā)送低電平,則發(fā)送電平與此時SDA 總線電平不符的那個器件將 自動關閉其輸出級。 IIC 總線工作流程
開始:信號表明傳輸開始。 地址:主設備發(fā)送地址信息,包含7 位的從設備地址和1 位的指示位(表明讀或者寫,即數據流的方向)。 數據:根據指示位,數據在主設備和從設備之間傳輸。數據一般以8 位傳輸,最重要的位放在前面;具體能傳輸多少量的數據并沒有限制。接收器上用一位的ACK 表明每一個字節(jié)都收到了。傳輸可以被終止和重新開始。 停止:信號結束傳輸。 S
|
|
Register |
Address |
R/W |
Description |
Reset Value |
|
IICCON |
0x54000000 |
R/W |
總線控制寄存器 |
0x0X |
|
IICCON |
Bit |
Description |
|
|
Acknowledge generation (note 1) |
[7] |
IIC總線確認位使能 0 = 禁止, 1 =使能 在Tx模式,IICSDA在確認時間內是任意的,在Rx 模式中= IICSDA 在確認時間內是低 |
0 |
|
Tx clock source selection |
[6] |
IIC總線傳輸時間對于資源時間的分頻位 0 = IICCLK = fPCLK /16 1 = IICCLK = fPCLK /512 |
0 |
|
Tx/Rx Interrupt (note 5) |
[5] |
IIC總線 Tx/Rx中斷使能/禁止位 0 = Disable, 1 = Enable |
0 |
|
Interrupt pending flag (note 2), (note 3) |
[4] |
IIC總線Tx/Rx中斷未決標志位. 該位不能被寫為1,當該位讀為1的時候,IICSCL信號為低并且IIC停止,要恢復操作,只需將該位清零 0 = 1) 沒有中斷未決(讀)2)清除未決狀態(tài) &恢復操作 (寫). 1 = 1) 中斷未決(讀) 2) N/A (寫) |
0 |
|
Transmit clock value (note 4) |
[3:0] |
IIC總線傳輸時鐘預分頻 IIC總線傳輸時鐘頻率由這個四位的值決定,由下列公式決定 Tx clock =IICCLK/(IICCON[3:0]+1). |
未定義 |
注意:
1.下面的幾種情況將產生一個IIC 中斷:
1) 當一個字節(jié)傳輸或接受操作完成的時 ;
2) 一個普通調用或一個從地址匹配產生時;
3) 總線仲裁失敗時;
2. 為了在IISSCL信號的上升沿之前調整IICSDA的設置時間,IICDS必須要在IIC的中斷位清零之前寫入。
3.IICLK 由IICCON[6]決定;
Tx時鐘會因為SCL時間的轉換而改變
IIC 狀態(tài)寄存器(IICSTAT)
|
Register |
Address |
R/W |
Description |
Reset Value |
|
IICSTAT |
0x54000004 |
R/W |
IIC總線狀態(tài)寄存器 |
0x0 |
|
IICSTAT |
Bit |
Description |
|
|
Mode selection |
[7:6] |
IIC總線主/從 Tx/Rx模式選擇位. 00: 從設備接受模式 01: 從設備發(fā)送模式 10: 主設備接受模式 11: 主設備發(fā)送模式 |
00 |
|
Busy signal status / START STOP condition |
[5] |
IIC總線忙信號狀態(tài)位 0 = 讀) 空閑 寫) STOP 信號產生 1 = 讀) 忙 寫) START信號產生. IICDS中的數據在START信號后自動傳輸 |
|
|
Serial output |
[4] |
IIC總線數據輸出使能/禁止位 0 =禁止 Rx/Tx, 1 = 使能 Rx/Tx |
0 |
|
Arbitration status flag |
[3] |
IIC總線過程仲裁狀態(tài)位 0 =總線仲裁成功 1 = 在連續(xù)I/O 中總線仲裁失敗 |
0 |
|
Address-as-slave status flag |
[2] |
IIC總線從地址狀態(tài)標志位. 0 = 當START/STOP信號探測到時清零 1 =接收到的slave地址匹配IICADD的值 |
0 |
|
Address zero status flag |
[1] |
IIC總線地址零狀態(tài)標志位 0 =當START/STOP信號探測到時清零. 1 =接收到的從地址為 00000000b. |
0 |
|
Last-received bit status flag |
[0] |
IIC總線IIC-bus上一次接收到的狀態(tài)標志位. 0 =上一次接收到的位是0 (ACK was received). 1 =上一次接收到的位是1 (ACK was not received). |
0 |
地址寄存器(IICADD)
|
Register |
Address |
R/W |
Description |
Reset Value |
|
IICADD |
0x54000008 |
R/W |
IIC總線地址寄存器 |
0xXX |
|
IICADD |
Bit |
Description |
|
|
Slave address |
[7:0] |
7位從地址,從IIC總線中鎖存 |
XXXXXXXX |
|
|
|
當IICSTAT 串行輸出允許為0,IICADD 為寫允許的時候 |
|
|
|
|
IICADD的值可以在任何時候被讀取, 而不用管當前串行 |
|
|
|
|
輸出允許位(IICSTAT)的設置 |
|
|
|
|
從地址 = [7:1] |
|
|
|
|
Not mapped = [0] |
|
移位數據寄存器(IICDS)
|
Register |
Address |
R/W |
Description |
Reset Value |
|
IICDS |
0x |
R/W |
IIC總線移位數據寄存器 |
0xXX |
|
IICDS |
Bit |
Description |
|
|
Data shift |
[7:0] |
IIC總線Tx/Rx 操作的8位移位寄存器 |
XXXXXXXX |
|
|
|
當IICSTAT 串行輸出允許為1,IICADD 為寫允許的時候 |
|
|
|
|
IICDS的值可以在任何時候被讀取, 而不用管當前串行輸 |
|
|
|
|
出允許位(IICSTAT)的設置. |
|
根據前面的原理介紹,編寫一個程序來實現IIC的讀寫操作。
1. 閱讀相關原理介紹,了解IIC協議發(fā)送和接收的基本過程。
2. 閱讀本實驗的源代碼,更深層次理解IIC的實現細節(jié),時序要求等。
3. 自己動手編寫一個程序來實現IIC的讀寫操作。
主函數Main
#include "2410header.h"
#include "2410IIC.h"
void
{
sysinit(); //系統初始化代碼,主要完成串口的初始化工作
Delay(0); //calibrate Delay()
Uart_Printf("IIC Test Pol:\n"); //串口打印數據
while (1)
{
Test_Iic2(); //IIC測試程序
Delay(1000);
Uart_Printf("\n\nPress Any Key To Continue\n\n");
Uart_Getch();
}
}
測試函數Test_Iic2
void Test_Iic2(void)
{
unsigned int i,j,save_E,save_PE;
static U8 data[256];
Uart_Printf("[ IIC Test(Polling) using KS
save_E = rGPECON; //保存寄存器的原來的值,等程序結束后恢復原值。
save_PE = rGPEUP;
rGPEUP |= 0xc000; //上拉禁止
rGPECON |= 0xa00000; //GPE15:IICSDA , GPE14:IICSCL
//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);
rIICADD = 0x10; //2410 slave address = [7:1]
rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
Uart_Printf("\nWrite test data into KS
for(i=0;i<256;i++)
_Wr
for(i=0;i<256;i++)
data[i] = 0; //初始化數組的值為0,
Uart_Printf("\nRead test data from KS
for(i=0;i<256;i++)
_Rd
for(i=0;i<16;i++)
{
for(j=0;j<16;j++)
Uart_Printf("%2x ",data[i*16+j]);
Uart_Printf("\n");
}
Uart_Printf("\nWrite test data into KS
for(i=0;i<256;i++)
_Wr
for(i=0;i<256;i++)
data[i] = 0;
Uart_Printf("\nRead test data from KS
for(i=0;i<256;i++)
_Rd
for(i=0;i<16;i++)
{
for(j=0;j<16;j++)
Uart_Printf("%2x ",data[i*16+j]);
Uart_Printf("\n");
}
Uart_Printf("\nWrite test data into KS
for(i=0;i<256;i++)
_Wr
for(i=0;i<256;i++)
data[i] = 0;
Uart_Printf("\nRead test data from KS
for(i=0;i<256;i++)
_Rd
for(i=0;i<16;i++)
{
for(j=0;j<16;j++)
Uart_Printf("%2x ",data[i*16+j]);
Uart_Printf("\n");
}
Uart_Printf("\nWrite test data into KS
for(i=0;i<256;i++)
_Wr
for(i=0;i<256;i++)
data[i] = 0;
Uart_Printf("\nRead test data from KS
for(i=0;i<256;i++)
_Rd
for(i=0;i<16;i++)
{
for(j=0;j<16;j++)
Uart_Printf("%2x ",data[i*16+j]);
Uart_Printf("\n");
}
rGPEUP = save_PE;
rGPECON = save_E;
}
寫EEPROM函數_Wr
void _Wr
{
_iicMode = WRDATA;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicData[1] = data;
_iicDataCount = 2;
rIICDS = slvAddr; //0xa0
//Master Tx mode, Start(Write), IIC-bus data output enable
//Bus arbitration sucessful, Address as slave status flag Cleared,
//Address zero status flag cleared, Last received bit is 0
rIICSTAT = 0xf0;
//Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1)
Run_IicPoll();
_iicMode = POLLACK;
while(1)
{
rIICDS = slvAddr;
_iicStatus = 0x100; //To check if _iicStatus is changed
rIICSTAT = 0xf0; //Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0
rIICCON = 0xaf; //Resumes IIC operation.
while(_iicStatus==0x100)
Run_IicPoll();
if(!(_iicStatus & 0x1))
break; //When ACK is received
}
rIICSTAT = 0xd0; //Master Tx condition, Stop(Write), Output Enable
rIICCON = 0xaf; //Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
//Write is completed.
}
讀EEPROM函數_Rd
void _Rd
{
_iicMode = SETRDADDR;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicDataCount = 1;
rIICDS = slvAddr;
rIICSTAT = 0xf0; //MasTx,Start
//Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1)
Run_IicPoll();
_iicMode = RDDATA;
_iicPt = 0;
_iicDataCount = 1;
rIICDS = slvAddr;
rIICSTAT = 0xb0; //Master Rx,Start
rIICCON = 0xaf; //Resumes IIC operation.
while(_iicDataCount!=-1)
Run_IicPoll();
*data = _iicData[1];
}
|
|