基于STM32实现模拟3个I2C口操作2个SHT20和1个DS3231,并通过串口输出数据的解决方案。结合了软件I2C的灵活性和硬件I2C的稳定性,适用于需要多设备通信的场景。
硬件连接
- SHT20传感器:假设连接到两个不同的GPIO口组合,分别作为两个I2C总线。
- SHT20_1:SCL -> PA0, SDA -> PA1
- SHT20_2:SCL -> PA2, SDA -> PA3
- DS3231:使用STM32自带的硬件I2C接口(如I2C1),SCL -> PB6, SDA -> PB7。
软件设计
- 软件I2C实现:用于操作两个SHT20传感器。参考实现软件I2C通信,定义两个I2C结构体分别对应两个SHT20。
- 硬件I2C实现:用于操作DS3231,使用HAL库配置I2C1。
- 串口通信:用于输出数据,配置USART接口。
代码
1. 软件I2C驱动(部分代码)
#include "stm32f1xx_hal.h"
#define IIC_DELAY_TIME 1
typedef struct {
GPIO_TypeDef* SCL_GPIO;
uint16_t SCL_Pin;
GPIO_TypeDef* SDA_GPIO;
uint16_t SDA_Pin;
} IIC_TypeDef;
void IIC_Init(IIC_TypeDef* iic) {
// GPIO初始化代码
}
void IIC_Start(IIC_TypeDef* iic) {
// 软件I2C起始信号
}
void IIC_Stop(IIC_TypeDef* iic) {
// 软件I2C停止信号
}
void IIC_SendByte(IIC_TypeDef* iic, uint8_t dat) {
// 发送字节
}
uint8_t IIC_ReadByte(IIC_TypeDef* iic) {
// 读取字节
return 0;
}
uint8_t IIC_Sack(IIC_TypeDef* iic) {
// 等待应答
return 0;
}
2. SHT20操作函数
#define SHT20_ADDR 0x80
float SHT20_ReadTemperature(IIC_TypeDef* iic) {
uint8_t cmd = 0xF3;
IIC_Start(iic);
IIC_SendByte(iic, SHT20_ADDR);
IIC_SendByte(iic, cmd);
IIC_Stop(iic);
HAL_Delay(85); // 等待测量完成
IIC_Start(iic);
IIC_SendByte(iic, SHT20_ADDR | 1); // 读模式
uint8_t data[2];
data[0] = IIC_ReadByte(iic);
IIC_Ack(iic, 1);
data[1] = IIC_ReadByte(iic);
IIC_Ack(iic, 0);
IIC_Stop(iic);
float temp = -46.85 + 175.72 * (((uint16_t)data[0] << 8) | data[1]) / 65536.0;
return temp;
}
3. DS3231操作函数
#define DS3231_ADDR 0x68
void DS3231_ReadTime(I2C_HandleTypeDef* hi2c, uint8_t* time) {
HAL_I2C_Master_Transmit(hi2c, DS3231_ADDR, 0x00, 1, 1000);
HAL_I2C_Master_Receive(hi2c, DS3231_ADDR, time, 7, 1000);
}
参考代码 stm32 模拟3个IIC口操作2个SHT20和1个DS3231,串口输出数据 www.youwenfan.com/contentalc/56853.html
4. 主函数
int main(void) {
HAL_Init();
// 初始化硬件I2C和USART
IIC_TypeDef iic1 = {
GPIOA, GPIO_PIN_0, GPIOA, GPIO_PIN_1}; // SHT20_1
IIC_TypeDef iic2 = {
GPIOA, GPIO_PIN_2, GPIOA, GPIO_PIN_3}; // SHT20_2
IIC_Init(&iic1);
IIC_Init(&iic2);
I2C_HandleTypeDef hi2c1; // 硬件I2C1
DS3231_Init(&hi2c1);
while (1) {
float temp1 = SHT20_ReadTemperature(&iic1);
float temp2 = SHT20_ReadTemperature(&iic2);
uint8_t time[7];
DS3231_ReadTime(&hi2c1, time);
// 通过串口输出数据
printf("SHT20_1 Temp: %.2f C\n", temp1);
printf("SHT20_2 Temp: %.2f C\n", temp2);
printf("DS3231 Time: %02d:%02d:%02d\n", time[2], time[1], time[0]);
HAL_Delay(1000);
}
}
注意事项
- GPIO初始化:确保GPIO的模式和速度配置正确。
- I2C设备地址:SHT20和DS3231的I2C地址是固定的,注意不要冲突。
- 延时处理:SHT20的测量需要一定时间,确保延时足够。
通过上述代码,可以实现STM32模拟多个I2C口操作多个设备,并通过串口输出数据。