IIC是通用串行总线,应用在各种MCU外设之上,使用汇编语言和GPIO模拟IIC总线。
SDA 和SCL 都是双向线路都通过一个电流源或上拉电阻连接到正的电源电压。当总线空闲时这两条线路都是高电平
IIC总线起始和停止条件
在I2C 总线中唯一出现的是被定义为起始S 和停止P 条件
在SCL 线是高电平时SDA 线从高电平向低电平切换表示起始条件
当SCL 是高电平时SDA 线由低电平向高电平切换表示停止条件
起始和停止条件一般由主机产生,总线在起始条件后被认为处于忙的状态,在停止条件的某段时间后
总线被认为再次处于空闲状态,如图
定义IIC接口的GPIO口
IIC_SCK_H: MACRO
OR P1,#04H
ENDM
IIC_SCK_L: MACRO
AND P1,#0FBH
ENDM
IIC_SDA_H: MACRO
OR P1,#02H
ENDM
IIC_SDA_L: MACRO
and P1,#0FDH
ENDM
IIC_SDA_IN: MACRO
AND P1CONL,#0F3H
ENDM
IIC_SDA_OUT: MACRO
AND P1CONL,#0F3H
OR P1CONL,#08H
ENDM
IIC_ACK_L: MACRO
IIC_SDA_L
CALL IIC_CK
ENDM
IIC_ACK_H: MACRO
IIC_SDA_H
CALL IIC_CK
ENDM
IIC时钟转换
数据传输必须带响应相关的响应时钟脉冲由主机产生在响应的时钟脉冲期间发送器释放SDA 线高在响应的时钟脉冲期间接收器必须将SDA 线拉低使它在这个时钟脉冲的高电平期间保持稳定的低电平。当然必须考虑建立和保持时间
IIC_CK:
NOP
NOP
NOP
NOP
NOP
NOP
IIC_SCK_H
NOP
NOP
NOP
NOP
NOP
NOP
NOP ; MUST BE BIGER THEN 4US
IIC_SCK_L
NOP
NOP
NOP
NOP
NOP
RET
IIC开始信号
IIC_START:
IIC_SDA_H
IIC_SCK_H
NOP
NOP
NOP
NOP
NOP
NOP
NOP
IIC_SDA_L
NOP
NOP
NOP
NOP
NOP
NOP
NOP
IIC_SCK_L
NOP
NOP
NOP
NOP
NOP
RET
IIC停止信号
IIC_STOP:
IIC_SDA_L
IIC_SCK_H
NOP
NOP
NOP
NOP
NOP
NOP
NOP
IIC_SDA_H
NOP
NOP
NOP
NOP
NOP
NOP
RET
IIC接收程序
IIC_RX:
IIC_SDA_IN
LD R15,#08H
LD R1,#00H ; <<<
IIC_RX_1:
RL R1
IIC_SCK_H
NOP
NOP
NOP
TCM P1,#02H ; P1.1 -- SDA
JR Z,IIC_RX_2
JR T,IIC_RX_3 ; >>>
IIC_RX_2:
OR R1,#01H
IIC_RX_3: ; <<<
NOP
IIC_SCK_L
DEC R15
JR NZ,IIC_RX_1
IIC_SDA_OUT
RET
IIC发送Byte
发送到SDA 线上的每个字节必须为8 位每次传输可以发送的字节数量不受限制每个字节后必须跟一个响应位首先传输的是数据的最高位MSB 。
如果从机要完成一些其他功能后才能接收或发送下一个完整的数据字节可以使时钟线SCL 保持低电平迫使主机进入等待状态。当从机准备好接收下一个数据字节并释放时钟线SCL 后数据传输继续
IIC_TX:
LD R15,#08H
IIC_TX_1:
RLC R3
JR C,IIC_TX_2
IIC_SDA_L
JR T,IIC_TX_3
IIC_TX_2:
IIC_SDA_H
IIC_TX_3:
CALL IIC_CK
DEC R15
JR NZ,IIC_TX_1
IIC_ACK_L ;ACK
RET
IIC的ACK应答信号
IIC_RX_ACK_LOW:
CALL IIC_RX
IIC_ACK_L
RET
使用IIC读取24C02的数据
EEP_WRITE:
CALL IIC_START
LD R3,#0A0H
CALL IIC_TX
LD R3,#10H ; EEP ADDRESS
CALL IIC_TX
LD R3,QN_MEMORY0
CALL IIC_TX
LD R3,QN_MEMORY1
CALL IIC_TX
LD R3,CUR_FREQUENCY0
CALL IIC_TX
LD R3,CUR_PROSET
CALL IIC_TX
LD R3,EEP_INIT_OK
CALL IIC_TX
CALL IIC_STOP
LD R0,#50H
;CALL delay_ms
RET
EEP_INIT:
CALL EEP_READ
CP EEP_INIT_OK,#59H
JR EQ,NOT_NEED_INIT
LD EEP_INIT_OK,#59H ; INIT DATA
LD QN_MEMORY0,#01H
LD QN_MEMORY0,#11H
LD CUR_FREQUENCY0,#01H
LD CUR_PROSET,#10H
CALL EEP_WRITE
NOT_NEED_INIT:
RET