#include "myiic.h"
#include "delay.h"
//已删除所有延时 1 - 2us延时 若IIC通信出错或许是没有延时问题
//或者时钟源问题
void IIC_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
/****************************IIC_SDA初始化***********************************************/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_IIC_SDA_PORT, ENABLE); //使能SDA连接端口时钟 /
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SDA; //SDA端口配置 /
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 /
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz /
GPIO_Init(GPIO_SDA_PORT, &GPIO_InitStructure); //根据设定参数初始化SDA /
/****************************IIC_SCL初始化***********************************************/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_IIC_SCL_PORT, ENABLE); //使能SCL连接端口时钟 /
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SCL; //SCL端口配置 /
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 /
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz /
GPIO_Init(GPIO_SCL_PORT, &GPIO_InitStructure); //根据设定参数初始化SCL /
/****************************************************************************************/
}
/**********************************************/
// IIC Start
//开始信号:在SCL为高电平时,SDA由高电平向低电平跳变,开始传输数据。
/**********************************************/
void IIC_Start()
{
SDA_OUT();
IIC_SCL=1;
IIC_SDA=1;
delay_us(2);
IIC_SDA=0;
delay_us(2);
IIC_SCL=0;
}
/**********************************************/
// IIC Stop
//结束信号:在SCL为高电平时,SDA由低电平向高电平跳变,结束传输数据。
/**********************************************/
void IIC_Stop()
{
SDA_OUT();
IIC_SCL=1;
IIC_SDA=0;
delay_us(2);
IIC_SDA=1;
delay_us(2);
}
/**********************************************/
// IIC主机产生ACK应答信号
/**********************************************/
void IIC_ACK(void)
{
SDA_OUT();
IIC_SCL=0;
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
/**********************************************/
// IIC主机不产生ACK应答信号
/**********************************************/
void IIC_NACK(void)
{
SDA_OUT();
IIC_SCL=0;
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
/**********************************************/
// IIC Wait Ack
//等待应答信号到来
//返回值 1,接收应答失败
// 0,接收应答成功
/**********************************************/
unsigned char IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;
IIC_SCL=1;
delay_us(2);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
/**********************************************
// IIC Write byte
//IIC写一个字节
**********************************************/
void IIC_Write_Byte(unsigned char data)
{
unsigned char i;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(i=0;i<8;i++)
{
IIC_SDA=(data&0x80)>>7;
data=data<<1;
// delay_us(2); //对TEA5767芯片这三个延时都是必须的
IIC_SCL=1;
// delay_us(2);
IIC_SCL=0;
// delay_us(2);
}
}
/**********************************************
// IIC Write Data
**********************************************/
void IIC_Write_Data(unsigned char Device_addr,unsigned char Reg_addr,unsigned char data)
{
IIC_Start();
SDA_OUT();
IIC_Write_Byte(Device_addr | 0x00); //器件地址(7位) + 读写位(读1写0)
IIC_Wait_Ack();
IIC_Write_Byte(Reg_addr); //要写入数据的寄存器地址
IIC_Wait_Ack();
IIC_Write_Byte(data);
IIC_Wait_Ack();
IIC_Stop();
}
/**********************************************
// IIC Read byte
//IIC读一个字节
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
**********************************************/
unsigned char IIC_Read_Byte(unsigned char Ack_EN)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!Ack_EN)
IIC_NACK();//发送nACK
else
IIC_ACK(); //发送ACK
return receive;
}
/**********************************************
// IIC Read Data
**********************************************/
unsigned char IIC_Read_Data(unsigned char Device_addr,unsigned char Reg_addr,unsigned char ACK_EN)
{
unsigned char receive;
IIC_Start();
IIC_Write_Byte(Device_addr | 0x00); //器件地址(7位) + 读写位(写0)
IIC_Wait_Ack();
IIC_Write_Byte(Reg_addr); //要读数据的寄存器地址
IIC_Wait_Ack();
IIC_Start();
SDA_IN();
IIC_Write_Byte(Device_addr | 0x01); //器件地址(7位) + 读写位(读1)
IIC_Wait_Ack();
receive=IIC_Read_Byte(0);
IIC_Wait_Ack();
IIC_Stop();
return receive;
}
|