--- title: IIC updated: 2022-01-11 01:26:41Z created: 2022-01-08 13:18:07Z --- # 软件模拟IIC ```c /* This sample show how to use MM32 write read EEPROM AT2404 through GPIO pin to simulate I2C interface 下面给出MM32通过GPIO模拟I2C读写EEPROM程序 */ #define I2C1_SCL_PORT GPIOB #define I2C1_SCL_PIN GPIO_Pin_13 #define I2C1_SCL_BUSCLK RCC_AHBPeriph_GPIOB #define I2C1_SDA_PORT GPIOB #define I2C1_SDA_PIN GPIO_Pin_14 #define I2C1_SDA_BUSCLK RCC_AHBPeriph_GPIOB #define SCL_H I2C1_SCL_PORT->BSRR = I2C1_SCL_PIN #define SCL_L I2C1_SCL_PORT->BRR = I2C1_SCL_PIN #define SCL_read (I2C1_SCL_PORT-IDR & I2C1_SCL_PIN) #define SDA_H I2C1_SDA_PORT->BSRR = I2C1_SDA_PIN #define SDA_L I2C1_SDA_PORT->BRR = I2C1_SDA_PIN #define SDA_read (I2C1_SDA_PORT->IDR & I2C1_SDA_PIN) void I2C_GPIO_Config(void); bool EEPROM_ByteWrite(u8 SendByte, u16 WriteAddress, u8 DeviceAddress); bool EEPROM_SequentialRead(u8 *pBuffer, u8 length, u16 ReadAddress, u8 DeviceAddress); #define I2C_PageSize 16//8 void delay_ms(__IO uint32_t nTime); #define Systick_Delay_1ms delay_ms void I2C_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /*Configure I2C1 Pins:SCL and SDA*/ RCC_AHBPeriphClockCmd(I2C1_SCL_BUSCLK, ENABLE); RCC_AHBPeriphClockCmd(I2C1_SDA_BUSCLK, ENABLE); GPIO_InitStructure.GPIO_Pin = I2C1_SCL_PIN ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(I2C1_SCL_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = I2C1_SDA_PIN; GPIO_Init(I2C1_SDA_PORT, &GPIO_InitStructure); } static void I2C_delay(void) { //set I2C SCL speed 设置通信速度 u8 i = 13; //100; while(i) { i--; } } bool I2C_Start(void) { I2C_delay(); SDA_H; SCL_H; I2C_delay(); if(!SDA_read) return FALSE; //SDA线为低电平总线忙,退出 SDA_L; I2C_delay(); if(SDA_read) return FALSE; //SDA线为高电平则总线出错,退出 SDA_L; I2C_delay(); return TRUE; } void I2C_Stop(void) { SCL_L; I2C_delay(); SDA_L; I2C_delay(); SCL_H; I2C_delay(); SDA_H; I2C_delay(); } void I2C_Ack(void) { SCL_L; I2C_delay(); SDA_L; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); } void I2C_NoAck(void) { SCL_L; I2C_delay(); SDA_H; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); } bool I2C_WaitAck(void) //返回为:-1有ACK, =0 无ACK { bool bstatus; SCL_L; I2C_delay(); SDA_H; I2C_delay(); SCL_H; I2C_delay(); if(SDA_read) { bstatus = FALSE; } else { bstatus = TRUE; } SCL_L; return bstatus; } void I2C_SendByte(u8 SendByte) //数据从高位到低位 { u8 i = 8; while(i--) { SCL_L; I2C_delay(); if(SendByte & 0x80) SDA_H; else SDA_L; SendByte <<= 1; I2C_delay(); SCL_H; I2C_delay(); } SCL_L; } u8 I2C_ReceiveByte(void) //数据从高位到低位 { u8 i = 8; u8 ReceiveByte = 0; SDA_H; while(i--) { ReceiveByte <<= 1; SCL_L; I2C_delay(); SCL_H; I2C_delay(); if(SDA_read) { ReceiveByte |= 0x01; } } SCL_L; return ReceiveByte; } ```