/**
************************************************************
************************************************************
************************************************************
* 文件名: fm_rtc_i2c.c
*
* 作者: 庞作超
*
* 日期: 2018-9-21
*
* 版本: V1.0
*
* 说明: iic硬件初始化、软件模拟iic驱动
*
* 修改记录:
************************************************************
************************************************************
************************************************************
**/
#include "fm_rtc_i2c.h"
#include "delay.h"
#include "PCF8563.h"
#include "si47xx.h"
//类型定义
#include "typedef.h"
#include "system_task.h"
IIC_ControlDef IIC_ControlStruct;
/*
************************************************************
* 函数名称: IIC_SpeedCtl
*
* 函数功能: 软件IIC速度控制
*
* 入口参数: 延时参数
*
* 返回参数: 无
*
* 说明: 单位:微秒
************************************************************
*/
void IIC_SpeedCtl ( unsigned short Speed )
{
IIC_ControlStruct.IIC_Speed = Speed;
}
/*
************************************************************
* 函数名称: IIC_Read_Speed
*
* 函数功能: 读取IIC速度
*
* 入口参数: 无
*
* 返回参数: 速度值
*
* 说明: 单位:微秒
************************************************************
*/
unsigned short IIC_Read_Speed ( void )
{
return IIC_ControlStruct.IIC_Speed;
}
/*
************************************************************
* 函数名称: Si47xx_IIC_Init
*
* 函数功能: Si47xx软件IIC总线IO初始化度
*
* 入口参数: 无
*
* 返回参数: 无
*
* 说明: 使用开漏方式,这样可以不用切换IO口的输入输出方向
* IIC2:PB10--SCL PB11--SDA
************************************************************
*/
void Si47xx_IIC_Init ( void )
{
GPIO_InitTypeDef gpioInitStruct;
RCC_APB2PeriphClockCmd (SI47XX_IIC_CLK, ENABLE );
gpioInitStruct.GPIO_Mode = GPIO_Mode_Out_OD; //开漏,这样不用去切换输出输入方向
gpioInitStruct.GPIO_Pin =SI47XX_IIC_SDA_PIN|SI47XX_IIC_SCL_PIN;
gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init (SI47XX_IIC_PORT, &gpioInitStruct );
IIC_SpeedCtl ( 5 );
Si47xx_SDA_H; //拉高SDA线,处于空闲状态
Si47xx_SCL_H; //拉高SCL线,处于空闲状态
}
/*
************************************************************
* 函数名称: Pcf8563_IIC_Init
*
* 函数功能: Pcf8563软件IIC总线IO初始化度
*
* 入口参数: 无
*
* 返回参数: 无
*
* 说明: 使用开漏方式,这样可以不用切换IO口的输入输出方向
* IIC1:PB6--SCL PB7--SDA
************************************************************
*/
void Pcf8563_IIC_Init ( void )
{
GPIO_InitTypeDef gpioInitStruct;
RCC_APB2PeriphClockCmd (PCF8563_IIC_CLK, ENABLE );
gpioInitStruct.GPIO_Mode = GPIO_Mode_Out_OD; //开漏,这样不用去切换输出输入方向
gpioInitStruct.GPIO_Pin =PCF8563_IIC_SDA_PIN|PCF8563_IIC_SCL_PIN;
gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init (PCF8563_IIC_PORT, &gpioInitStruct );
IIC_SpeedCtl ( 5 );
Si47xx_SDA_H; //拉高SDA线,处于空闲状态
Si47xx_SCL_H; //拉高SCL线,处于空闲状态
}
/*
************************************************************
* 函数名称: Si47xx_IIC_Start
*
* 函数功能: 软件IIC开始信号
*
* 入口参数: 无
*
* 返回参数: 无
*
* 说明:
************************************************************
*/
void Si47xx_IIC_Start ( void )
{
Si47xx_SDA_H; //拉高SDA线
Si47xx_SCL_H; //拉高SCL线
DelayUs ( IIC_Read_Speed() ); //延时,速度控制
Si47xx_SDA_L; //当SCL线为高时,SDA线一个下降沿代表开始信号
DelayUs ( IIC_Read_Speed() ); //延时,速度控制
Si47xx_SCL_L; //钳住SCL线,以便发送数据
}
/*
************************************************************
* 函数名称: Pcf8563_IIC_Start
*
* 函数功能: 软件IIC开始信号
*
* 入口参数: 无
*
* 返回参数: 无
*
* 说明:
************************************************************
*/
void Pcf8563_IIC_Start ( void )
{
Pcf8563_SDA_H; //拉高SDA线
Pcf8563_SCL_H; //拉高SCL线
DelayUs ( IIC_Read_Speed() ); //延时,速度控制
Pcf8563_SDA_L; //当SCL线为高时,SDA线一个下降沿代表开始信号
DelayUs ( IIC_Read_Speed() ); //延时,速度控制
Pcf8563_SCL_L; //钳住SCL线,以便发送数据
}
/*
************************************************************
* 函数名称: Si47xx_IIC_Stop
*
* 函数功能: 软件IIC停止信号
*
* 入口参数: 无
*
* 返回参数: 无
*
* 说明:
************************************************************
*/
void Si47xx_IIC_Stop ( void )
{
Si47xx_SDA_L; //拉低SDA线
Si47xx_SCL_L; //拉低SCL先
DelayUs ( IIC_Read_Speed() ); //延时,速度控制
Si47xx_SCL_H; //拉高SCL线
Si47xx_SDA_H; //拉高SDA线,当SCL线为高时,SDA线一个上升沿代表停止信号
DelayUs ( IIC_Read_Speed() );
}
/*
************************************************************
* 函数名称: Pcf8563_IIC_Stop
*
* 函数功能: 软件IIC停止信号
*
* 入口参数: 无
*
* 返回参数: 无
*
* 说明:
************************************************************
*/
void Pcf8563_IIC_Stop ( void )
{
Pcf8563_SDA_L; //拉低SDA线
Pcf8563_SCL_L; //拉低SCL先
DelayUs ( IIC_Read_Speed() ); //延时,速度控制
Pcf8563_SCL_H; //拉高SCL线
Pcf8563_SDA_H; //拉高SDA线,当SCL线为高时,SDA线一个上升沿代表停止信号
DelayUs ( IIC_Read_Speed() );
}
/*
************************************************************
* 函数名称: Si47xx_IIC_WaitAck
*
* 函数功能: 软件IIC等待应答
*
* 入口参数: 无
*
* 返回参数: timeOut:超时时间
*
* 说明:
************************************************************
*/
_Bool Si47xx_IIC_WaitAck ( unsigned int TimeOut )
{
Si47xx_SDA_H;
DelayUs ( IIC_Read_Speed() ); //拉高SDA线
Si47xx_SCL_H;
DelayUs ( IIC_Read_Speed() ); //拉高SCL线
while ( Si47xx_SDA_R ) //如果读到SDA线为1,则等待。应答信号应是0
{
if ( --TimeOut )
{
Si47xx_IIC_Stop(); //超时未收到应答,则停止总线
return IIC_ERR; //返回失败
}
DelayUs ( IIC_Read_Speed() );
}
Si47xx_SCL_L; //拉低SCL线,以便继续收发数据
return IIC_OK; //返回成功
}
/*
************************************************************
* 函数名称: Pcf8563_IIC_WaitAck
*
* 函数功能: 软件IIC等待应答
*
* 入口参数: 无
*
* 返回参数: timeOut:超时时间
*
* 说明:
************************************************************
*/
_Bool Pcf8563_IIC_WaitAck ( unsigned int TimeOut )
{
Pcf8563_SDA_H;
DelayUs ( IIC_Read_Speed() ); //拉高SDA线
Pcf8563_SCL_H;
DelayUs ( IIC_Read_Speed() ); //拉高SCL线
while ( Pcf8563_SDA_R ) //如果读到SDA线为1,则等待。应答信号应是0
{
if ( --TimeOut )
{
Pcf8563_IIC_Stop(); //超时未收到应答,则停止总线
return IIC_ERR; //返回失败
}
DelayUs ( IIC_Read_Speed() );
}
Pcf8563_SCL_L; //拉低SCL线,以便继续收发数据
return IIC_OK; //返回成功
}
/*
************************************************************
* 函数名称: Si47xx_IIC_Ack
*
* 函数功能: 软件IIC产生一个应答
*
* 入口参数: 无
*
* 返回参数: 无
*
* 说明: 当SDA线为低时,SCL线一个正脉冲代表发送一个应答信号
************************************************************
*/
void Si47xx_IIC_Ack ( void )
{
Si47xx_SCL_L; //拉低SCL线
Si47xx_SDA_L; //拉低SDA线
DelayUs ( IIC_Read_Speed() );
Si47xx_SCL_H; //拉高SCL线
DelayUs ( IIC_Read_Speed() );
Si47xx_SCL_L; //拉低SCL线
Si47xx_SDA_H;
}
/*
************************************************************
* 函数名称: Pcf8563_IIC_Ack
*
* 函数功能: 软件IIC产生一个应答
*
* 入口参数: 无
*
* 返回参数: 无
*
* 说明: 当SDA线为低时,SCL线一个正脉冲代表发送一个应答信号
************************************************************
*/
void Pcf8563_IIC_Ack ( void )
{
Pcf8563_SCL_L; //拉低SCL线
Pcf8563_SDA_L; //拉低SDA线
DelayUs ( IIC_Read_Speed() );
Pcf8563_SCL_H; //拉高SCL线
DelayUs ( I