/*
* =====================================================================================
* Author: [email protected]
* =====================================================================================
*/
XE164的IIC 协议实现是仿照标准IIC 协议V2.1 版本
IIC 的一些基本知识:
1:2条双向串行线,一条数据SDA ,一条时钟线SCL;
2:在时钟信号为低时准备好传送的数据,时钟信号位高时采样数据;
3:START 信号开始掌管 总线,STOP 结束时 释放总线
START信号:SCL 是高电平,SDA 信号由高变低;
STOP信号:SCL 是高电平,SDA 信号由低变高;如下图:
图1,起始和停止条件
4:数据是 8位数据位传送,采用的是MSB 方式;
5:应答信号
1)Master 每发送完 8 bit 数据后等待Slave 的ACK,在第九个时钟序号时,若
响应的SCL 信号有主机产生,在响应的时钟脉冲期间,接收器将SDA 拉低
若没有收到ACK 则,将SDA 拉高,产生STOP/RESTART 信号,如下图:
图2 IIC响应
6:IIC 写流程
1)Master发起START;
2)Master发送IIC Add(7bit),和w操作0(1bit),等待ACK;
3)Slave 发送ACK;
4)Master 发送data(8bit),等待ACK;
5)Slave发送ACK;
6)4,5 可重复多次;
7)Master发起STOP。
时隙如下图:
图3 IIc 写流程
7:IIC 总线是线与总线系统,只要有一个设备发送 0 ,那么 总线上就是 0;
XE164和ISL1208 芯片仿照IIC 协议实现
遵循标准的协议,例如说,开始信号,结束信号,ACK信号,数据传送方式(MSB),
数据传送大小(8 bits);
ISL1208要点:
1)As a slave device in all applications;
2)Data transfer type is MSB;
3)发送器,不论是主站还是从站,在传送完成后将释放SDA 线,在第九个时钟
周期来的时候,接收器将把SDA 线拉低,以来发送ACK 信号,确定其收到8
bits;
4)发送ACK 信号有3种情况:
a)接收 Identification 后;
b)接收 Addresss 后;
c)接收 data后;
如图:
图4 1208 发送ACK情况
5)写操作---Master transmit data
a)Master send START signal;
b)Master send a valid Identification Byte--11011111,and receive
the acknowledge;
c)Master send a valid Address Byte,and receive ACK;
b)Slave receive data,and transmit the acknowledge;
c)Master transmint STOP signal,You can repeat b;
6)读操作---Slave transmit data
a)START signal;
b)Master transmit the Identification Byte---11011110,and receive
the acknowledge;
c)Master send a valid Address Byte,and receive the acknowledge;
d)Master send a second START signal;
e)主站再次发送 标识字节---11011111,然后等待接收ACK;
f)在走完上述流程后,如果每个字节的第8位之后SCL周期之内,只要主机
做出应答---ACK,那么继续走下一步;
j)从站发送有效数据,然后等待接收站(这里是Master)反馈ACK;
h)主站结束读操作,你可以重复操作 f,j;
XE164要点:
1)寄存器配置
要使用IIC,那么首先的配置 IIC;
a)选择IIC模式,在CCR---通道控制寄存器,用来使能/禁止基于通道事件产 生中断,控制奇偶校验产生及选择通道选用的协议;
U2C0_CCR = 0x0000;
↓
配置通道相关参数→U2C0_CCR = 0x0004; 选择IIC协议;
b)波特率配置
U2C0_FDRL---设置分频策略
U2C0_BRGL
U2C0_BRGH---波特率发生寄存器
c) 通道设置
U2C0_DX0CR---连接 SDA
U2C0_DX1CR ---连接SCL
IIC协议中不使用输入级DX2
P1_IOCR06 = 0x00F0;----作为数据输出端口
P1_IOCR07 = 0x00F0;----作为时钟信号输出端口
d)IIC协议传输速率选择配置
U2C0_PCRL = 0x0000; //从站地址
U2C0_PCRH = 0x0000; //0:100kb/s 2:400Kb/s
e) 数据传送控制配置
U2C0_TCSRL = 0x0500;
U2C0_TCSRH = 0x0000;
2)IIC是面向字节的总线协议,不过USIC数据缓存字最多可包含16位数据。除将要发 送的数据字节之外(位于TBUF[7:0]),用于控制IIC序列的位域TDF(发送数据格 式)位于TBUF[10:8]。TDF编码定义如何发送每个数据字节(IIC主控或从控)、控 制(重复)开始和终止符号的发送。通过该结构,只需写访问TBUFx或使用FIFO 数据缓存即可为IIC主控器件定义完整的数据帧(因为不必访问其它控制寄存器)。
3)Xe164 发送数据需要发送TDL码;具体码值可以参考手册表21-9;
RTS 代码实现
/*开启/禁止1208寄存器,已进行参数设置*/
Temp = 0xD0;
WriteByteToISL1208(&Temp, 1, Status_Add);
SetCurrentTime(&dsTime); //Send the information to 1208 device
Temp = 0x01;
WriteByteToISL1208(&Temp, 1, DTR_Add); //采用DTR软件补偿 +20ppm
// .7---ARST=1, BAT/ALM 状态位的自动复位使能; 振荡器使能; 禁止写
Temp = 0x80;
WriteByteToISL1208(&Temp, 1, Status_Add);
/**Function :Write bytes to the device
***Input:
&i2c_data:the data will be transmit;
&no_of_bytes:how bytes to tramsmit;
&base_addr:the addr of the IIC device's register
***************/
void WriteByteToISL1208(unsigned char *i2c_data, unsigned char no_of_bytes, unsigned char base_addr)
{
unsigned char i;
/*********************************************************
* The TBUF is 2 BYTES ;
* TDL use one byte;
* register address use one byte,send second,it will auto receive
* the ACK from slave;
**********************************************************/
U2C0_IIC_vWriteData(U2C0TDF_MStart, ISL1208_IDW); //start signal & identification byte(to write)
U2C0_IIC_vWriteData(U2C0TDF_MTxData,(base_addr&0x0F)); //address byte
for(i=0;i<no_of_bytes;i++)
{
U2C0_IIC_vWriteData(U2C0TDF_MTxData,i2c_data[i]); //data byte
}
U2C0_IIC_vWriteData(U2C0TDF_MStop,0X00); //stop signal
return;
}
void ReadBytesFromISL1208(unsigned char *i2c_data, unsigned char no_of_bytes, unsigned char base_addr)
{
unsigned char i;
U2C0_IIC_vWriteData(U2C0TDF_MStart, ISL1208_IDW); //start signal & identification byte(to write)
U2C0_IIC_vWriteData(U2C0TDF_MTxData,base_addr); //address byte
U2C0_IIC_vWriteData(U2C0TDF_MRStart, ISL1208_IDR); //Restart signal & identification byte (to Read)
for(i=0;i<no_of_bytes;i++)
{
if(i<(no_of_bytes-1))
{
U2C0_IIC_vWriteData(U2C0TDF_MRxAck0,0X00); //send ACK to IS1208 and go on read
i2c_data[i] = (unsigned char)U2C0_IIC_uwReadData();
}
else
{
U2C0_IIC_vWriteData(U2C0TDF_MRxAck1,0X00); //send ACK to IS1208 and stop read
i2c_data[i] = (unsigned char)U2C0_IIC_uwReadData();
}
}
U2C0_IIC_vWriteData(U2C0TDF_MStop,0X00); //stop signal
return;
}