IIC 通信实例

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 WriteByte(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;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值