本文使用CH592X软件模拟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);

串口打印输出:

 

posted on 2025-01-10 13:04  WCH蓝牙应用分享  阅读(44)  评论(0)    收藏  举报