stm32f103 标准库软件模拟iic读写一个字节
时间: 2023-09-24 21:03:21 浏览: 121
STM32F103模拟IIC程序(亲测可用)
以下是使用STM32F103标准库进行软件模拟I2C读写一个字节的示例代码:
```c
#include "stm32f10x.h"
#define SDA_PIN GPIO_Pin_7
#define SCL_PIN GPIO_Pin_6
#define I2C_GPIO GPIOB
void I2C_Delay(void)
{
volatile int i = 7;
while(i--);
}
void I2C_Start(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(I2C_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
GPIO_SetBits(I2C_GPIO, SDA_PIN);
GPIO_SetBits(I2C_GPIO, SCL_PIN);
I2C_Delay();
GPIO_ResetBits(I2C_GPIO, SDA_PIN);
I2C_Delay();
GPIO_ResetBits(I2C_GPIO, SCL_PIN);
}
void I2C_Stop(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(I2C_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
GPIO_ResetBits(I2C_GPIO, SDA_PIN);
GPIO_SetBits(I2C_GPIO, SCL_PIN);
I2C_Delay();
GPIO_SetBits(I2C_GPIO, SDA_PIN);
I2C_Delay();
}
void I2C_Ack(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(I2C_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
GPIO_ResetBits(I2C_GPIO, SDA_PIN);
I2C_Delay();
GPIO_SetBits(I2C_GPIO, SCL_PIN);
I2C_Delay();
GPIO_ResetBits(I2C_GPIO, SCL_PIN);
}
void I2C_Nack(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(I2C_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
GPIO_SetBits(I2C_GPIO, SDA_PIN);
I2C_Delay();
GPIO_SetBits(I2C_GPIO, SCL_PIN);
I2C_Delay();
GPIO_ResetBits(I2C_GPIO, SCL_PIN);
}
int I2C_WaitAck(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
uint8_t ack = 0;
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
GPIO_SetBits(I2C_GPIO, SDA_PIN);
I2C_Delay();
GPIO_SetBits(I2C_GPIO, SCL_PIN);
I2C_Delay();
if(GPIO_ReadInputDataBit(I2C_GPIO, SDA_PIN) == RESET)
{
ack = 1;
}
GPIO_ResetBits(I2C_GPIO, SCL_PIN);
return ack;
}
void I2C_SendByte(uint8_t byte)
{
uint8_t i = 8;
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(I2C_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
while(i--)
{
if(byte & 0x80)
{
GPIO_SetBits(I2C_GPIO, SDA_PIN);
}
else
{
GPIO_ResetBits(I2C_GPIO, SDA_PIN);
}
I2C_Delay();
GPIO_SetBits(I2C_GPIO, SCL_PIN);
I2C_Delay();
GPIO_ResetBits(I2C_GPIO, SCL_PIN);
byte <<= 1;
}
}
uint8_t I2C_ReadByte(void)
{
uint8_t i = 8;
uint8_t byte = 0;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
while(i--)
{
byte <<= 1;
GPIO_SetBits(I2C_GPIO, SCL_PIN);
I2C_Delay();
if(GPIO_ReadInputDataBit(I2C_GPIO, SDA_PIN) == SET)
{
byte |= 0x01;
}
GPIO_ResetBits(I2C_GPIO, SCL_PIN);
I2C_Delay();
}
return byte;
}
void I2C_WriteByte(uint8_t device_addr, uint8_t reg_addr, uint8_t data)
{
I2C_Start();
I2C_SendByte(device_addr << 1);
if(!I2C_WaitAck())
{
I2C_Stop();
return;
}
I2C_SendByte(reg_addr);
if(!I2C_WaitAck())
{
I2C_Stop();
return;
}
I2C_SendByte(data);
if(!I2C_WaitAck())
{
I2C_Stop();
return;
}
I2C_Stop();
}
uint8_t I2C_ReadByte(uint8_t device_addr, uint8_t reg_addr)
{
uint8_t data = 0;
I2C_Start();
I2C_SendByte(device_addr << 1);
if(!I2C_WaitAck())
{
I2C_Stop();
return 0;
}
I2C_SendByte(reg_addr);
if(!I2C_WaitAck())
{
I2C_Stop();
return 0;
}
I2C_Start();
I2C_SendByte((device_addr << 1) | 0x01);
if(!I2C_WaitAck())
{
I2C_Stop();
return 0;
}
data = I2C_ReadByte();
I2C_Nack();
I2C_Stop();
return data;
}
```
这段代码将I2C总线的SDA和SCL引脚分别定义为GPIOB的第7和第6个引脚。I2C_Start()函数用于在总线上发送起始信号,I2C_Stop()函数用于发送停止信号。I2C_Ack()和I2C_Nack()函数分别用于发送应答或非应答信号。I2C_WaitAck()函数用于等待从设备发送的应答信号。I2C_SendByte()函数用于向从设备发送一个字节的数据,I2C_ReadByte()函数用于从从设备读取一个字节的数据。I2C_WriteByte()函数用于向从设备写入一个字节的数据,I2C_ReadByte()函数用于从从设备读取一个字节的数据。
阅读全文