IIC 功能使用方法 IIC 功能使用方法 1 适用产品: 1.1 SM59R16A2/ SM59R08A2 1.2 SM59R16A5/ SM59R09A5/ SM59R05A5/ SM59R16A3/ SM59R09A3/ SM59R05A3 1.3 SM59R04A2/ SM59R04A1/ SM59R03A1/ SM59R02A1 2 IIC 使用概述: 2.1 使用硬件 SCL (clock)及 SDA (data) 两条线,必须接拉升电阻。 2.2 速度:SCL 最高可达 400Kbps(由软件设定 SFR IICBR[2:0])。 2.3 IIC 可选择 master 或 slave 两种模式。 2.4 提供中断(RXIF, TXIF)及两组控制地址使用。 2.5 由软件设定,Master 硬件可自动产生 IIC 的启动(START)、重新启动(Re-START)及停止(STOP) 信号;Slave 硬件可侦测 IIC 的 START、Re-START 及 STOP 信号。 2.6 Slave 最多可接 127 devices,线材电容量最高限制为 400pF。 3 P4IIC (IIC function pin assignment)说明: P4IIC (SPI function pin assignment) SM59R16A5 ○ SM59R09A5 ○ SM59R05A5 ○ SM59R16A3 ○ SM59R09A3 ○ SM59R05A3 ○ SM59R16A2 × SM59R08A2 × Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 1 Ver A 2010/09 IIC 功能使用方法 SM59R04A2 ○ SM59R04A1 ○ SM59R03A1 ○ SM59R02A1 ○ ○:表示该型号可以使用 P4IIC 功能 ×:表示该型号不可使用 P4IIC 功能 Notice:所有系列 Package type DIP-40 皆没有 P4,所以没有用此功能 P4IIC (IIC function pin assign)说明 内建IIC,可直接经由软件设定将其脚位指定至P1或P4,避免和其它特殊功能脚位重复, 并提高硬件规划的兼容性。 Mnemonic AUX Description Direct Bit 7 Auxiliary register 91h BRS Bit 6 Bit 5 Bit 4 Serial interface 0 and 1 P4CC P4SPI P4UR1 Bit 3 Bit 2 Bit 1 Bit 0 RESET P4IIC P0KBI - DPS 00H Bit 4 Bit 3 Bit 2 MSS MAS RStart TXIF RDR TDR P4IIC: P4IIC = 0 – IIC function on P1. P4IIC = 1 – IIC function on P4. P4IIC 0 1 4 IIC_SCL P1.6 P4.0 IIC_SDA P1.7 P4.1 IIC 相关的特殊缓存器 SPI Special Function Register (SFR) Mnemonic Description Direct Bit 7 Bit 6 Bit 5 Bit 1 Bit 0 RESET IIC function IICCTL IIC control register F9h IICEN IICS IIC status register F8h MStart IICA1 IIC Address 1 register FAh IICA2 IIC Address 2 register FBh IICRWD IIC Read/Write register FCh IIC status2 register FDh IICS2 BF RXIF IICBR[2:0] RXAK TXAK 04H RW 00H IICA1[7:1] MATCH1 or RW1 A0H IICA2[7:1] MATCH2 or RW2 60H IICRWD[7:0] - Mnemonic: IICCTL 7 6 5 IICEN ----BF MSS - 4 MAS - 3 RStart - 2 AB_EN 1 IICBR[2:0] 00H BF_EN AB_F BF Address: F9h 0 Reset 04h IICEN: IC 致能位(Enable IIC module) IICEN = 1,IIC 致能。 Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 2 Ver A 2010/09 00H IIC 功能使用方法 IICEN = 0,IIC 禁能。 BF: (only SM59R16A2/SM59R08A2 used) IC 传送失败旗标 Bus failed flag (used in master mode only): 当 Master 传送数据”1”至 SDA,但 Master 侦测 SDA 为”0”时,此旗标将被硬件设置为”1” 。 此旗标可由软件清除。 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 送出。 RStart: 重新启动位 Re-start control bit (master mode only): RStart = 0,在送出控制地址后旗标由硬件清除为”0” 。 RStart = 1,由软件设定,在收到 ACK 后,送出启动条件(Start condition)及控制地址 (控制地址位由 MAS)。 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 MStart RxIF Baud rate Fosc/32 Fosc/64 Fosc/128 Fosc/256 Fosc/512 Fosc/1024 Fosc/2048 Fosc/4096 5 TxIF 4 RDR 3 TDR 2 RxAK 1 TxAK Address: F8h 0 Reset RW 00h MStart: 启动位 Master start control bit (master mode only) MStart = 1,由软件设置为”1”,送出启动条件(Start condition)及控制地址位(控制地址位 由 MAS)。 MStart = 0,由软件清除为”0”,送出停止条件(Stop condition)。 RxIF: 数据接收中断旗标 Data receive interrupt flag Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 3 Ver A 2010/09 IIC 功能使用方法 Slave 由此旗标可判断资料是否已接收 RxIF = 1,当数据读写缓存器(IICRWD)加载数据完成时,由硬件设为”1”。 RxIF = 0,接收完成后必须由软件清除。 TxIF: 数据传送中断旗标 Data transmit interrupt flag Master 由此旗标可判断资料是否已传出 TxIF = 1,当数据已由数据读写缓存器(IICRWD)载至位移缓存器,并已由位移缓存器传送 时,TxIF 为”1” TxIF = 0,传送数据完成后必须由软件清除。 RDR: 数据接收完成位 Read data ready RDR = 1,IIC module 接收数据至数据读写缓存器(IICRWD)时,由硬件自动设定为”1” 。 RDR = 0,当数据读写缓存器(IICRWD)完成接收后,必须由软件清除为”0”;当 RDR = 0 时,IIC module 才可再次写入新的数据至数据读写缓存器(IICRWD)。 TDR: 数据传送完成位 Transmit data ready TDR = 1,由程序将数据写入数据读写缓存器(IICRWD)后,由软件设定此旗标为”1” ,告 知硬件 IIC module 将数据传出。 TDR = 0,当IIC module由数据读写缓存器(IICRWD)读取数据并完成传送时,此位则由硬 件自动清除。 RxAK: 接收应答位 Receive acknowledgement 当 IIC module 传送数据时此位为只读位,等待接收端回复应答(ACK/NACK),不可由程序 编写。 当 IIC module 为 master mode:传出数据(8-bit)后,由 slave 回复应答位(RxAK)。 当 IIC module 为 slave mode:传出数据(8-bit)后,由 master 回复应答位(RxAK)。 TxAK: 传送应答位 Transmit acknowledgement IIC module 当接收端时,接收数据完成后,回复传送端应答位(ACK/NACK)。 RW: Slave mode read or write(read only) 1. 当 IIC module 为 slave mode 时,此位为只读,不可由程序编写。 2. 此位由 master 的地址 IICA1(或 IICA2) 的 8th-bit 所控制: = 0 : master 要求 slave 的 IIC module 为接收模式(即 master write, slave read)。 = 1 : master 要求 slave 的 IIC module 为传送模式(即 master read, slave write)。 Fig. Acknowledgement bit in the 9th bit of a byte transmission Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 4 Ver A 2010/09 IIC 功能使用方法 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,由软件设定,当 slave 接收到 master 的启动条件(Start condition), 及控制地址(IICA1)7-bit,两者会相互比对,比较结果可参考 Match1。 Match1: = 1,当 slave 硬件侦测到启动条件(Start condition),且控制地址(IICA1)7-bit 相同时,slave 的 8th-bit(Match1)会由硬件设置为”1” 。 = 0,当 slave 硬件(1) RXIF 发生但未侦测到启动条件(Start condition),或(2)TXIF 发生时,Match1 由硬件清除为”0”。 Master mode: IICA1[7:1]: IIC Address registers 1. 第一组控制地址 IICA1 共 7-bit,由软件设定。 2. 当 MAS = 0,选择控制地址(IICA1)。 (当 MAS = 1,选择控制地址(IICA2)。) 3. 当 MStart 由软件设置为”1”时,会送出启动条件(Start condition)及控制地址位(IICA1)。 RW1: 当 master 与 slave 的控制地址 7-bit 相同时,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,由软件设定,当 slave 接收到 master 的启动条件(Start condition), 及控制地址(IICA2)7-bit,两者会相互比对,比较结果可参考 Match2。 Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 5 Ver A 2010/09 IIC 功能使用方法 Match2: = 1,当 slave 硬件侦测到启动条件(Start condition),且控制地址(IICA2)7-bit 相同时,slave 的 8th-bit(Match2)会由硬件设置为”1” 。 = 0,当 slave 硬件(1) RXIF 发生但未侦测到启动条件(Start condition),或(2)TXIF 发生时,Match2 由硬件清除为”0”。 Master mode: IICA2[7:1]: IIC Address registers 1. 第二组控制地址 IICA2 共 7-bit,由软件设定。 2. 当 MAS = 1,选择控制地址位(IICA2)。 (当 MAS = 0,选择控制地址位(IICA1)。) 3. 当 MStart 由软件设置为”1”时,会送出启动条件(Start condition)及控制地址位(IICA2)。 RW2: 当 master 与 slave 的控制地址 7-bit 相同时,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)。 Mnemonic: IICRWD 7 6 5 4 3 IICRWD[7:0] 2 Address: FCh 0 Reset 00h 1 IICRWD[7:0]: IIC 数据读写缓存器(8-bit) IIC read write data buffer: IIC module 为接收模式(读取)时,为接收数据的暂存区。 IIC module 为传送模式(写入)时,为传送数据的暂存区。 The IICS2 register only SM59R16A5/SM59R09A5/SM59R05A5/SM59R16A3/SM59R09A3/SM59R05A3 and SM59R04A2/SM59R04A1/SM59R03A1/SM59R02A1 used. Mnemonic: IICS2 Address: FDH 7 6 5 4 - - - - 3 AB_EN 2 1 0 Reset BF_EN AB_F BF 00H AB_EN: 仲裁失去了致能位. (仅主机模式)Arbitration lost enable bit. (Master mode only) =1,致能,master硬件将检查仲裁丢失位AB_F,一旦发生丢失仲裁,AB_F将被设置为”1”, 即返回到闲置状态。 =0,禁能,master硬件不会理会仲裁丢失情况。 当系统为多主从(multi-master)应用时,请致能该侦测位(AB_EN)。 当系统为单主从(single-master)应用时,可禁能该侦测位(AB_EN)。 BF_EN: 总线忙碌侦测致能位 Bus busy enable bit. (Master mode only) =1,致能,master硬件无法送出启动条件(Start condition),直到BF=0。 =0,禁能,master硬件不理会BF=0或1。 当系统为多主从(multi-master)应用时,请致能该侦测位(BF_EN)。 当系统为单主从(single-master)应用时,可禁能该侦测位(BF_EN)。 AB_F: 仲裁丢失位(仅主机模式) Arbitration lost bit. (Master mode only) =1,当master SDA送出”1”却侦测回应为”0”时,即发生丢失仲裁,AB_F将被设置为”1”。 系 统为多主从(multi-master)应用,通讯时请侦测该位。 =0,在重送数据前软件需清除此位,且需检查BF直到已清除为”0”。 Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 6 Ver A 2010/09 IIC 功能使用方法 BF: 总线忙碌侦测位 Bus busy bit. (Master mode only) =1,当Master侦测到BUS上有SCL=0或SDA=0或启动条件(Start condition)时,该BF由硬 件设为”1”。系统为多主从(multi-master)应用,通讯时请侦测该位。 =0,当Master侦测到停止条件(Stop condition),大约4.7us后,BF由硬件清除为”0”。此位 也可由软件清除为”0”,使总线回到初始状态。 5 IIC 中断 5.1 向量表(Interrupt vectors table) Interrupt Vector Address Interrupt Number *(use Keil C Tool) IE0 – External interrupt 0 0003h 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 0023h 4 TF2/EXF2 – Timer 2 interrupt 002Bh 5 PWMIF – PWM interrupt (The SM59R16A2/SM59R08A2 haven’t) 0043h 8 SPIIF – SPI interrupt 004Bh 9 ADCIF – A/D converter interrupt 0053h 10 KBIIF – keyboard Interface interrupt 005Bh 11 LVIIF – Low Voltage Interrupt (The SM59R16A2/SM59R08A2 haven’t) 0063h 12 IICIF – IIC interrupt 006Bh 13 RI1/TI1 – Serial channel 1 interrupt 0083h 16 008Bh 17 0093h 18 Interrupt Request Flags RTC/ALARM interrupt (Only SM59R16A5/SM59R09A5/SM59R05A5 have) Comparator interrupt (Only SM59R16A5/SM59R09A5/SM59R05A5 have) *See Keil C about C51 User’s Guide about Interrupt Function description Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 7 Ver A 2010/09 IIC 功能使用方法 5.2 中断相关缓存器(Interrupt SFR) Mnemonic Description Direct Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 RESET Interrupt IEN0 Interrupt Enable 0 register A8h EA - ET2 ES0 ET1 EX1 ET0 EX0 00h IEN1 Interrupt Enable 1 register B8h EXEN2 - IEIIC - IEEEI IEADC IESPI - 00h IEN2 Interrupt Enable 2 register 9Ah - - - - - - - ES1 00h IP0 Interrupt priority level 0 A9h - - IP0.5 IP0.4 IP0.3 IP0.2 IP0.1 IP0.0 00h IP1 Interrupt priority level 1 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 IIC_interrupt(void) interrupt 13 { if(IICS_TXIF) { TxInt = 1; IICS_TXIF = 0;//Clear interrupt flag } if(IICS_RXIF) { RxInt = 1; IICS_RXIF = 0;//Clear interrupt flag } } Ps. IIC 中断发生,必须清除 IICS^TXIF 或 IICS^RXIF,而非 IRCON 的 IICIF! (中断应用可参考范例程序二) 6 MCU 为 master,EEPROM 为 slave 通讯应用的流程图(二): Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 8 Ver A 2010/09 IIC 功能使用方法 6.1 Demo Board(SDB0001B) 上 的 EEPROM 为 24LC04 (4KEEPROM , 512x8bits , 32pages , 16bytes/page,详细规格书可上网下载). 6.2 MCU 对 EEPROM 做 page write (256bytes = 16bytes x 16page),再用 random read 做 data verify 确 认 7 MCU 对 EEPROM 24LC04 系列应用的范例程序(二) Description Main program MCU master w/r IIC-EEPROM: //=============================== //INCLUDE FILES //=============================== #include "..\h\SM59R16A2.h" #include "..\h\SM59R16A2_ExtraDef.h" #include "..\LCD\LCD16x2.h" #include "..\MISC\Delay.h" //=============================== //DEFINITIONs //=============================== #define IICSendStop() IICS_MStart = false #define NACK 1 #define ACK 0 #define Address_S 0x00 //for ICCEE verify #define Address_E 0xFF //for ICCEE verify #define NC 0 //Don't care //=============================== Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 9 Ver A 2010/09 IIC 功能使用方法 //GLOBAL VARIABLES //=============================== bit IICEE_Error = false ; // This bit is used to indicate if the read/write is successful. // True/1: Error, False/0: No Error bit TxInt = 0; bit RxInt = 0; unsigned int Count_OK=0, Count_Err=0; unsigned char code EDID_Data[]= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0X10, 0X11, 0X12, 0X13, 0X14, 0X15, 0X16, 0X17, 0X18, 0X19, 0X1A, 0X1B, 0X1C, 0X1D, 0X1E, 0X1F, 0X20, 0X21, 0X22, 0X23, 0X24, 0X25, 0X26, 0X27, 0X28, 0X29, 0X2A, 0X2B, 0X2C, 0X2D, 0X2E, 0X2F, 0X30, 0X31, 0X32, 0X33, 0X34, 0X35, 0X36, 0X37, 0X38, 0X39, 0X3A, 0X3B, 0X3C, 0X3D, 0X3E, 0X3F, 0X40, 0X41, 0X42, 0X43, 0X44, 0X45, 0X46, 0X47, 0X48, 0X49, 0X4A, 0X4B, 0X4C, 0X4D, 0X4E, 0X4F, 0X50, 0X51, 0X52, 0X53, 0X54, 0X55, 0X56, 0X57, 0X58, 0X59, 0X5A, 0X5B, 0X5C, 0X5D, 0X5E, 0X5F, 0X60, 0X61, 0X62, 0X63, 0X64, 0X65, 0X66, 0X67, 0X68, 0X69, 0X6A, 0X6B, 0X6C, 0X6D, 0X6E, 0X6F, 0X70, 0X71, 0X72, 0X73, 0X74, 0X75, 0X76, 0X77, 0X78, 0X79, 0X7A, 0X7B, 0X7C, 0X7D, 0X7E, 0X7F, 0X80, 0X81, 0X82, 0X83, 0X84, 0X85, 0X86, 0X87, 0X88, 0X89, 0X8A, 0X8B, 0X8C, 0X8D, 0X8E, 0X8F, 0X90, 0X91, 0X92, 0X93, 0X94, 0X95, 0X96, 0X97, 0X98, 0X99, 0X9A, 0X9B, 0X9C, 0X9D, 0X9E, 0X9F, 0XA0, 0XA1, 0XA2, 0XA3, 0XA4, 0XA5, 0XA6, 0XA7, 0XA8, 0XA9, 0XAA, 0XAB, 0XAC, 0XAD, 0XAE, 0XAF, 0XB0, 0XB1, 0XB2, 0XB3, 0XB4, 0XB5, 0XB6, 0XB7, 0XB8, 0XB9, 0XBA, 0XBB, 0XBC, 0XBD, 0XBE, 0XBF, 0XC0, 0XC1, 0XC2, 0XC3, 0XC4, 0XC5, 0XC6, 0XC7, 0XC8, 0XC9, 0XCA, 0XCB, 0XCC, 0XCD, 0XCE, 0XCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; //=============================================================== //OWNED SUBROUTINES //=============================================================== void OSD(unsigned char SW, unsigned int D0, unsigned int D1) { switch( SW) { case 0: PrintLcdStrLX(1, 0, "IIC demo:24xx EE"); break; case 1: PrintLcdStrLX(2, 0, "Writing... "); SetCursorAddr(2, 13); Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 10 Ver A 2010/09 IIC 功能使用方法 PrintLcdDec(D0); break; case 2: PrintLcdStrLX(2, Delay10mSec(50); break; case 3: PrintLcdStrLX(1, PrintLcdStrLX(1, SetCursorAddr(1, PrintLcdDec(D0); break; case 4: PrintLcdStrLX(2, SetCursorAddr(2, PrintLcdDec(D0); SetCursorAddr(2, PrintLcdDec(D1); Delay10mSec(50); break; case 5: break; case 6: break; case 7: break; case 8: break; case 9: break; case 10: break; default: break; 0, "Done. "); 0, "Verifying... 12, " "); 13); 0, "OK: 3); Er: "); "); 11); } } void IIC_Init(unsigned char IICSetting) { IICCTL = IICSetting ; } void MCU_Init() { // IIC_Init(IIC_EN|IIC_MASTER|IIC_ADR_CA1|IIC_BR4096); // Init BR IIC_Init(IIC_EN|IIC_MASTER|IIC_ADR_CA1|IIC_BR32); // Init BR IEN0 = 0x80; //Enable interrupt All IEN1 = 0x20; //Enable interrupt IIC } void IICDisable(void) { IICCTL = 0x04 ; } // 0x04 is MCU reset value //=============================================================== //This function will send out the START pulse and CONTROL byte. Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 11 Ver A 2010/09 IIC 功能使用方法 //=============================================================== void IIC_SendStart(unsigned char ControlByte) { if( IICCTL & MSK_IICCTL_MAS ) IICA2 = ControlByte; // MAS = 1 else IICA1 = ControlByte; // MAS = 0 IICS_MStart = true; while(~TxInt); TxInt = 0; } //=============================================================== //This function will send out the RESTART pulse and CONTROL byte. //=============================================================== void IIC_SendRestart(unsigned char ControlByte) { if( IICCTL & MSK_IICCTL_MAS ) IICA2 = ControlByte; // MAS = 1 else IICA1 = ControlByte; // MAS = 0 IICCTL |= IIC_RSTART; while(~TxInt); TxInt = 0; } //=============================================================== //This function will wait and receive one byte, then feedback ACK or NACK. //=============================================================== unsigned char IIC_ReceiveByte(bit ACKStatus) { unsigned char temp; unsigned int Counter = 0; // Feedback ACK/NACK to slave for continue/stopping the transaction soon. IICS_TXAK = ACKStatus; while(~RxInt); RxInt = 0; temp = IICRWD; IICS_RDR = 0; // Clear Read Data Ready bit return(temp); } void IIC_TransmitByte(unsigned char TxData) { IICRWD = TxData; IICS_TDR = 1; while(~TxInt); TxInt = 0; } unsigned char IICEE_RandomRead(unsigned char Block, unsigned char Address) Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 12 Ver A 2010/09 IIC 功能使用方法 { unsigned char temp; // -- Send CONTROL byte -IIC_SendStart( 0xA0|Block ); operation // Set CONTROL byte to be write // -- Send ADDRESS -IIC_TransmitByte(Address); // -- Send CONTROL byte -IIC_SendRestart( 0xA1|Block ); operation. // Set CONTROL byte to be read // -- Read one byte -temp = IIC_ReceiveByte(NACK); // Wait for one byte // -- Send STOP -IICSendStop(); return(temp); } void IICEE_ByteWrite(unsigned char Block, unsigned char Address, unsigned char WriteData) { // -- Send CONTROL byte -IIC_SendStart( 0xA0|Block ); // Set CONTROL byte to be write operation // -- Send ADDRESS -IIC_TransmitByte(Address); // -- Write one byte -IIC_TransmitByte(WriteData); // -- Send STOP -IICSendStop(); } void IICEE_Page_Write(unsigned char Block, unsigned char Page_sel ) { unsigned int i=0; unsigned int Address_Page_S=0; Address_Page_S= Page_sel<<4; // -- Send CONTROL byte -IIC_SendStart( 0xA0|Block ); // Set CONTROL byte to be write operation // -- Send ADDRESS -IIC_TransmitByte( Address_Page_S ); Delay10mSec(1); // -- Write N bytes -for (i=Address_Page_S; i<(Address_Page_S+16); i++) //16byte per 1page { OSD(1, EDID_Data[i], NC); IIC_TransmitByte( EDID_Data[i]); // Transmit one byte Delay10mSec(1); Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 13 Ver A 2010/09 IIC 功能使用方法 } // -- Send STOP -IICSendStop(); } void IICEE_Byte_Read() { unsigned int i, temp ; for (i=Address_S; i<=Address_E; i++) { //PrintLcdDec(i); temp = IICEE_RandomRead(0, i); //read OSD(3, temp, NC); P2 = temp; if( temp == EDID_Data[i] ) //verify Count_OK++; else { Count_Err++; } Delay10mSec(1); // For display stable. } OSD(4, Count_OK, Count_Err); } void IIC_interrupt(void) interrupt 13 using 1 { if(IICS_TXIF) { TxInt = 1; IICS_TXIF = 0;//Clear interrupt flag } if(IICS_RXIF) { RxInt = 1; IICS_RXIF = 0;//Clear interrupt flag } } void main() { unsigned char i=0; P2 = 0x00; MCU_Init(); LCD_Init(); Delay10mSec(5); OSD(0, NC, NC); // P2 is 7 Segment. for test only //Init MCU //Init LCD //On screen display for (i=0; i<=15; i++) { IICEE_Page_Write(0, i); //Block=0, page=0~15 } OSD(2, NC, NC); while(1) { Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 14 Ver A 2010/09 IIC 功能使用方法 IICEE_Byte_Read(); } } Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 15 Ver A 2010/09 IIC 功能使用方法 8 通讯协议以标准的 IIC EEPROM 24Cxx 为范例,Master 和 Slave 皆使用 SM59R16A5,示范 page write 及 random ead 之间如何沟通 及控制,以下是 Master 及 Slave 沟通时的缓存器状态及说明。 Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 16 Ver A 2010/09 IIC 功能使用方法 Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 17 Ver A 2010/09 IIC 功能使用方法 9 通讯协议以标准的 IIC EEPROM 24Cxx,使用 SM59R16A5 当 Master 和 Slave 的范例程序: Description Main program -- MCU IIC master -1. 以下定义有注明”user modify”,是 user 可搭配 slave 自行变更修改,其它未注明的不建议修改。 2. 一般模式中,Device ID 应尽量避免使用 0xA0(EEPROM 常用)和 0x00(general call address 使用), 或其它 IIC 规范中特定保留的部分。 3. 范例使用 IIC 数据存取最常使用的通讯协议,page write 及 random read,可直接与 slave 沟通。 //======================================================================== // // S Y N C M O S T E C H N O L O G Y // //======================================================================== //IIC Master sample code, "user modify" as fallow, that is allowed for //modify. Others are not suggest or illegal. //=============================== //INCLUDE FILES //=============================== #include "SM59R16A5.h" #include "IIC.h" //=============================== //IIC DEFINITIONs //=============================== #define d_IIC_EN 0x80 #define d_DEVICE_ID 0x50 //#define d_DEVICE_ID 0xA0 //user modify //user modify #define d_IIC_MASTER #define d_IIC_SLAVE #define d_IIC_MODE_SEL 0x20 0x00 d_IIC_MASTER //user modify #define #define #define #define d_IIC_ADR_CA1 d_IIC_ADR_CA2 d_MSK_IICCTL_MAS d_IIC_ADR_SEL 0x00 0x10 0x10 d_IIC_ADR_CA2 //user modify #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 0x05 0x06 0x07 d_BR32 //user modify #define d_NACK 1 #define d_ACK 0 #define d_WRITE 0 #define d_READ 1 #define IIC_Start() MStart = 1 #define IIC_Restart() IICCTL |= 0x08 #define IIC_SendStop() MStart = 0 //=============================== //Code Data //=============================== unsigned char code EDID_Data[]= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; //=============================================================== Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 18 Ver A 2010/09 IIC 功能使用方法 //OWNED SUBROUTINES //=============================================================== void Delay10uSec(unsigned int NTime) { unsigned int i, j; for(i=0; i<NTime; i++) for(j=0; j<18; j++); } void IIC_interrupt(void) interrupt d_IIC_Vector { if(TXIF) { TXIF = 0; //Clear interrupt flag } if(RXIF) { } } void IIC_Init(unsigned char IICSetting) { IICA1 = 0x00; IICA2 = 0x50; IICCTL = IICSetting ; IEN1 = 0x20; // Enable interrupt IIC IICS2 = 0x0C; // Enable IIC AB_EN & BF_EN } void MCU_Init() { IFCON |= 0x80; // MCU 1T IEN0 = 0x80; // Enable interrupt All IIC_Init(d_IIC_EN | d_IIC_MODE_SEL | d_IIC_ADR_SEL | d_IIC_BR); // Init BR } void IIC_Disable(void) { IEN1 &= 0xDF; IICCTL = 0x00; IICS = 0x00; IICS2 = 0x00; } // Disable interrupt IIC // Disable IIC all function // Clear IIC all status // Clear IIC all status //=============================================================== //This function will send out the START pulse and CONTROL byte. //=============================================================== void IIC_SendStart(unsigned char ControlByte) { if( IICCTL & d_MSK_IICCTL_MAS ) IICA2 = ControlByte; // MAS = 1 else IICA1 = ControlByte; // MAS = 0 while(TDR); IIC_Start(); // wait last data trans. finish // MStart = 1 } //=============================================================== //This function will send out the RESTART pulse and CONTROL byte. //=============================================================== void IIC_SendRestart(unsigned char ControlByte) Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 19 Ver A 2010/09 IIC 功能使用方法 { while(TDR); // wait last data trans. finish if( IICCTL & d_MSK_IICCTL_MAS ) IICA2 = ControlByte; // MAS = 1 else IICA1 = ControlByte; // MAS = 0 IIC_Restart(); // IICCTL |= 0x08; } //=============================================================== //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 while(~RXIF){}; RXIF=0; temp RDR = IICRWD; = 0; // Clear Read Data Ready bit return(temp); } void IIC_TransmitByte(unsigned char TxData) { while(TDR); // wait last data trans. finish IICRWD = TxData; TDR = 1; } void IIC_Page_Write( char Crtl_byte, char Addr, char LEN) { unsigned char counter=0; IIC_SendStart( Crtl_byte ); IIC_TransmitByte( Addr ); // -- Send CONTROL byte -// -- Send ADDRESS -- for (counter=0; counter<LEN; counter++) // -- Write N bytes -{ IIC_TransmitByte( EDID_Data[Addr + counter]);// -- Transmit one byte -} while(TDR); IIC_SendStop(); // must wait last data trans. finish // -- Send STOP -- MStart= 0 } void IIC_Random_Read( char Crtl_byte, char Addr, char LEN) { unsigned char Temp[16]; unsigned char counter=0; IIC_SendStart( Crtl_byte | d_WRITE ); IIC_TransmitByte(Addr + counter); // -- Send CONTROL byte -// -- Send ADDRESS -- IIC_SendRestart(Crtl_byte | d_READ); for(counter=0; counter<LEN; counter++) { if(counter<(LEN-1)) { // -- Send Restart -// -- Read N byte -- Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 20 Ver A 2010/09 IIC 功能使用方法 Temp[counter] = IIC_ReceiveByte(d_ACK); // Receive one byte } else { Temp[counter] = IIC_ReceiveByte(d_NACK);// Receive last byte } } IIC_SendStop(); // -- Send STOP -- MStart= 0 } void Check_Arbitration(void) { while(IICS2&0x02) { IICS2 &= 0xFD; Delay10uSec(1); } } // multi-master use void Check_Busy(void) { while(IICS2&0x01) { IICS2 &= 0xFE; Delay10uSec(1); } } // multi-master use void main() { MCU_Init(); Check_Arbitration(); Check_Busy(); // multi-master use // multi-master use IIC_Page_Write(d_DEVICE_ID, 0x00, 16); IIC_Random_Read(d_DEVICE_ID, 0x00, 8); IIC_Random_Read(d_DEVICE_ID, 0x08, 8); Delay10uSec(10); Delay10uSec(10); Delay10uSec(10); IIC_Disable(); while(1) { } } Description Main program -- MCU IIC Slave -//==================================================================== // // S Y N C M O S T E C H N O L O G Y // //==================================================================== #include "SM59R16A5.h" //===================================================================== #define d_IIC_Adress_1 0x50 //user modify #define d_IIC_Adress_2 0x00 //user modify #define #define #define #define #define d_ACK d_NACK d_Write d_Read d_null 0 1 0 1 0x00 Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 21 Ver A 2010/09 IIC 功能使用方法 //===================================================================== unsigned char n_RW = d_null; unsigned char n_Addr = d_null; unsigned char n_IIC_Step= d_null; unsigned char n_DAT[16]; //===================================================================== void IIC_interrupt(void) interrupt d_IIC_Vector { if((IICA1&0x01)|(IICA2&0x01)) { n_IIC_Step = d_null; } // Device ID match, step clear if(RXIF) { RXIF = 0; RDR =0; n_IIC_Step++; switch (n_IIC_Step) { case 0: break; case 1: // match n_RW = RW; break; case 2: // write addr n_Addr = IICRWD; break; default: // write data n_DAT[n_Addr++] = IICRWD; break; } } else if(TXIF) { TXIF = 0; } } void IIC_init_slave(void) { IICCTL = 0x80; IICS = 0x00; IRCON = 0x00; IICA1 = d_IIC_Adress_1; IICA2 = d_IIC_Adress_2; IEN0 |= 0x80; IEN1 |= 0x20; //Enable IIC module //init IICS //init IRCON //Control Byte 1 //Control Byte 2 //Enable interrupt All //Enable interrupt IIC } void main(void) { IIC_init_slave(); while(1) { //===================================================================== if((n_RW==d_Read)&(n_IIC_Step>=1)) // slave TX start Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 22 Ver A 2010/09 IIC 功能使用方法 { if(RXAK == d_ACK) { IICRWD = n_DAT[n_Addr++]; TDR=1; while(TDR){} } else if(RXAK == d_NACK) { n_IIC_Step = d_null; n_RW = d_null; } // trans. data if recive ACK // End if recive NACK } //===================================================================== }//end of while(1) }//end of main Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0192 23 Ver A 2010/09