stm32f103i模拟i2c串口输出
时间: 2023-08-15 21:06:39 浏览: 82
以下是STM32F103I模拟I2C串口输出的代码示例:
```
#include "stm32f10x.h"
#define SDA_PIN GPIO_Pin_7
#define SCL_PIN GPIO_Pin_6
#define I2C_DELAY() delay_us(1)
void i2c_init(void);
void i2c_start(void);
void i2c_stop(void);
void i2c_send_byte(uint8_t byte);
uint8_t i2c_receive_byte(uint8_t ack);
void delay_us(uint32_t us)
{
uint32_t i;
for (i = 0; i < us; i++)
{
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
}
}
void i2c_init(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_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, SDA_PIN | SCL_PIN);
}
void i2c_start(void)
{
// SDA拉高时SCL为高电平,否则可能导致I2C总线死锁
GPIO_SetBits(GPIOB, SDA_PIN);
GPIO_SetBits(GPIOB, SCL_PIN);
I2C_DELAY();
GPIO_ResetBits(GPIOB, SDA_PIN);
I2C_DELAY();
GPIO_ResetBits(GPIOB, SCL_PIN);
I2C_DELAY();
}
void i2c_stop(void)
{
GPIO_ResetBits(GPIOB, SDA_PIN);
I2C_DELAY();
GPIO_SetBits(GPIOB, SCL_PIN);
I2C_DELAY();
GPIO_SetBits(GPIOB, SDA_PIN);
I2C_DELAY();
}
void i2c_send_byte(uint8_t byte)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
if (byte & 0x80)
GPIO_SetBits(GPIOB, SDA_PIN);
else
GPIO_ResetBits(GPIOB, SDA_PIN);
I2C_DELAY();
GPIO_SetBits(GPIOB, SCL_PIN);
I2C_DELAY();
GPIO_ResetBits(GPIOB, SCL_PIN);
I2C_DELAY();
byte <<= 1;
}
}
uint8_t i2c_receive_byte(uint8_t ack)
{
uint8_t i, byte = 0;
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);
for (i = 0; i < 8; i++)
{
byte <<= 1;
GPIO_SetBits(GPIOB, SCL_PIN);
I2C_DELAY();
if (GPIO_ReadInputDataBit(GPIOB, SDA_PIN))
byte |= 0x01;
GPIO_ResetBits(GPIOB, SCL_PIN);
I2C_DELAY();
}
if (ack)
GPIO_ResetBits(GPIOB, SDA_PIN);
else
GPIO_SetBits(GPIOB, SDA_PIN);
GPIO_SetBits(GPIOB, SCL_PIN);
I2C_DELAY();
GPIO_ResetBits(GPIOB, SCL_PIN);
I2C_DELAY();
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
return byte;
}
int main(void)
{
uint8_t data[] = "Hello, World!";
uint8_t i, len = sizeof(data) / sizeof(data[0]);
i2c_init();
i2c_start();
i2c_send_byte(0x3C << 1);
for (i = 0; i < len; i++)
i2c_send_byte(data[i]);
i2c_stop();
while (1)
;
}
```
这里模拟了I2C总线,并通过串口输出"Hello, World!"。在初始化时,需要设置SDA和SCL引脚为输出模式。在发送数据时,需要先发送起始位,然后发送从设备地址,最后发送要传输的数据。在接收数据时,需要先发送起始位,然后发送从设备地址,最后接收数据并发送应答位。
阅读全文