obsidian-notes/代码/IIC.md
CSSC-WORK\murmur 3e6078442b init version
2024-04-15 11:19:57 +08:00

154 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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