3.5 KiB
3.5 KiB
title | updated | created |
---|---|---|
IIC | 2022-01-11 01:26:41Z | 2022-01-08 13:18:07Z |
软件模拟IIC
/*
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;
}