/****************************************************************************** 文 件 名:Simulated_IIC_Master.c 功能描述:IO端口模拟的IIC(I2C)主机函数库文件 作 者:张暄 版 本:V1.0 日 期:2016.12.21 ******************************************************************************/ #include "Simulated_IIC_2_Master.h" #include "RTE_GPIO.h" #include "TYW_stdint.h" #include "RTE_GPIO.h" #include "rh850_macros.h" uint8_t u8SimulatedIIC2ReceivedACK; #define SIMULATED_IIC_2_SCL SDB_LED_SCL //SCL信号 #define SIMULATED_IIC_2_SCL_DIR SDB_LED_SCL_DIR //SCL方向 #define SIMULATED_IIC_2_OUT_SDA SDB_LED_SDA //SDA信号 #define SIMULATED_IIC_2_IN_SDA SDB_LED_SDA_IN #define SIMULATED_IIC_2_SDA_DIR SDB_LED_SDA_DIR //SDA方向 /****************************************************************************** 函数名:IIC_Init 功 能:初始化IIC总线 参 数:无 返回值:无 ******************************************************************************/ void Simulated_IIC_2_Init(void) { SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_IN; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_IN; //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK; } /****************************************************************************** 函数名:IIC_Start 功 能:在IIC总线上发送起始信号,发起一次IIC通信 参 数:无 返回值:无 ******************************************************************************/ void Simulated_IIC_2_Start(void) { u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK; SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_IN; //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_IN; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_OUT; //SDA输出0,此时SDA = 0 SIMULATED_IIC_2_OUT_SDA = 0; Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_OUT; //SCL输出0,此时SCL = 0 SIMULATED_IIC_2_SCL = 0; Simulated_IIC_2_Delay( ); } /****************************************************************************** 函数名:IIC_Stop 功 能:在IIC总线上发送停止信号,终止当前IIC通信 参 数:无 返回值:无 ******************************************************************************/ void Simulated_IIC_2_Stop(void) { u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK; SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_OUT; //SDA输出0,此时SDA = 0 SIMULATED_IIC_2_OUT_SDA = 0; Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_IN; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_IN; //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); } /****************************************************************************** 函数名:IIC_Transmit_Data 功 能:向IIC总线上发送1字节数据 参 数:Data:发送的数据 返回值:总线上器件的确认(ACK) 0 - ACK 1 - NAK ******************************************************************************/ void Simulated_IIC_2_Transmit_Data(uint8_t Data) { uint8_t i; u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK; for ( i = 0; i < 8; i++ ) { if ( Data & 0x80 ) SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_IN; //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1 else { SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_OUT; //SDA输出0,此时SDA = 0 SIMULATED_IIC_2_OUT_SDA = 0; } Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_IN; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_OUT; //SCL输出0,此时SCL = 0 SIMULATED_IIC_2_SCL = 0; Simulated_IIC_2_Delay( ); Data <<= 1; } SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_IN; //设置SDA为输入状态 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_IN; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_IN_SDA; SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_OUT; //SCL输出0,此时SCL = 0 SIMULATED_IIC_2_SCL = 0; Simulated_IIC_2_Delay( ); } /****************************************************************************** 函数名:IIC_Receive_Data 功 能:从IIC总线上接收1字节数据 参 数:无 返回值:接收到的数据 ******************************************************************************/ uint8_t Simulated_IIC_2_Receive_Data(void) { uint8_t i; uint8_t Data; Data = 0; SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_IN; //设置SDA为输入状态 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); for ( i = 0; i < 8; i++ ) { Data <<= 1; SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_IN; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); Data |= SIMULATED_IIC_2_IN_SDA; SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_OUT; //SCL输出0,此时SCL = 0 SIMULATED_IIC_2_SCL = 0; Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); } return Data; } /****************************************************************************** 函数名:IIC_Transmit_ACK 功 能:向IIC总线上发送确认信号 参 数:ACK:确认信号的类型: SIMULATED_IIC_2_ACK 肯定应答 IIC_NAK 否定应答 返回值:无 ******************************************************************************/ void Simulated_IIC_2_Transmit_ACK(uint8_t ACK) { u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK; if ( ACK > SIMULATED_IIC_2_NAK ) return; if ( ACK ) SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_IN; //SDA被设置为输入,IO口为高阻状态,总线上SDA信号由上拉电阻拉高,此时SDA = 1 else { SIMULATED_IIC_2_SDA_DIR = GPIO_DIR_OUT; //SDA输出0,此时SDA = 0 SIMULATED_IIC_2_OUT_SDA = 0; } Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_IN; //SCL被设置为输入,IO口为高阻状态,总线上SCL信号由上拉电阻拉高,此时SCL = 1 Simulated_IIC_2_Delay( ); Simulated_IIC_2_Delay( ); SIMULATED_IIC_2_SCL_DIR = GPIO_DIR_OUT; //SCL输出0,此时SCL = 0 SIMULATED_IIC_2_SCL = 0; Simulated_IIC_2_Delay( ); } /****************************************************************************** 函数名:IIC_Receive_ACK 功 能:获取从总线上接收到的确认信号 参 数:无 返回值:总线上器件的确认信号类型:Simulated_IIC_ACK 肯定应答 SIMULATED_IIC_2_NAK 否定应答 IIC_INVALID_ACK 无效的应答信号(应答信号还未收到) ******************************************************************************/ uint8_t Simulated_IIC_2_Receive_ACK(void) { uint8_t ACK; ACK = u8SimulatedIIC2ReceivedACK; u8SimulatedIIC2ReceivedACK = SIMULATED_IIC_2_INVALID_ACK; return ACK; } /****************************************************************************** 函数名:IIC_Delay 功 能:延时5us,用于收发过程中的时序控制 注意:必须调整IIC_5us_DELAY_CALIBRATION参数校准延时时间在5us左右 参 数:ACK:确认信号的类型 0 - ACK 1 - NAK 返回值:无 ******************************************************************************/ void Simulated_IIC_2_Delay(void) { uint8_t i; for ( i = 0; i < SIMULATED_IIC_2_FREQ_CALIBRATION; i++ ) { nop( ); } }