//为啥用软件模拟IIC而不用硬件IIC? 除了ST的IIC模块本身问题,还因为硬件IIC移植不方便,在不同的MCU中无法通用。
/****************************Copyright(c)*********************************************
**--------------文件信息--------------------------------------------------------------
** 文 件 名:
** 创 建 人: 温世坚(wenshijian4@163.com)
** 创建日期: 2015年9月18日
** 描 述:
**---------- 版本信息------------------------------------------------------------------
** 版 本: V2.92
** 说 明:
**-------------------------------------------------------------------------------------
**************************************************************************************/
#include"IIC_Recv.h"
/****************************************************************************************
** 函数名称: IIC_ReadSilent
** 功能描述: 读取IIC数据,并返回数据长度及数据内容
** 参 数: *IIC_Recv :用于接收IIC数据的数组
** 返 回 值: 接收到的数据长度(以字节为单位)
** 日 期: 2015年4月17日
**---------------------------------------------------------------------------------------
** 修 改 人: 温世坚
** 日 期:
**--------------------------------------------------------------------------------------
****************************************************************************************/
unsigned char IICx_Lens;
unsigned char ibit,Sda;
unsigned intSCL_H_Len,SCL_L_Len;
//简单延时函数1
void IIC_Delay(void)
{
u8 time=40;//60;//减少延时时间,20160707,待测试,WEN
while(time--);
}
//简单延时函数2
void IIC_DelayUS(u8 us)
{
while(us--);
}
//IIC 起始逻辑
u8 IIC_Start(void)
{
SCL_H;
SDA_H;
IIC_Delay();//IIC_DelayUS(20);
if(!Read_SDA)
return 0;
SDA_L;
IIC_Delay();
if(Read_SDA)
return 0;
SCL_L;
IIC_Delay();
return 1;
}
//IIC停止逻辑
void IIC_Stop(void)
{
SCL_H;
SDA_L;
IIC_Delay();//IIC_DelayUS(20);
SDA_H;
IIC_Delay();//IIC_DelayUS(20);
}
/****************************************************************************************
** 函数名称: IIC_WriteByte
** 功能描述: 操作SDL,SDA,发送数据到IIC总线
** 参 数: *IIC_Recv :用于接收IIC数据的数组
** 返 回 值: 1:发送成功;0:发送失败
** 日 期: 2016年07月06日
**---------------------------------------------------------------------------------------
** 修 改 人: WEN
** 日 期:
**--------------------------------------------------------------------------------------
****************************************************************************************/
u8 IIC_WriteByte(u8 byte)
{
u8 i=8;
u8 mask=0x80;
while(i--)
{
SCL_L;
IIC_DelayUS(10);//IIC_Delay();//此处调整延时,减小延时时间,20160706,WEN
if(byte&mask)
SDA_H;
else
SDA_L;
mask>>=1;
IIC_DelayUS(10);//IIC_Delay();//此处调整延时,减小延时时间,20160706,WEN
SCL_H;
IIC_DelayUS(20);//IIC_Delay();//此处调整延时,减小延时时间,20160706,WEN
}
SCL_L;
SDA_H;
IIC_DelayUS(20);//IIC_Delay();//此处调整延时,减小延时时间,20160706,WEN
SCL_H;
IIC_DelayUS(20);//IIC_Delay();//此处调整延时,减小延时时间,20160706,WEN
if(Read_SDA)
{
SCL_L;
return 0;
}
SCL_L;
return 1;
}
u8 IIC_ReadByte_ACK(void)
{
u8 i=8;
u8 byte=0;
SDA_H;
while(i--)
{
byte<<=1;
SCL_L;
IIC_DelayUS(20);//IIC_Delay();//此处调整延时,减小延时时间,20160706,WEN
SCL_H;
IIC_DelayUS(20);//IIC_Delay();//此处调整延时,减小延时时间,20160706,WEN
if(Read_SDA)
byte|=0x01;
}
SCL_L;
IIC_Delay();
SDA_L;
IIC_Delay();
SCL_H;
IIC_Delay();
SCL_L;
return byte;
}
u8 IIC_ReadByte_NACK(void)
{
u8 i=8;
u8 byte=0;
SDA_H;
while(i--)
{
byte<<=1;
SCL_L;
IIC_DelayUS(20);//IIC_Delay();//此处调整延时,减小延时时间,20160706,WEN
SCL_H;
IIC_DelayUS(20);//IIC_Delay();//此处调整延时,减小延时时间,20160706,WEN
if(Read_SDA)
byte|=0x01;
}
SCL_L;
IIC_Delay();
SDA_H;
IIC_Delay();
SCL_H;
IIC_Delay();
SCL_L;
return byte;
}
/****************************************************************************************
** 函数名称: IIC_Write
** 功能描述: 往IIC指定地址写一个字节数据
** 参 数: u8 addr,u8 byte
** 返 回 值: 1:成功;0:失败
** 日 期: 2016年07月06日
**---------------------------------------------------------------------------------------
** 修 改 人: WEN
** 日 期:
**--------------------------------------------------------------------------------------
****************************************************************************************/
u8 IIC_Write(u8 addr,u8 byte)
{
if(!IIC_Start())return 0;
if(!IIC_WriteByte(addr)){IIC_Stop();return 0;}
if(!IIC_WriteByte(byte)){IIC_Stop();return 0;}
return 1;
}
/****************************************************************************************
** 函数名称: IIC_WriteEnd
** 功能描述: 往IIC写固定数据,使IIC的INT线恢复高电平,即取消中断
** 参 数:
** 返 回 值: 1:发送成功;0:发送失败
** 日 期: 2016年07月06日
**---------------------------------------------------------------------------------------
** 修 改 人: 温世坚
** 日 期:
**--------------------------------------------------------------------------------------
****************************************************************************************/
u8 IIC_WriteEnd()
{
if(!IIC_Start())return 0;
if(!IIC_WriteByte(0xB8)){IIC_Stop();return 0;}
if(!IIC_WriteByte(0x3E)){IIC_Stop();return 0;}
if(!IIC_WriteByte(0xFF)){IIC_Stop();return 0;}
IIC_Stop();
return 1;
}
/****************************************************************************************
** 函数名称: IIC_MasterRead
** 功能描述: 从特定地址读取固定长度的数据,然后通过指针返回数据
** 参 数: u8 *IIC_R :用于接收IIC数据的数组
** 返 回 值: 接收到的数据长度
** 日 期: 2016年07月06日
**---------------------------------------------------------------------------------------
** 修 改 人: WEN
** 日 期:
**--------------------------------------------------------------------------------------
****************************************************************************************/
u8 IIC_MasterRead(u8*IIC_Recv)
{
u8 j;
if(!IIC_Start())return 0;
if(!IIC_WriteByte(0xB8)){IIC_Stop();return 0;}
if(!IIC_WriteByte(0x20)){IIC_Stop();return 0;}
if(!IIC_Start()){IIC_Stop();return 0;}
if(!IIC_WriteByte(0xB9)){IIC_Stop();return 0;}
for(j=0;j<6;j++)//11
{
IIC_Recv[j]=IIC_ReadByte_ACK();
}
IIC_Recv[j]=IIC_ReadByte_NACK();
IIC_Stop();
return 12;
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』