154 lines
3.5 KiB
Markdown
154 lines
3.5 KiB
Markdown
---
|
||
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;
|
||
}
|
||
```
|