CH5XX模拟I2C操作SHT21
本文使用CH592软件模拟iic驱动SHT21,
1.i2c.c
#include "i2c.h"
#include "CH59x_common.h"
#define IIC_SCL_PIN GPIO_Pin_15 // PB15-SCL
#define IIC_SDA_PIN GPIO_Pin_14 // PB14-SDA
#define IIC_SCL_H() R32_PB_DIR &= ~IIC_SCL_PIN
#define IIC_SCL_L() R32_PB_DIR |= IIC_SCL_PIN
#define IIC_SDA_H() R32_PB_DIR &= ~IIC_SDA_PIN
#define IIC_SDA_L() R32_PB_DIR |= IIC_SDA_PIN
#define SCL_read() (R32_PB_PIN & IIC_SCL_PIN)
#define SDA_read() (R32_PB_PIN & IIC_SDA_PIN)
void IIC_Init()
{
GPIOB_ModeCfg(IIC_SCL_PIN, GPIO_ModeIN_PU); // 初始化为上拉输入
GPIOB_ModeCfg(IIC_SDA_PIN, GPIO_ModeIN_PU); // 初始化为上拉输入
GPIOB_ResetBits(IIC_SCL_PIN | IIC_SDA_PIN); // 配置默认输出低电平,保证在切换IO引脚为输出方向时能够及时输出低电平
IIC_SCL_H(); // SCL拉高
IIC_SDA_H(); // SDA拉高
}
void IIC_Delay()
{
mDelayuS(10); // 可根据实际情况调整延时时间
}
void IIC_START()
{
IIC_SDA_H();
IIC_SCL_H();
IIC_Delay();
IIC_SDA_L();
IIC_Delay();
IIC_SCL_L();
}
void IIC_STOP()
{
IIC_SDA_L();
IIC_SCL_H();
IIC_Delay();
IIC_SDA_H();
IIC_Delay();
}
int IIC_WaitAck()
{
IIC_SCL_L();
IIC_Delay();
IIC_SDA_H();
IIC_Delay();
IIC_SCL_H();
IIC_Delay();
if (SDA_read())
{
IIC_SCL_L();
return 0;
}
IIC_SCL_L();
return 1;
}
void IIC_SendByte(uint8_t SendByte)
{
uint8_t i = 8;
while (i--)
{
IIC_SCL_L();
IIC_Delay();
if (SendByte & 0x80)
IIC_SDA_H();
else
IIC_SDA_L();
SendByte <<= 1;
IIC_Delay();
IIC_SCL_H();
IIC_Delay();
}
IIC_SCL_L();
}
uint8_t IIC_ReadByte()
{
uint8_t i = 8;
uint8_t ReceiveByte = 0;
IIC_SDA_H();
while (i--)
{
ReceiveByte <<= 1;
IIC_SCL_L();
IIC_Delay();
IIC_SCL_H();
IIC_Delay();
if (SDA_read())
ReceiveByte |= 0x01;
}
IIC_SCL_L();
return ReceiveByte;
}
2.i2c.h
#ifndef I2C_H #define I2C_H #include "CH59x_common.h" extern void IIC_Init(); extern void IIC_Delay(); extern void IIC_START(); extern void IIC_STOP(); extern int IIC_WaitAck(); extern void IIC_SendByte(uint8_t SendByte); extern uint8_t IIC_ReadByte(); #endif
3.sht21.c
#include "sht21.h"
void sht21_reset()
{
IIC_START();
IIC_SendByte(SHT21_ADDR << 1);
IIC_WaitAck();
IIC_SendByte(SOFT_RESET);
IIC_WaitAck();
IIC_STOP();
}
void sht21_write_command(uint8_t command)
{
IIC_START();
IIC_SendByte(SHT21_ADDR << 1);
IIC_WaitAck();
IIC_SendByte(command);
IIC_WaitAck();
IIC_STOP();
}
uint16_t sht21_read_data()
{
uint16_t data = 0;
IIC_START();
IIC_SendByte((SHT21_ADDR << 1) | 0x01);
IIC_WaitAck();
data = IIC_ReadByte();
data <<= 8;
data |= IIC_ReadByte();
IIC_STOP();
return data;
}
float sht21_get_temperature()
{
sht21_write_command(TRIGGER_TEMP_MEASUREMENT_HOLD);
mDelaymS(100); // 等待测量完成,根据数据手册,温度测量最长需85ms
uint16_t raw_temp = sht21_read_data();
float temperature = -46.85 + 175.72 * raw_temp / 65536.0;
return temperature;
}
float sht21_get_humidity()
{
sht21_write_command(TRIGGER_HUMIDITY_MEASUREMENT_HOLD);
mDelaymS(100); // 等待测量完成,根据数据手册,湿度测量最长需22ms
uint16_t raw_humidity = sht21_read_data();
float humidity = -6.0 + 125.0 * raw_humidity / 65536.0;
return humidity;
}
4.sht21.h
#ifndef SHT21_H #define SHT21_H #include "i2c.h" #include "CH59x_common.h" #define SHT21_ADDR 0x40 // SHT21的I2C地址 // SHT21的命令 #define TRIGGER_TEMP_MEASUREMENT_HOLD 0xE3 #define TRIGGER_HUMIDITY_MEASUREMENT_HOLD 0xE5 #define WRITE_USER_REG 0xE6 #define READ_USER_REG 0xE7 #define SOFT_RESET 0xFE extern void sht21_reset(); extern void sht21_write_command(uint8_t command); extern uint16_t sht21_read_data(); extern float sht21_get_temperature(); extern float sht21_get_humidity(); #endif
5.main.c
IIC_Init();
sht21_reset();
float temperature = sht21_get_temperature();
float humidity = sht21_get_humidity();
PRINT("Temperature: %.2f C, Humidity: %.2f %%RH\n", temperature, humidity);
串口打印输出:


浙公网安备 33010602011771号