您的位置:首页 > 其它

IIC 通信实例

2015-03-30 14:45 162 查看
IIC

标签:

1、标准速率:100kbit/s、快速:400kbit/s、高速:4Mbit/s

2、2线通信协议

3、起始与停止:SCL高时,SDA由  高  -->  低(↓)  变化,起始信号;SDA由  低  -->  高(↑)  变化,停止信号

4、空闲状态:SDA和SCL都处于高电平状态

5、数据传输与应答:数据必须是8位,且高位在前(MSB),第9个脉冲周期由接收方发送应答信号(发送方同时等待这个应答信号),即接收方将SDA拉低(之前SDA为高)。(有时会将应答超时视作已接受到正确数据,有的地方则必须等待到应答信号,下面的例中就是后者)。

6、地址格式:7-4bit为器件类型,半导体公司生产时就已经固定了。3-1bit为器件地址位,一般用户自定义,例如EEPROM外部的3个引脚(A0,A1,A2)硬件电路的接法决定了其数值,所以一路IIC总线上同一型号的IC最多能接8个。最后一位就是R/W标记位了,0为写命令,1为读命令。

7、IIC总线进行数据传输时,SCL为高电平时SDA必须保持稳定才有效,只有SCL为低电平时才允许SDA有变化。

8、PHILIPS(飞利浦)开发

9、双向串行总线协议

C语言实现过程(基于摄像头NT99141控制协议的IIC通信实例)

#include <intrins.h>  

#define uint unsigned int

 #define uchar unsigned char

#define Delay( n)

//以下为伪定义,实际以芯片IO口配置为主

#define SET_SDA_OUT( )

#define SDA_OUT( )

#define SDA_H( )

#defien SDA_L( )

#define SET_SDA_IN( )

#defien SDA_IN( )

#defien SCL_H( )

#define SCL_L( )

#define delay( )

typedef u8 unsigned char;

void Start(void)

{

SDA_H( );

delay()

SCL_H;

delay( );
//SCL为高 SDA变低
↓,起始信号

SDA_L( );

delay( );

SDA_L( );

delay( );

}

void Stop(void)

{

SCL_L( );

delay( );

SDA_L( );

delay( );

SCL_H( );

delay( );//SCL为高 SDA变高↑,停止信号

SDA_H( );

delay( );

}

u8 WaitAck(void)

{

u8 tmp = 200;

SDA_H( );delay( );//拉高,等待应答被拉低

SET_SDA_IN( );delay( );

SCL_H( );delay( );

while(SDA_IN( ))

{

if(--tmp == 0)

{

Stop( );

return 0;

}

}

SCL_L( );

return 1;

}

void Ack(void)

{

SCL_L( );

delay( );

SDA_L( );//应答,拉低

delay( );

SCL_H( );

delay( );

SCL_L( );

delay( );

}

void NoAck(void)

{

SCL_L( );

delay( );

SDA_H( );

delay( );

SCL_H( );

delay( );

SCL_L( );

delay( );

}

u8 Writ
4000
eByte(u8 data)

{

u8 i,ret = 0;

SCL_L( );

delay( );

for(i = 0 ; i < 8 ; i++)

{

if(data & 0x80)

{

SDA_H( );

}

else

{

SDA_L( );

}

data <<= 1;

delay( );

SCL_H( );

delay( );

SCL_L( );

delay( );

}

delay( );

ret = WaitAck( );//发送完一个字节后等待对方发送应答信号

SET_SDA_OUT( );

return (ret);//返回应答状态,为0证明应答失败,为1应答正常

}

u8 ReadByte(void)

{

u8 i,data = 0;

SET_SDA_IN;//需要设置SDA为输入以及是否上拉

delay( );

for(i = 0; i < 8 ; i++)

{

SCL_L( );

delay( );

SCL_H( );

delay( );

data <<= 1;

if(SDA_IN)
//此处直接读取SDA的状态

{

data += 1;

}

}

return data;

}

u8 WriteAddr(ADDR_T addr,u8 data)

{

u8 tmp = 0;

Start( );

if(0 == WriteByte(WCMD))goto _return;//发送写命令,本例中必须等到应答信号,否则认为丛机接收失败

//Delay(10);//选择性延时

if(0 == WriteByte(addr))goto _return;//发送写地址

//Delay(10);//选择性延时

if(0 == WriteByte(data))goto _return;//发送数据

tmp = 1;

_return:

Stop( );

return tmp;

}

u8 ReadAddr(u8 addr,u8 *data)

{

u8 tmp = 0;

Start( );

if(0 == WriteByte(WCMD))goto _return;//发送写命令

//Delay(10);//选择性延时

if(0 == WriteByte(addr))goto _return;//发送读地址

Stop( );

//Delay(10);//选择性延时

Start( );

if(0 == WriteByte(RCMD))goto _return;//发送读命令

//Delay(10);//选择性延时

*data = ReadByte( );   //读数据

_return:

Stop( );

return tmp;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  通信 IIC