SM39R 系列IIC 使用說明

IIC 使用說明
SM39R 系列 IIC 使用說明
1
適用產品:
1.1 SM39R02A2/ SM39R04A2
1.2 SM39R2051G1/ SM39R4051G1
1.3 SM39R08A2/ SM39R12A2/ SM39R16A2
2
IIC 使用概述:
2.1 使用硬件 SCL (clock)及 SDA (data)管腳,須接上拉電阻,建議 2K~10KΩ。
2.2 速度:SCL 最高可達 400Kbps(由軟件設定 SFR IICBR[2:0])。
2.3 IIC 和 ICE 內部使用同一電路,所以使用 IIC 功能和 ICE 模擬不可同時使用。
2.4 IIC 可選擇 master 或 slave 兩種模式,提供中斷(RXIF, TXIF, MPIF)及兩組控制位址(IICA1, IICA2)
使用。
2.5 Master 硬件可自動產生 IIC 的啓動(START)、重新啓動(Re-START)及停止(STOP)信號,自動偵
測 bus busy(BB flag)及 arbitration(LAIF)。
2.6 Slave 硬件可偵測 IIC 的 START(Match)、Re-START(Match)及 STOP(MPIF)信號。
2.7 Slave 最多可接 127 devices,線材電容量最高限制為 400pF。
3
IIC 相關的特殊暫存器 Special Function Register (SFR)
Mnemonic
Description
Direct
Bit 7
AUX
IICCTL
Auxiliary register
IIC control register
91h
F9h
BRGS
IICEN
IICS
IIC status register
F8h
-
IICA1
IICA2
IICRWD
IICEBT
IIC Address 1
register
IIC Address 2
register
IIC Read/Write
register
IIC Enaable Bus
Transaction
Bit 6
Bit 5
Bit 4
IIC function
P2SPI
P2UR
MSS
MAS AB_EN
MPIF
LAIF
RXIF
FAh
IICA1[7:1]
FBh
IICA2[7:1]
FCh
FDh
Bit 3
Bit 2
P2IIC
BF_EN
-
TXIF
Bit 1
Bit 0
DPS
IICBR[2:0]
RW or
RXAK TXAK
BB
MATCH1
or RW1
MATCH2
or RW2
IICRWD[7:0]
FU_EN
-
-
-
RESET
00H
04H
00H
A0H
60H
00H
-
-
-
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
1
Ver A 2011/09
00H
IIC 使用說明
Mnemonic: AUX
7
6
5
BRGS
P2SPI
4
P2UR
3
P2IIC
2
-
1
-
Address: 91h
0
Reset
DPS
00H
P2IIC: P2IIC = 0 – IIC function on P1.
P2IIC = 1 – IIC function on P2.
P2IIC
0
1
SCL
P1.2
P2.6
SDA
P1.3
P2.7
IIC 腳位直接由軟件指定至 P1 或 P2,可避免和其它特殊功能腳位重複,提高硬件規劃的相容性。有此
功能的 MCU 如下表:
P4IIC(IIC function pin assignment)
MCU device
SM39R16A2/ SM39R12A2/ SM39R08A2
○
SM39R4051/ SM39R2051
X
SM39R04G1/ SM39R02G1
X
○:表示該型號可以使用 P2IIC 功能
X:表示該型號不可使用 P2IIC 功能
Mnemonic: IICCTL
7
6
5
IICEN
MSS
MAS
4
AB_EN
3
2
BF_EN
1
IICBR[2:0]
Address: F9h
0
Reset
04h
IICEN: IC 致能位元(Enable IIC module)
IICEN = 1,IIC 致能。
IICEN = 0,IIC 禁能。
MSS: 主從模式選擇位元 Master or slave mode select:
MSS = 1,設定為 master mode。
MSS = 0,設定為 slave mode。
*當使用 IIC 設定其它 IIC SFR 時,程序必須先致能此位元。
MAS: 控制位址位元 Master address select (master mode only):
MAS = 0 ,選擇控制位址(control byte)由 SFR IICA1 送出。
MAS = 1 ,選擇控制位址(control byte)由 SFR IICA2 送出。
AB_EN: 仲裁檢查致能位元 Arbitration lost enable bit. (Master mode only)
AB_EN = 1,致能仲裁檢查。
AB_EN = 0,禁能仲裁檢查,master不理會主控權丟失情況。
仲裁檢查:在multi-master架構,master由硬件送出SDA為”1”,卻偵測到為”0”時,即發生仲裁丟失,
失去對IIC bus的主控權(表示IIC bus上已有其它master正在通訊),LAIF將被設置為”1”。
當系統為多主從(multi-master)應用時,必須致能AB_EN,並檢查LAIF位元。
當系統為單主從(single-master)應用時,可禁能AB_EN。
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
2
Ver A 2011/09
IIC 使用說明
BF_EN: 匯流排忙碌偵測致能位元 Bus busy enable bit. (Master mode only)
BF_EN = 1,致能,若BF=1,master會無法送出啓動條件(Start condition),直到BF=0。
BF_EN = 0,禁能,master硬件不理會BF=0或1。
致能BF_EN時:
1.
當Master硬件偵測到啓動條件(Start condition),或BUS上的SCL=0、或SDA=0時,即為
bus busy狀態,BB會由硬件設為”1”。
2.
當Master硬件偵測到停止條件(Stop condition)後,BB由硬件清除為”0”。此位元也可由軟件
清除。
當系統為多主從(multi-master)應用時,必須致能BF_EN,並檢查BB(bus busy)位元。
當系統為單主從(single-master)應用時,可禁能BF_EN。
IICBR[2:0]: IIC 鮑率選擇元位 Baud rate selection (master mode only):
系統頻率(Fosc)依據 MCU 外部晶振(或內部晶振)而定,預設值為 Fosc/512 。
IICBR[2:0]
000
001
010
011
100
101
110
111
Mnemonic: IICS
7
6
MPIF
5
LAIF
Baud rate
Fosc/32
Fosc/64
Fosc/128
Fosc/256
Fosc/512
Fosc/1024
Fosc/2048
Fosc/4096
4
RXIF
3
TXIF
2
RXAK
1
TxAK
Address: F8H
0
Reset
RW or BB
00H
MPIF: 停止中斷旗標 Stop Interrupt Flag:
1.
master: 送出或偵測(multi-master)到stop condition時,MPIF會由HW設置為1,會
產生中斷,但與RxIF及TxIF無關。MPIF必須由軟件清除,或離開中斷時由HW清除。
2.
slave: 收到stop condition時,MPIF會由HW設置為1,但不產生中斷,MPIF必須由
軟件清除。
LAIF: 仲裁檢查旗標 Lost Arbitration bit. (Master mode only)
LAIF = 1,失去匯流排主控權 lost bus arbitration。
LAIF = 0,匯流排閒置 bus ready。
當系統為多主從(multi-master)應用時,請致能該偵測位元(AB_EN)。
當系統為單主從(single-master)應用時,可禁能該偵測位元(AB_EN)。
AB_EN = 1,致能仲裁檢查。
AB_EN = 0,禁能仲裁檢查,master不理會主控權丟失情況。
仲裁檢查:在multi-master架構,master由硬件送出SDA為”1”,卻偵測到為”0”時,即發生
仲裁丟失,失去對IIC bus的主控權(表示IIC bus上已有其它master正在通訊),LAIF將被設
置為”1”。
當系統為多主從(multi-master)應用時,必須致能AB_EN,並檢查LAIF位元。
當系統為單主從(single-master)應用時,可禁能AB_EN。
RxIF: 資料接收中斷旗標 Data receive interrupt flag
以下事件發生時 RxIF 會由硬件設為”1”,並發生中斷:
1. master mode: IICRWD 載入資料完成時。
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
3
Ver A 2011/09
IIC 使用說明
2. slave mode: IICRWD 載入資料完成時。
3. slave mode: Match (即 salve 收到 start condition 及 device ID)時。
RxIF必須由軟件清除。
TxIF: 資料傳送中斷旗標 Data transmit interrupt flag
以下事件發生時 TxIF 會由硬件設為”1”,並發生中斷:
1. master mode: 送出 start condition 及 device ID 時。
2. master mode: 資料從 IICRWD 載至位移暫存器,並已由位移暫存器傳送時。
3. slave mode: 資料從 IICRWD 載至位移暫存器,並已由位移暫存器傳送時。
TxIF必須由軟件清除。
RxAK: 接收應答位元 Receive acknowledgement (read only)
此為唯讀位元,傳送端等待接收端回覆應答(ACK/NACK),不可由程序編寫。
1. master mode:傳出資料(8-bit)後,由 slave 回覆應答位元(RxAK)。
2. slave mode:傳出資料(8-bit)後,由 master 回覆應答位元(RxAK)。
TxAK: 傳送應答位元 Transmit acknowledgement
接收端接收前必須先設定好 TxAK(ACK or NACK),接收資料完成後,即由硬件送出 TxAK
至傳送端。
RW or BB: Master Mode:
匯流排忙碌偵測位元 Bus busy bit
BB = 1,匯流排忙碌 bus busy。
BB = 0,匯流排閒置 bus ready。
致能BF_EN時:
1.
當Master硬件偵測到啓動條件(Start condition),或BUS上的SCL=0、或SDA=0時,
即為bus busy狀態,BB會由硬件設為”1”。
2.
當Master硬件偵測到停止條件(Stop condition)後,BB由硬件清除為”0”。此位元也可
由軟件清除。
當系統為多主從(multi-master)應用時,必須致能BF_EN,並檢查BB(bus busy)位元。
當系統為單主從(single-master)應用時,可禁能BF_EN。
Slave Mode:
讀寫狀態位元 Read or Write status bit(read only)
此位元由 master 的位址 IICA1(或 IICA2) 的 8th-bit 所控制:
RW = 0,master 要求 slave 的 IIC module 為接收模式(即 master write, slave read)。
RW = 1,master要求slave的IIC module為傳送模式(即master read, slave write)。
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
4
Ver A 2011/09
IIC 使用說明
Fig. Acknowledgement bit in the 9th bit of a byte transmission
Mnemonic: IICA1
7
6
5
4
IICA1[7:1]
R/W
3
2
1
Address: FAH
Reset
0
Match1 or RW1 A0H
R or R/W
Slave mode:
IICA1[7:1]: IIC Address registers
控制位址(第一組)IICA1 共 7-bit,須由軟件設定。
Match1: 當 slave 接收到 master 的啓動條件(Start or Re-Start condition),及控制位址(IICA1)7-bit,由硬
件比對:
= 1,當比對相同時,Match1 及 RxIF 皆由硬件設置為”1”,並產生中斷。
= 0,Match1 由硬件清除為”0”,如下情況:
1. RXIF 發生但未偵測到啓動條件(Start or Re-Start condition)。
2. TXIF 發生時。
Master mode:
IICA1[7:1]: IIC Address registers
1. 第一組控制位址 IICA1 共 7-bit,由軟件設定。
2. 當 MAS = 0,選擇控制位址第一組(IICA1)。
當 MAS = 1,選擇控制位址第二組(IICA2)。
3. 當 IICEBT 由軟件設置為”10”時,會送出啓動條件(Start or Re-Start condition)及控制位址位元
(IICA1)。
RW1: master 送出的 8th-bit(R/W-bit),告知 slave 讀寫的狀態
RW1= 1:為 master IIC module 接收模式(即 master read, slave write)。
RW1= 0:為 master IIC module 傳送模式(即 master write, slave read)。
Fig. : RW bit in the 8th bit after IIC address
Mnemonic: IICA2
7
6
5
Address: FBh
4
IICA2[7:1]
R/W
3
2
1
0
Match2 or RW2
R or R/W
Reset
60h
Slave mode:
IICA2[7:1]: IIC Address registers
控制位址(第二組)IICA2 共 7-bit,須由軟件設定。
Match2: 當 slave 接收到 master 的啓動條件(Start or Re-Start condition),及控制位址(IICA2)7-bit,由硬
件比對:
= 1,當比對相同時,Match2 及 RxIF 皆由硬件設置為”1”,並產生中斷。
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
5
Ver A 2011/09
IIC 使用說明
= 0,Match2 由硬件清除為”0”,如下情況:
1. RXIF 發生但未偵測到啓動條件(Start or Re-Start condition)。
2. TXIF 發生時。
Master mode:
IICA2[7:1]: IIC Address registers
1. 控制位址(第二組)IICA2 共 7-bit,由軟件設定。
2. 當 MAS = 0,選擇控制位址第一組(IICA1)。
當 MAS = 1,選擇控制位址第二組(IICA2)。
3. 當 IICEBT 由軟件設置為”10”時,會送出啓動條件(Start or Re-Start condition)及控制位址位元
(IICA2)。
RW2: master 送出的 8th-bit(R/W-bit),告知 slave 讀寫的狀態
RW2= 1:為 master IIC module 接收模式(即 master read, slave write)。
RW2= 0:為 master IIC module 傳送模式(即 master write, slave read)。
Mnemonic: IICRWD
7
6
5
4
3
IICRWD[7:0]
2
Address: FCh
0
Reset
00h
1
IICRWD[7:0]: 資料讀寫暫存器(8-bit) IIC read write data buffer:
1. IIC 接收時,IICRWD 為接收資料的暫存區;
當資料接收完成時 RxIF=1,再讀取 IICRWD,讀完後必須 release IIC bus(即 IICEBT 寫入”01”)。
2. IIC 傳送時,IICRWD 為傳送資料的暫存區;
先將資料寫入 IICRWD,再寫入 IIC 傳送指令(即 IICEBT 寫入”01”)即可,傳送完成時 TxIF=1。
Address: FDH
Mnemonic: IICEBT
7
6
5
-
FU_EN
Master
Mode
FU_EN[7:6]:
4
-
3
-
2
-
1
-
0
-
Reset
00H
FU_EN[7:6]
00
Reserved
01
Master transmit data 傳資料操作命令及流程:
1. Write data to IICRWD (by software)
2. FU_EN write 01 (by software)
3. Transmit data finish and receive RxAK when FU_EN
auto-clear (by HW)
4. TxIF will set (by HW) then interrupt occur, TxIF must clear
(by software)
5. Check RxAK status
EX:
IICRWD=TxData;
// load data
IICEBT=0x40;
// trans. data
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
6
Ver A 2011/09
IIC 使用說明
while(IICEBT != 0x00);// waiting data trans. Finish
while(TxIF=0);
TxIF=0;
if(RxAK)
{
// by user…
}
else
{
// by user…
}
Master receive data 收資料操作命令及流程:
1. TxAK set ACK/NACK before receive data (by software)
2. FU_EN write 01(by software) for release bus
3. Receive data finish and transmit TxAK when FU_EN
auto-clear (by HW)
4. RxIF will set (by HW) then interrupt occur
5. User can read data from IICRWD (by software)
6. RxIF must clear (by software)
Ex:
TXAK=ACKStatus; // Feedback ACK/d_NACK to slave
IICEBT=0x40;
// Ready for receive
while(IICEBT != 0x00);// waiting data recive finish
while(RxIF=0);
RxIF=0;
temp=IICRWD;
10
送出啓動條件(Start or Re-Start condition)及控制位址位元
(IICA1/IICA2)
Ex:
IICEBT = 0x80;
// generate a start condition
while(IICEBT != 0x00);
return RXAK;
11
送出停止條件(Stop condition)
IIC bus module generate a stop condition on the SDA/SCL.
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
7
Ver A 2011/09
IIC 使用說明
EX:
IICEBT = 0xC0;
// generate a stop condition
while(IICEBT != 0x00);// waiting data recive finish
Notice:
在此僅作簡易的程序示範,完整程序可參考”完整範例程序”的master及slave,或使用SyncMOS
Codzard產生。
Slave Slave transmit data 傳資料操作命令及流程(同 master):
mode: 1. Write data to IICRWD (by software)
2. FU_EN write 01 (by software)
3. Transmit data finish and receive RxAK when FU_EN auto-clear (by HW)
4. TxIF will set (by HW) then interrupt occur, TxIF must clear (by software)
Slave receive data 收資料操作命令及流程(不同於 master):
1. TxAK set ACK before receive data (by software)
2. Receive data finish and transmit TxAK when IICEBT auto-clear (by HW)
3. RxIF will set (by HW) then interrupt occur
4. User can read data from IICRWD (by software)
5. FU_EN write 01(by software) for release bus
6. RxIF must clear (by software)
Slave receive Start or Re-Start condition 操作命令及流程:
1. TxAK set ACK before match (by software)
2. Transmit TxAK when device ID match
3. RxIF will set (by HW) then interrupt occur
4. User can read data from IICRWD (by software)
5. FU_EN write 01(by software) for release bus
6. RxIF must clear (by software)
void IIC_interrupt() interrupt d_IIC_Vector
{
unsigned char buf;
//slave rx===========================================================
if(RXIF)
{
//=======================================================
if ((IICA1 & 0x01) || (IICA2 & 0x01))
// match
{
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
8
Ver A 2011/09
IIC 使用說明
if (n_RW == d_Write)
IICEBT = d_CMD_RW;
// don't release if read phase
// IIC bus release if write phase
}
//=======================================================
else
{
buf
= IICRWD;
// save addr offset
IICEBT
= 0x40;
// IIC bus release
}
//=======================================================
RXIF = 0;
}
//slave tx===========================================================
if (TXIF)
{
TXIF = 0;
// Clear interrupt flag
}
//===================================================================
}
Notice:
1. Slave只須設定FU_EN[7:6] =[ 0 1] (當作Release BUS的功能 ),其它值不可設定。
2. 如果沒release,IIC SCL會被lock住(=0)。
3. 在此僅作簡易的程序示範,完整程序可參考”完整範例程序”的master及slave,或使用SyncMOS
Codzard產生。
4
IIC 中斷
4.1 向量表(Interrupt vectors table)
Interrupt Vector
Address
0003h
Interrupt Number
*(use Keil C Tool)
0
TF0 – Timer 0 interrupt
000Bh
1
IE1 – External interrupt 1
0013h
2
TF1 – Timer 1 interrupt
001Bh
3
RI0/TI0 – Serial channel 0 interrupt
TF2/EXF2 – Timer 2 interrupt
(SM39R16A2/ SM39R12A2/ SM39R08A2 only)
PWMIF – PWM interrupt
(SM39R16A2/ SM39R12A2/ SM39R08A2 only)
SPIIF – SPI interrupt
0023h
4
002Bh
5
0043h
8
004Bh
9
ADCIF – A/D converter interrupt
0053h
10
KBIIF – keyboard Interface interrupt
005Bh
11
LVIIF – Low Voltage Interrupt
0063h
12
IICIF – IIC interrupt
006Bh
13
Interrupt Request Flags
IE0 – External interrupt 0
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
9
Ver A 2011/09
IIC 使用說明
RI1/TI1 – Serial channel 1 interrupt
Comparator interrupt
(SM39R16A2/ SM39R12A2/ SM39R08A2 only)
0083h
16
0093h
18
*See Keil C about C51 User’s Guide about Interrupt Function description
4.2 中斷相關暫存器(Interrupt SFR)
Mnemonic
IEN0
IEN1
IEN2
IRCON
IRCON2
IP0
IP1
Description
Interrupt Enable 0
register
Interrupt Enable 1
register
Interrupt Enable 2
register
Interrupt request
register
Interrupt request
register 2
Interrupt priority
level 0
Interrupt priority
level 1
Direct
Bit 7
Bit 6
A8H
EA
-
B8H
EXEN2
9AH
Bit 5
Interrupt
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
RESET
ET2
ES
ET1
EX1
ET0
EX0
00H
-
IEIIC
IELVI
IEKBI
IEADC
IESPI
IEPWM
00H
-
-
-
-
-
ECmpI
-
-
00H
C0H
EXF2
TF2
IICIF
LVIIF
KBIIF
ADCIF
SPIIF
PWMIF
00H
97H
-
-
-
-
-
CmpIF
-
-
00H
A9H
-
-
IP0.5
IP0.4
IP0.3
IP0.2
IP0.1
IP0.0
00H
B9H
-
-
IP1.5
IP1.4
IP1.3
IP1.2
IP1.1
IP1.0
00H
IIC 中斷應用可參考以下設定:
(1) IIC 中斷致能設定:
IEN0 |= 0x80;
//Enable interrupt All
IEN1 |= 0x20;
//Enable interrupt IIC
(2) IIC 中斷程序表示:
void ISR_IIC (void) interrupt 13
{
if(TXIF)
{
TXIF = 0;//Clear interrupt flag
}
if(RXIF)
{
RXIF = 0;//Clear interrupt flag
}
if(MPIF)
{
MPIF = 0;//Clear interrupt flag
}
}
Ps. IIC 中斷發生,必須清除 IICS 的 TXIF 或 RXIF 或 MPIF,而非 IRCON 的 IICIF!
5
以下使用兩顆 MCU,分別做為 master 及 slave,以最普遍使用的 EEPROM 24Cxx 做為通訊 protocal
來說明 IIC 應用:
5.1 MCU IIC flag 狀態圖(IIC Page Write):
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
10
Ver A 2011/09
IIC 使用說明
Master:
Slave:
• M1. FU_EN寫入10,Master送出Start、Device ID及RW訊號。 • S1. S1. 當slave硬件偵測到Start condition及device ID,
Match bit由硬件設為1。
• M2. 送出完成時,FU_EN由硬件清為零,TxIF由硬體設置為
1,並產生中斷,TxIF由軟體清除。時也需判斷RxAK的狀態。 •
S2. 收到Device ID(及RW)時,硬件會傳出TxAK;RxIF會
由硬件設為1,並觸發中斷,軟件必須寫FU_EN=01,用來
release bus。
•
•
M3. Data寫入IICRWD後, FU_EN寫入01,即會將Data送出。
M4. Data送出後,FU_EN由硬件清為零,TxIF由軟件設置為
1,並產生中斷。
•
•
M5. FU_EN寫入11,送出Stop訊號,後MPIF由硬件設為1,
並產生中斷。
S3. 收到Data時,硬件會傳出TxAK;RxIF會由硬件設為1,
並觸發中斷,軟件必須寫FU_EN=01,用來release bus。
•
S4. 在收到Stop condition後,MPIF由硬件設為1,MPIF須
由軟體清除為0。
5.2 MCU IIC flag 狀態圖(IIC Random Read):
Master:
Slave:
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
11
Ver A 2011/09
IIC 使用說明
•
M1&M3. FU_EN寫入10h,Master送出Start(or
•
Re-Start)、Device ID及RW訊號。收到ACK後FU_EN由硬
件清除,並觸發TxIF。
•
•
bit由硬件設為1。
•
S2. 收到Device ID(及RW)或Data,硬件會接著傳出TxAK;
M2. TX:將Data寫入IICRWD後,FU_EN寫入01h,即送
RxIF會由硬件設為1,並觸發中斷,軟件必須寫FU_EN=01,
出Data。收到ACK後FU_EN由硬件清除,並觸發TxIF。
用來release bus。
M4. RX:FU_EN寫入01h後,SCL開始送出CLK,並將Data
•
收進IICRWD,收到ACK後FU_EN由硬件清除,並觸發
RxIF及中斷。
•
S1. 當slave硬件偵測到Start condition及device ID,Match
送出。
•
M5. Stop:FU_EN寫入11h後,送出Stop,收到ACK後
FU_EN由硬件清除,並觸發MSIF及中斷。
S3. 每次Data寫入IICRWD後,FU_EN寫入01,即會將Data
S4. 每次Data完成送出後,FU_EN由硬件清除為0,TxIF由
硬體設置為1,並觸發中斷,TxIF須由軟體清除為0。
•
S5. 當收到N-ACK時,Slave即停止Data回傳。在收到Stop
condition,MPIF由硬件設為1,MPIF須由軟體清除為0。
5.3 MCU IIC 完整範例程序(master):
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
12
Ver A 2011/09
IIC 使用說明
MCU master w/r EEPROM(24cxx):
Description
Main program
//========================================================================
//
//
S Y N C M O S T E C H N O L O G Y
//
//========================================================================
#include "SM39R16A2.h"
#include "IIC.h"
//===============================
//IIC DEFINITIONs
//===============================
#define d_DEVICE_ID1
0x60
#define d_DEVICE_ID2
0xA0
// user modify
// user modify
#define d_IIC_ADR_CA1
#define d_IIC_ADR_CA2
#define d_IIC_ADR_SEL
// user modify, Device ID select
0x00
0x20
d_IIC_ADR_CA1
#define
#define
#define
#define
#define
#define
#define
#define
#define
d_BR32
d_BR64
d_BR128
d_BR256
d_BR512
d_BR1024
d_BR2048
d_BR4096
d_IIC_BR
0x00
0x01
0x02
0x03
0x04
#define
#define
#define
#define
#define
#define
#define
#define
d_MASTER
d_SLAVE
d_MODE_SEL
d_IIC_EN
d_NACK
d_ACK
d_WRITE
d_READ
0x40
#define
#define
#define
#define
#define
#define
d_BB_DIS
d_BB_EN
d_BUS_BUSY
d_AR_DIS
d_AR_EN
d_ARBITRATION
0x00
#define
#define
#define
d_CMD_RW
d_CMD_Start
d_CMD_Stop
0x05
0x06
0x07
d_BR32
0x00
d_MASTER
// user modify
//691.2->588
// use master mode
0x80
1
0
0
1
0x08
d_BB_EN
0x00
0x10
d_AR_EN
0x40
0x80
0xC0
//===============================================================
//OWNED SUBROUTINES
//===============================================================
void IIC_interrupt(void) interrupt d_IIC_Vector
{
if(TXIF)
{
TXIF = 0;
// Clear interrupt flag
}
if(RXIF)
{
RXIF = 0;
// Clear interrupt flag
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
13
Ver A 2011/09
IIC 使用說明
}
if(MPIF)
{
MPIF=0;
}
// Clear interrupt flag
}
void IIC_Init_master(void)
{
IICA1
= d_DEVICE_ID1;
IICA2
= d_DEVICE_ID2;
IICS = 0x00;
// Clear IIC all status
IEN0 |= 0x80;
// Enable interrupt All
IEN1 |= 0x20;
// Enable interrupt IIC
IICCTL
= d_IIC_EN | d_MODE_SEL | d_ARBITRATION | d_BUS_BUSY | d_IIC_ADR_SEL |
d_IIC_BR;
}
void IIC_Disable(void)
{
IICCTL
= 0x00;
IEN1 &= 0xDF;
IICS = 0x00;
}
// Disable IIC all function
// Disable interrupt IIC
// Clear IIC all status
//===============================================================
//This function will send out the Start or Re-Start pulse and CONTROL byte.
//===============================================================
bit IIC_SendStart(unsigned char ControlByte)
{
IICA2
= ControlByte;
// MAS = 1
IICA1
= ControlByte;
// MAS = 0
IICEBT = d_CMD_Start;
while(IICEBT != 0x00)
{
;
}
return RXAK;
// generate a start condition
}
//===============================================================
//This function will send out the Stop pulse
//===============================================================
void IIC_SendStop(void)
{
IICEBT = d_CMD_Stop;
// generate a stop condition
while(IICEBT != 0x00)
// waiting data recive finish
{
;
}
}
//===============================================================
//This function will wait and receive one byte, then feedback ACK or NACK.
//===============================================================
unsigned char IIC_ReceiveByte(bit ACKStatus)
{
unsigned char temp;
TXAK = ACKStatus;
// Feedback ACK/d_NACK to slave
IICEBT
= d_CMD_RW;
// Ready for receive
while(IICEBT != 0x00)
// waiting data recive finish
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
14
Ver A 2011/09
IIC 使用說明
{
;
}
temp = IICRWD;
//Delay(100);
return(temp);
// finetune by user
}
void IIC_TransmitByte(unsigned char TxData)
{
IICRWD
= TxData;
// load data
IICEBT
= d_CMD_RW;
// trans. data
while(IICEBT != 0x00)
// waiting data trans. finish
{
;
}
//Delay(100);
// finetune by user
}
void IIC_Page_Write( char Crtl_byte, unsigned char Addr, char LEN)
{
unsigned char counter=0;
IIC_SendStart(Crtl_byte | d_WRITE);
// -- Send CONTROL byte --
if(RXAK==d_ACK)
{
IIC_TransmitByte( Addr );
// -- Send ADDRESS --
for (counter=0; counter<LEN; counter++)
{
if(RXAK==d_ACK)
{
IIC_TransmitByte(Addr + counter);
}
else
{
;
}
// -- Write N bytes --
// -- Transmit one byte --
// error process
}
}
else
{
;
}
IIC_SendStop();
// error process
// -- Send STOP -- MStart= 0
}
void IIC_Random_Read( char Crtl_byte, unsigned char Addr, char LEN)
{
unsigned char Temp[16];
unsigned char counter=0;
IIC_SendStart(Crtl_byte | d_WRITE);
if(RXAK==d_ACK)
{
IIC_TransmitByte(Addr);
if(RXAK==d_ACK)
{
IIC_SendStart(Crtl_byte | d_READ);
// -- Send CONTROL byte --
// -- Send ADDRESS --
// -- Send CONTROL byte --
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
15
Ver A 2011/09
IIC 使用說明
for(counter=0; counter<LEN; counter++) // -- Read N byte -{
if(RXAK==d_ACK)
{
if(counter<(LEN-1))
{
Temp[counter] = IIC_ReceiveByte(d_ACK); // Receive one byte
}
else
{
Temp[counter] = IIC_ReceiveByte(d_NACK);// Receive last byte
}
}
else
{
;
// error process
}
}
}
else
{
;
// error process
}
}
else
{
;
}
IIC_SendStop();
// error process
// -- Send STOP -- MStart= 0
}
void Check_Arbitration(void)
// multi-master use
{
// arbitration lost, set by H/W
// clear by S/W
while(LAIF)
{
LAIF = 0;
}
}
void Check_Busy(void)
// multi-master use
{
// Bus busy, BB set by H/W
// Bus ready, BB clear by H/W or S/W
while(BB)
{
;
}
}
void Delay(unsigned int NTime)
{
unsigned int
i, j;
for(i=0; i<NTime; i++)
{
for(j=0; j<100; j++)
{
;
}
}
}
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
16
Ver A 2011/09
IIC 使用說明
#define waitslave 10
void main()
{
IIC_Init_master();
Check_Arbitration();
Check_Busy();
// multi-master use
// multi-master use
while(1)
{
IIC_Page_Write(d_DEVICE_ID1,
Delay(waitslave);
IIC_Random_Read(d_DEVICE_ID1,
Delay(waitslave);
IIC_Page_Write(d_DEVICE_ID1,
Delay(waitslave);
IIC_Random_Read(d_DEVICE_ID1,
Delay(waitslave);
IIC_Random_Read(d_DEVICE_ID1,
Delay(waitslave);
}
0x00, 3);
// finetune by user
0x00, 3);
// finetune by user
0x03, 3);
// finetune by user
0x03, 3);
// finetune by user
0x00, 6);
}
5.4 MCU IIC 完整範例程序(slave):
Description
Main program
MCU be slave as IIC-EEPROM:
//========================================================================
//
//
S Y N C M O S T E C H N O L O G Y
//
//========================================================================
// Test condition:
// Slave MCU Crystal 4~25MHz, pull-up 2.2KR
// Master SCL=100KHz and 400KHz test ok
//========================================================================
#include "SM39R16A2.h"
#include "IIC.h"
//=====================================================================
#define d_DEVICE_ID1
0xA0
// user modify
#define d_DEVICE_ID2
0x60
// user modify
#define d_ACK
#define d_NACK
#define d_Write
#define d_Read
#define d_null
#define d_CMD_RW
#define d_SAVE_ADDR
#define d_SAVE_DATA
0
1
0
1
0
0x40
1
2
//=====================================================================
bit bACK_last = d_NACK;
unsigned char n_Next_Step = d_null;
unsigned char n_RW
= d_null;
unsigned char n_Addr
= d_null;
unsigned char n_DAT[16];
//=====================================================================
void IIC_interrupt() interrupt d_IIC_Vector
{
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
17
Ver A 2011/09
IIC 使用說明
//slave rx===========================================================
if(RXIF)
{
//=======================================================
if ((IICA1 & 0x01) || (IICA2 & 0x01))
// match
{
n_Next_Step = d_SAVE_ADDR;
// set next step
n_RW
= RW;
// save RW status
if (n_RW == d_Write)
// don't release if read phase
IICEBT
= d_CMD_RW;
// IIC bus release if write phase
}
//=======================================================
else if (n_Next_Step == d_SAVE_ADDR)
{
n_Next_Step = d_SAVE_DATA;
// set next step
n_Addr
= IICRWD;
// save addr offset
IICEBT
= d_CMD_RW;
// IIC bus release
}
//=======================================================
else if (n_Next_Step == d_SAVE_DATA)
{
n_Next_Step
= d_SAVE_DATA;
// set next step
n_DAT[n_Addr++] = IICRWD;
// save data
IICEBT
= d_CMD_RW;
// IIC bus release
}
//=======================================================
RXIF = 0;
}
//slave tx===========================================================
if (TXIF)
{
TXIF = 0;
// Clear interrupt flag
}
//===================================================================
}
void IIC_init_slave()
{
IFCON
|= 0x80;
IICS = 0x00;
IRCON
= 0x00;
IICEBT
= d_CMD_RW;
IICA1
= d_DEVICE_ID1;
IICA2
= d_DEVICE_ID2;
IEN1
|= 0x20;
IEN0 |= 0x80;
IICCTL
= 0x80;
}
// MCU 1T
// init IICS
// init IRCON
// IIC bus ready
// Control Byte 1
// Control Byte 2
// Enable interrupt IIC
// Enable interrupt All
// Enable IIC module, slave mode, use IICA1
void IIC(void)
{
//slave tx===========================================================
if(n_RW==d_Read)
{
//slave tx get stop====================================
if(MPIF)
// get Stop condition
{
n_RW = d_null;
// break while(n_RW==d_Read)
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
18
Ver A 2011/09
IIC 使用說明
MPIF = 0;
}
//========================================================
else
{
//slave tx finish================================
if((RXAK == d_NACK)&&(bACK_last==d_ACK))// End if RXAK recive NACK
{
bACK_last
= d_NACK;
}
//slave tx on going==============================
else if(MPIF==0)
{
bACK_last
= d_ACK;
IICRWD
= n_DAT[n_Addr++];
IICEBT
= d_CMD_RW;
// IIC bus ready
while(IICEBT==d_CMD_RW)
{
;
}
//IICEBT will auto clear by HW
}
//===============================================
}
}
//slave rx===========================================================
else if(n_RW==d_Write)
{
//slave rx finish====================================
if(MPIF)
// get Stop condition
{
//slave rx get stop====================================
//slave finish recive data, here user process data, example n_DAT[].....
TXAK = d_NACK;
//TX NACK if slave busy
MPIF = 0;
// clear MPIF if finish process
TXAK = d_ACK;
}
}
//===================================================================
}
void main(void)
{
IIC_init_slave();
while(1)
{
IIC();
}//while(1)
}//end of main
6
不同工作電壓的 IIC 通訊應用:
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
19
Ver A 2011/09
IIC 使用說明
圖示
MCU Vcc
說明
Target Vcc
Pull
-up
Target Vcc
Pull
-up
SCL
MCU SM39R
Target IC
SDA
HW:
1.
Bus 必須接上拉(pull-up)電阻,電阻值須視實際應用
調整。
2.
必要時調降 MCU Vcc 可降低 MCU VIH/VIL,但仍
須符合 MCU 工作電壓 2.7~5.5V 規範。
3.
建議 Target Vcc> MCU Vcc*60%。
(Spec. ideal MCU Vcc=3.3V:VIH=1.9V,VIL=0.7V)
(Spec. ideal MCU Vcc=5V:VIH=2.7V,VIL=1V)
SW:
1.
先設置 SM39R 的 GPIO 設置為 open drain。
2.
enable IIC function。
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0235
20
Ver A 2011/09