stm32F103 模拟i2c从机代码
时间: 2023-07-09 17:17:47 浏览: 288
以下是基于STM32F103C8T6芯片的模拟I2C从机代码示例:
```c
#include "stm32f10x.h"
#define SDA_PIN GPIO_Pin_9
#define SCL_PIN GPIO_Pin_8
#define I2C_SLAVE_ADDR 0x50
void GPIO_Configuration(void);
void I2C_Configuration(void);
void I2C_SDA_Output(void);
void I2C_SDA_Input(void);
void I2C_Start(void);
void I2C_Stop(void);
uint8_t I2C_WriteByte(uint8_t data);
uint8_t I2C_ReadByte(uint8_t ack);
int main(void)
{
GPIO_Configuration();
I2C_Configuration();
while(1)
{
//等待主机发来的数据
while(GPIO_ReadInputDataBit(GPIOB, SCL_PIN) == Bit_RESET);
GPIO_ResetBits(GPIOB, SCL_PIN);
uint8_t addr = I2C_ReadByte(0);
uint8_t data = I2C_ReadByte(0);
//处理接收到的数据
while(GPIO_ReadInputDataBit(GPIOB, SCL_PIN) == Bit_RESET);
GPIO_SetBits(GPIOB, SCL_PIN);
while(GPIO_ReadInputDataBit(GPIOB, SCL_PIN) == Bit_SET);
}
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = SDA_PIN | SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, SDA_PIN | SCL_PIN);
}
void I2C_Configuration(void)
{
I2C_SDA_Output();
I2C_SDA_Input();
}
void I2C_SDA_Output(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, SDA_PIN);
}
void I2C_SDA_Input(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void I2C_Start(void)
{
GPIO_SetBits(GPIOB, SDA_PIN | SCL_PIN);
GPIO_ResetBits(GPIOB, SDA_PIN);
GPIO_ResetBits(GPIOB, SCL_PIN);
}
void I2C_Stop(void)
{
GPIO_ResetBits(GPIOB, SDA_PIN);
GPIO_SetBits(GPIOB, SCL_PIN);
GPIO_SetBits(GPIOB, SDA_PIN);
}
uint8_t I2C_WriteByte(uint8_t data)
{
for(int i=0; i<8; i++)
{
if(data & 0x80)
GPIO_SetBits(GPIOB, SDA_PIN);
else
GPIO_ResetBits(GPIOB, SDA_PIN);
GPIO_SetBits(GPIOB, SCL_PIN);
GPIO_ResetBits(GPIOB, SCL_PIN);
data <<= 1;
}
while(GPIO_ReadInputDataBit(GPIOB, SDA_PIN) == Bit_RESET);
GPIO_SetBits(GPIOB, SCL_PIN);
uint8_t ack = GPIO_ReadInputDataBit(GPIOB, SDA_PIN);
GPIO_ResetBits(GPIOB, SCL_PIN);
return ack;
}
uint8_t I2C_ReadByte(uint8_t ack)
{
uint8_t data = 0;
for(int i=0; i<8; i++)
{
data <<= 1;
while(GPIO_ReadInputDataBit(GPIOB, SCL_PIN) == Bit_RESET);
if(GPIO_ReadInputDataBit(GPIOB, SDA_PIN) == Bit_SET)
data |= 0x01;
GPIO_ResetBits(GPIOB, SCL_PIN);
}
if(ack)
GPIO_SetBits(GPIOB, SDA_PIN);
else
GPIO_ResetBits(GPIOB, SDA_PIN);
GPIO_SetBits(GPIOB, SCL_PIN);
GPIO_ResetBits(GPIOB, SCL_PIN);
return data;
}
```
在本示例中,我们使用了GPIO模拟I2C从机。首先,我们需要定义SDA和SCL引脚的GPIO_Pin编号和I2C从机地址。在main函数中,我们首先调用GPIO_Configuration和I2C_Configuration函数初始化GPIO和I2C。
在主循环中,我们不断地等待主机发来的数据。当SCL线变为高电平时,表示主机要开始传输数据了。我们调用I2C_ReadByte函数接收地址和数据。接收完成后,我们处理数据并向主机发送ACK信号。
I2C_WriteByte和I2C_ReadByte函数分别用于向主机发送数据和接收数据。
注意,本示例仅供参考,实际应用中需要根据具体情况进行修改。
阅读全文