一、 I2C
1. I2C概要
I2C总线由SDA和SCL构成的2线式双向通信,通过组合这2个信号,进行通信的开始/停止/数据传送/应答等接收信号。
非通信时:SDA、SCL都保持高电平。
通信的开始和结束通过SCL处于高电平,切上升或者下降SDA来控制。
数据的传送及发送信号时的SDA线上的数据变更在SCL线低电平区间进行,接收信号侧在SCL线处于高电平区间进行读取数据,任何情况下,都在SCL线的每一计时器脉冲以1bit逐步进行。
I2C总线的器件没有通常的逻辑器件所具有的芯片选择引脚,代之以对的是器件分配从地址,当接收器的从地质与选择从地址一致时,开始通信。
2. I2C通信的开始和停止
3、I2C数据的传送
4、I2C数据的应答
5、从地址
6、写时序
7、读时序(RX8025官网资料中的读时序是错误的,经过测试,下图中的时序是正确的)
二、I2C及RX8025AC驱动
#include "myiic.h"
#include "delay.h"
void Delayus(u16 us)
{
u16 i;
for(i=0;i<us;i++)
__nop();
}
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //ÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB6,PB7 Êä³ö¸ß
}
void IIC_Start(void)
{
SDA_OUT();
SCL_1
SDA_1
Delayus(10);
SDA_0
Delayus(10);
SCL_0
Delayus(10);
}
void IIC_Stop(void)
{
u8 i;
SDA_OUT();//sdaÏßÊä³ö
SDA_0
Delayus(10);
SCL_1
Delayus(10);
SDA_1
for(i=0;i<5;i++)
{
Delayus(10);
}
}
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDAÉèÖÃΪÊäÈë
Delayus(10);
Delayus(10);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
SCL_0//ʱÖÓÊä³ö0
return 0;
}
void IIC_Ack(void)
{
SDA_OUT();
SDA_0;
Delayus(10);
SCL_1
Delayus(10);
SCL_0
Delayus(10);
}
void IIC_NAck(void)
{
SDA_OUT();
SDA_1;
Delayus(10);
SCL_1
Delayus(10);
SCL_0
Delayus(10);
}
void IIC_Send_Byte(u8 txd)
{
u8 i;
SDA_OUT();
for(i=0;i<8;i++)
{
if(txd & 0x80) SDA_1
else SDA_0
txd <<= 1;
Delayus(10);
SCL_1
Delayus(10);
SCL_0
}
Delayus(10);
SCL_1
Delayus(10);
SCL_0
}
u8 IIC_Read_Byte(unsigned char ack)
{
u8 i,receive=0;
SDA_IN();//SDAÉèÖÃΪÊäÈë
for(i=0;i<8;i++)
{
SCL_1
Delayus(10);
receive <<=1;
if(READ_SDA) receive |= 0x01;
SCL_0
Delayus(10);
}
SDA_OUT();
return receive;
}
void R8025AC_Read(u8 sadd, u8 *buf, u8 len)
{
u8 i;
IIC_Start();
IIC_Send_Byte(0x64);
IIC_Send_Byte(sadd<<4|0x01);
IIC_Start();
IIC_Send_Byte(0x65);
for(i=0;i<len-1;i++)
{
buf[i] = IIC_Read_Byte(1);
IIC_Ack();
}
buf[i] = IIC_Read_Byte(0);
IIC_NAck();
IIC_Stop();
}
void R8025AC_Write(u8 sadd,u8 *buf,u8 len)
{
u8 i;
IIC_Start();
IIC_Send_Byte(0X64);
IIC_Send_Byte(sadd<<4);
for(i=0;i<len;i++)
{
IIC_Send_Byte(buf[i]);
}
IIC_Stop();
}