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-0236
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-0236
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-0236
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-0236
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-0236
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-0236
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-0236
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-0236
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-0236
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-0236
10
Ver A 2011/09
IIC 使用说明
Master:
• M1. FU_EN写入10,Master送出Start、Device ID及RW讯号。
• M2. 送出完成时,FU_EN由硬件清为零,TxIF由硬件设置为1,
并产生中断,TxIF由软件清除。时也需判断RxAK的状态。
• M3. Data写入IICRWD后, FU_EN写入01,即会将Data送出。
• M4. Data送出后,FU_EN由硬件清为零,TxIF由软件设置为1,
并产生中断。
• M5. FU_EN写入11,送出Stop讯号,后MPIF由硬件设为1,
并产生中断。
Slave:
• S1. S1. 当slave硬件侦测到Start condition及device ID,
Match bit由硬件设为1。
• S2. 收到Device ID(及RW)时,硬件会传出TxAK;RxIF会
由硬件设为1,并触发中断,软件必须写FU_EN=01,用来
release bus。
• 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:
•
•
M1&M3. FU_EN写入10h,Master送出Start(or
S1. 当slave硬件侦测到Start condition及device ID,Match
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0236
11
Ver A 2011/09
IIC 使用说明
Re-Start)、Device ID及RW讯号。收到ACK后FU_EN由硬
•
件清除,并触发TxIF。
•
•
bit由硬件设为1。
RxIF会由硬件设为1,并触发中断,软件必须写FU_EN=01,
出Data。收到ACK后FU_EN由硬件清除,并触发TxIF。
用来release bus。
M4. RX:FU_EN写入01h后,SCL开始送出CLK,并将Data
•
收进IICRWD,收到ACK后FU_EN由硬件清除,并触发
M5. Stop:FU_EN写入11h后,送出Stop,收到ACK后
S4. 每次Data完成送出后,FU_EN由硬件清除为0,TxIF由
硬件设置为1,并触发中断,TxIF须由软件清除为0。
•
FU_EN由硬件清除,并触发MSIF及中断。
S3. 每次Data写入IICRWD后,FU_EN写入01,即会将Data
送出。
•
RxIF及中断。
•
S2. 收到Device ID(及RW)或Data,硬件会接着传出TxAK;
M2. TX:将Data写入IICRWD后,FU_EN写入01h,即送
S5. 当收到N-ACK时,Slave即停止Data回传。在收到Stop
condition,MPIF由硬件设为1,MPIF须由软件清除为0。
5.3 MCU IIC 完整范例程序(master):
Description
MCU master w/r EEPROM(24cxx):
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0236
12
Ver A 2011/09
IIC 使用说明
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
}
if(MPIF)
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0236
13
Ver A 2011/09
IIC 使用说明
{
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-0236
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);
for(counter=0; counter<LEN; counter++)
{
// -- Send CONTROL byte --
// -- Send ADDRESS --
// -- Send CONTROL byte -// -- Read N byte --
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0236
15
Ver A 2011/09
IIC 使用说明
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++)
{
;
}
}
}
#define waitslave 10
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0236
16
Ver A 2011/09
IIC 使用说明
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
{
//slave rx===========================================================
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0236
17
Ver A 2011/09
IIC 使用说明
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)
MPIF = 0;
}
Specifications subject to change without notice, contact your sales representatives for the most recent information.
ISSFA-0236
18
Ver A 2011/09
IIC 使用说明
//========================================================
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-0236
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-0236
20
Ver A 2011/09