IIC 协议在英飞凌公司产品 XE164 上实现

来源:互联网 发布:node实现反向代理跨域 编辑:程序博客网 时间:2024/04/30 14:38

/*

 * =====================================================================================

 *       Author:  cdutyangshaokun@163.com

 * =====================================================================================

 */

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;

}

原创粉丝点击