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;
|
|||
|
}
|
|||
|
```
|