/*************笔记****************
1、CubeMX 定义任意两个引脚,作为通讯脚,并对引脚作出如下配置:
GPlO output level --High
GPIO mode --Output open drai
GPIO Pull-up/Pull-down --No pull-up and no pull-down
Maximum output speed --LOW
User label --IIC_SCL/IIC_SDA
IIC_SCL--PB6 IIC_SDA--PB7
---------------------------------------------------------
***********************************/
#include "hal_iic.h"
/**********************************************************************/
// 功能描述:用于IIC通讯时延时,以满足IIC对时序的要求(内部使用)
// 输入参数:cnt 延时记数器 (定义成volatile防止被优化掉)
// 返 回 值:无
// 编写时间:2014.11.21
// 作 者:
// 修改记录:
/**********************************************************************/
//#pragma optimize= none
void IIC_Delay(volatile uint32_t cnt)
{
while(cnt--);
}
/**********************************************************************/
// 功能描述: IIC使能初始化
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:无
// 编写时间:2014.11.21
// 作 者:
// 修改记录:
/**********************************************************************/
void IIC_Init(const IIC_PIN *I)
{
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1); //SCL = 1
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1); //SDA = 1
}
/**********************************************************************/
// 功能描述: IIC通讯开始
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:无
// 编写时间:2014.11.21
// 作 者:胡安勤
// 修改记录:
/**********************************************************************/
void IIC_Start (const IIC_PIN *I)//
{
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1); //SDA = 1
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1); //SCL = 1
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 0); //SDA = 0
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0); //SCL = 0
IIC_Delay(I->DelayTick);
}
/**********************************************************************/
// 功能描述: IIC通讯结束
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:无
// 编写时间:2014.11.21
// 作 者:
// 修改记录:
/**********************************************************************/
void IIC_Stop (const IIC_PIN *I)
{
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 0); //SDA = 0
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1); //SCL = 1
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1); //SDA = 1
IIC_Delay(I->DelayTick);
}
/**********************************************************************/
// 功能描述: IIC从设备应答
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:0: 设备应答正常 1: 设备无应答
// 编写时间:2014.11.21
// 作 者:
// 修改记录:
/**********************************************************************/
IIC_STATUS IIC_Wait_ACK(const IIC_PIN *I)
{
uint8_t s1;
uint8_t i = 0;
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1); //SCL = 1
IIC_Delay(I->DelayTick);
s1 = GPIO_READ_PIN(I->SDA_PORT, I->SDA_PIN);
while (s1 && i++ < 100) //判断是否应答 0应答,1无答
{
s1 = GPIO_READ_PIN(I->SDA_PORT, I->SDA_PIN);
}
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0); //SCL = 0
IIC_Delay(I->DelayTick);
if(s1)
{
return(IIC_WAIT_ACK_ERR);
}
else
{
return(IIC_OK);
}
}
/**********************************************************************/
// 功能描述: 主设备应答
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:无
// 编写时间:2014.11.21
// 作 者:
// 修改记录:
/**********************************************************************/
void IIC_ACK(const IIC_PIN *I)
{
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 0); //SDA = 0
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1); //SCL = 1
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0); //SCL = 0
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1); //SDA = 1
}
/**********************************************************************/
// 功能描述: 主设备非应答
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 返 回 值:无
// 编写时间:2014.11.21
// 作 者:
// 修改记录:
/**********************************************************************/
void IIC_NACK(const IIC_PIN *I)
{
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1); //SDA = 1
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1); //SCL = 1
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0); //SCL = 0
IIC_Delay(I->DelayTick);
}
/**********************************************************************/
// 功能描述: 发送一个字节
// 输入参数:I:结构体,定义IIC使用的PIN管脚 data: 待发送字节
// 返 回 值:无
// 编写时间:2014.11.21
// 作 者:
// 修改记录:
/**********************************************************************/
void IIC_WriteByte(const IIC_PIN *I, uint8_t data)
{
uint16_t i;
for(i = 0; i < 8; i++)
{
if((data & 0x80) == 0x80)
{
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1); //SDA = 1
}
else
{
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 0); //SDA = 0
}
data = data << 1;
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1); //SCL = 1
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0); //SCL = 0
//IIC_Delay(I->DelayTick);
}
IIC_Delay(I->DelayTick);
GPIO_WRITE_PIN(I->SDA_PORT, I->SDA_PIN, 1); //SDA = 1
}
/**********************************************************************/
// 功能描述: 从从设备接收一个字节
// 输入参数:I:结构体,定义IIC使用的PIN管脚
// 输出参数:data:读取到的字节
// 返 回 值:无
// 编写时间:2014.11.21
// 作 者:
// 修改记录:
/**********************************************************************/
void IIC_ReadByte(const IIC_PIN *I, uint8_t *data)
{
uint8_t tmp = 0;
uint8_t i;
IIC_Delay(I->DelayTick);
for(i = 0; i < 8; i++)
{
tmp = tmp << 1;
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 1); //SCL = 1
IIC_Delay(I->DelayTick);
if (GPIO_READ_PIN(I->SDA_PORT, I->SDA_PIN)) //读数据脚
{
tmp = tmp | 0x01;
}
else
{
tmp = tmp & 0xfe;
}
GPIO_WRITE_PIN(I->SCL_PORT, I->SCL_PIN, 0); //SCL = 0
IIC_Delay(I->DelayTick);
}
*data = tmp;
}