/*-------------------------------------------------------------------------------------- * @file IICSetup.c * @author ZhangJing * @version base on stm32f0x * @date 2015.09.11 * @brief 模拟IIC驱动 ---------------------------------------------------------------------------------------*/ #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "TypeDefine.h" #include "IICSetup.h" /****************************************************************************** *函数名: TWI_Delay * *功能描述: 延时函数 * *输入参数: 无 * *输出参数: 无 * *返回值: 无 * ******************************************************************************/ void TWI_Delay(void) { uint8_t i = 15; while(i--); } void RTC_Delay(void) { uint16_t i = 500; while(i--); } /************************************************************************************* * Function: IICInit * Object: 用I/O口模拟的IIC初始化 * 输入: 无 * 输出: 无 * 备注: 1、用 GPIOA的PIN4/PIN5 GPIOE的PIN2/PIN3作为IIC模拟引脚 **************************************************************************************/ void IICInit( void ) { /*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; // PA4-SDA PA5-SCL GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; TWI_SDA_1; TWI_SCL_1; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; // PE3-SDA PE2-SCL GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; RTC_SDA_1; RTC_SCL_1; GPIO_Init(GPIOE, &GPIO_InitStructure); } /************************************************************************************* * Function: TWI_START * Object: 发送启动 * 输入: 无 * 输出: 返回IIC总线状态 * 备注: **************************************************************************************/ uint8_t TWI_START(void) { TWI_SDA_1; TWI_NOP; TWI_SCL_1; TWI_NOP; if(!TWI_SDA_STATE) { ////DebugPrint("TWI_START:BUSY\n"); return TWI_BUS_BUSY; } TWI_SDA_0; TWI_NOP; if(TWI_SDA_STATE) { ////DebugPrint("TWI_START:BUS ERROR\n"); return TWI_BUS_ERROR; } TWI_SCL_0; TWI_NOP; return TWI_READY; } /************************************************************************************* * Function: TWI_STOP * Object: 发送停止位 * 输入: 无 * 输出: 无 * 备注: **************************************************************************************/ void TWI_STOP(void) { TWI_SCL_0; TWI_NOP; TWI_SDA_0; TWI_NOP; TWI_SCL_1; TWI_NOP; TWI_SDA_1; TWI_NOP; // TWI_SCL_0; // TWI_NOP; //////DebugPrint("TWI_STOP\n"); } /************************************************************************************* * Function: TWI_SendACK * Object: 收到数据发送ACK * 输入: 无 * 输出: 无 * 备注: **************************************************************************************/ void TWI_SendACK(void) { TWI_SCL_0; TWI_NOP; TWI_SDA_0; TWI_NOP; TWI_SCL_1; TWI_NOP; TWI_SCL_0; TWI_NOP; //////DebugPrint("TWI_SendACK\n"); } /************************************************************************************* * Function: TWI_SendNACK * Object: 收到数据发送NACK * 输入: 无 * 输出: 无 * 备注: **************************************************************************************/ void TWI_SendNACK(void) { TWI_SCL_0; TWI_NOP; TWI_SCL_1; TWI_NOP; TWI_SDA_1; TWI_NOP; TWI_SCL_0; TWI_NOP; //////DebugPrint("TWI_SendNACK\n"); } /************************************************************************************* * Function: TWI_WaitAck * Object: 收到数据等待ACK * 输入: 无 * 输出: 返回IIC总线状态 * 备注: **************************************************************************************/ uint8_t TWI_WaitAck(void) { TWI_SCL_0; TWI_NOP; TWI_SDA_1; TWI_NOP; TWI_SCL_1; TWI_NOP; if(TWI_SDA_STATE) { TWI_SCL_0; return 0x00; } TWI_SCL_0; return 0x01; } /************************************************************************************* * Function: TWI_SendByte * Object: 发送一个字节 * 输入: 要发送的数据(一个字节) * 输出: 返回IIC总线状态 * 备注: **************************************************************************************/ uint8_t TWI_SendByte(uint8_t Data) { uint8_t i; TWI_SCL_0; for(i=0;i<8;i++) { TWI_SCL_0; TWI_NOP; //数据建立保持一定延时 if(Data&0x80) { TWI_SDA_1; } else { TWI_SDA_0; } Data<<=1; TWI_NOP; TWI_SCL_1; TWI_NOP; } TWI_SCL_0; if(TWI_SDA_STATE) { // TWI_SCL_0; //////DebugPrint("TWI_NACK!\n"); return TWI_NACK; } else { // TWI_SCL_0; //////DebugPrint("TWI_ACK!\n"); return TWI_ACK; } } /************************************************************************************* * Function: TWI_ReceiveByte * Object: 接收一个字节 * 输入: 无 * 输出: 返回接收到的数据 * 备注: 1、uint8_t Dat = 0;按位做接收数据组合 **************************************************************************************/ uint8_t TWI_ReceiveByte(void) { uint8_t i,Dat = 0; TWI_SDA_1; //TWI_SCL_0; Dat=0; for(i=0;i<8;i++) { //TWI_SCL_1;//???????[???],???????? //TWI_NOP; Dat<<=1; TWI_SCL_0; TWI_NOP; TWI_SCL_1; TWI_NOP; if(TWI_SDA_STATE) //读引脚状态 { Dat|=0x01; } TWI_SCL_0;//准备好再次接收数据 //TWI_NOP;//等待数据准备好 } //////DebugPrint("TWI_Dat:%x\n",Dat); return Dat; } /************************************************************************************* * Function: RTC_START * Object: 发送启动 * 输入: 无 * 输出: 返回IIC总线状态 * 备注: **************************************************************************************/ uint8_t RTC_START(void) { RTC_SDA_1; RTC_SCL_1; RTC_NOP; if(!RTC_SDA_STATE) return RTC_BUS_BUSY; RTC_SDA_0; RTC_NOP; if(RTC_SDA_STATE) return RTC_BUS_ERROR; RTC_SCL_0; RTC_NOP; return RTC_READY; /* RTC_SDA_1; RTC_SCL_1; RTC_NOP; RTC_SDA_0; RTC_NOP; RTC_SCL_0; RTC_NOP; */ } /************************************************************************************* * Function: RTC_STOP * Object: 发送停止位 * 输入: 无 * 输出: 无 * 备注: **************************************************************************************/ void RTC_STOP(void) { /* RTC_SCL_1; RTC_SDA_0; RTC_NOP; RTC_SDA_1; RTC_NOP; */ RTC_SCL_0; RTC_NOP; RTC_SDA_0; RTC_NOP; RTC_SCL_1; RTC_NOP; RTC_SDA_1; RTC_NOP; // TWI_SCL_0; // TWI_NOP; //////DebugPrint("TWI_STOP\n"); } /************************************************************************************* * Function: TWI_SendACK * Object: 收到数据发送ACK * 输入: 无 * 输出: 无 * 备注: **************************************************************************************/ void RTC_SendACK(void) { RTC_SCL_0; RTC_NOP; RTC_SDA_0; RTC_NOP; RTC_SCL_1; RTC_NOP; RTC_SCL_0; RTC_NOP; //////DebugPrint("TWI_SendACK\n"); } /************************************************************************************* * Function: RTC_SendNACK * Object: 收到数据发送NACK * 输入: 无 * 输出: 无 * 备注: **************************************************************************************/ void RTC_SendNACK(void) { RTC_SCL_0; RTC_NOP; RTC_SDA_1; RTC_NOP; RTC_SCL_1; RTC_NOP; RTC_SCL_0; RTC_NOP; //////DebugPrint("TWI_SendNACK\n"); } /************************************************************************************* * Function: RTC_WaitAck * Object: 收到数据等待ACK * 输入: 无 * 输出: 返回IIC总线状态 * 备注: **************************************************************************************/ uint8_t RTC_WaitAck(void) { RTC_SCL_0; RTC_NOP; RTC_SDA_1; RTC_NOP; RTC_SCL_1; RTC_NOP; if(RTC_SDA_STATE) { RTC_SCL_0; return 0x00; } RTC_SCL_0; return 0x01; } /************************************************************************************* * Function: RTC_SendByte * Object: 发送一个字节 * 输入: 要发送的数据(一个字节) * 输出: 返回IIC总线状态 * 备注: **************************************************************************************/ uint8_t RTC_SendByte(uint8_t Data) { uint8_t i; //RTC_SCL_0; for( i = 0 ; i < 8 ; i++ ) { RTC_SCL_0; RTC_NOP; //数据建立保持一定延时 if( Data & 0x80 ) { RTC_SDA_1; } else { RTC_SDA_0; } Data <<= 1; RTC_NOP; RTC_SCL_1; RTC_NOP; } RTC_SCL_0; /* RTC_SCL_0; RTC_SDA_1; RTC_NOP; RTC_SCL_1; RTC_NOP; */ if(RTC_WaitAck()==0) //读引脚状态 { return 0; } else return 1; } /************************************************************************************* * Function: RTC_ReceiveByte * Object: 接收一个字节 * 输入: 无 * 输出: 返回接收到的数据 * 备注: 1、uint8_t Dat = 0;按位做接收数据组合 **************************************************************************************/ uint8_t RTC_ReceiveByte(void) { uint8_t i,Dat = 0; RTC_SDA_1; //RTC_SCL_0; for(i=0;i<8;i++) { //RTC_SCL_0; //RTC_NOP; Dat<<=1; RTC_SCL_0; RTC_NOP; RTC_SCL_1; RTC_NOP; if(RTC_SDA_STATE) //读引脚状态 { Dat|=0x01; } } RTC_SCL_0; /* RTC_SCL_0; RTC_NOP; RTC_SDA_0; RTC_NOP; RTC_SCL_1; RTC_NOP; RTC_SCL_0;*/ //////DebugPrint("TWI_Dat:%x\n",Dat); return Dat; }