一、了解HC32F448芯片关于IIC部分的引脚定义

根据官方手册DS_HC32F448系列数据手册_Rev1.31.pdf来看,对于引脚部分的定义为下图:

已知上图的定义,那么我们直接找两个满足条件的引脚来做IIC1的SDA/SCL,并配置相关功能就好。

二、解析SHT20温湿度传感器规格书

规格书第7页的末尾以及第8页的开头有说明读取SHT20温湿度传感器的指令,如图:

大致意思就是读取温湿度传感器的iic指令的7位起始地址为“1000 000”,换算为hex格式为:0x40;第8位接一个方向位(读为1,写为0),然后发出测量指令就好了,第8页开始的表格就是指令说明,我用的是第3行和第4行:温度指令“1111 0011”(hex:0xF3),湿度指令“1111 0101”(hex:0xF5)。

温湿度转换也可以通过规格书提供的公式进行转换:

三、引脚定义及解析代码

关于引脚配置有一个很简便的方法,可以通过官方提供的软件配置XHSC XHCode,然后发送接收函数我们可以参考官方历程。有时候自己去挪例子程序里面的配置不熟悉的话会导致一些搞不定的问题

3.1 iic引脚配置和收发函数。

/**
 * @brief  I2C_Init1 配置i2c的波特率,边沿时长,分频系数,总线命令
 * @param  CM_I2C_TypeDef *I2Cx:I2C1 or I2C2 ,you only need to write a i2c base dar directly
 * @retval LL_OK
 */
//Port Config
static void IIC_PortCfg(void)
{
    GPIO_SetDebugPort(GPIO_PIN_SWO, DISABLE);
    GPIO_SetFunc(GPIO_PORT_B,GPIO_PIN_03,GPIO_FUNC_49);//I2C1-SCL
    
    GPIO_SetDebugPort(GPIO_PIN_TRST, DISABLE);
    GPIO_SetFunc(GPIO_PORT_B,GPIO_PIN_04,GPIO_FUNC_48);//I2C1-SDA
    
}
 
 
//I2Cx Config
static void App_I2CxCfg(void)
{
    int32_t i32Ret;
    stc_i2c_init_t stcI2cInit;
    float32_t fErr;

    /* Enable I2C1 clock */
    FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_I2C1, ENABLE);
    /************************* Configure I2C1***************************/
    (void)I2C_DeInit(CM_I2C1);

    (void)I2C_StructInit(&stcI2cInit);
    stcI2cInit.u32ClockDiv = I2C_CLK_DIV8;
    stcI2cInit.u32Baudrate = 50000UL;
    stcI2cInit.u32SclTime = 0UL;
    i32Ret = I2C_Init(CM_I2C1, &stcI2cInit, &fErr);
    if (LL_OK != i32Ret) {
        //Initialized failed, add your code here.
    }
    I2C_BusWaitCmd(CM_I2C1, ENABLE);


}


/**
 * @brief  Master transmit data
 *
 * @param  [in] u16DevAddr          The slave address
 * @param  [in] au8Data             The data array
 * @param  [in] u32Size             Data size
 * @param  [in] u32Timeout          Time out count
 * @retval int32_t:
 *            - LL_OK:              Success
 *            - LL_ERR_TIMEOUT:     Time out
 */
int32_t I2C_Master_Transmit(uint16_t u16DevAddr, const uint8_t au8Data[], uint32_t u32Size, uint32_t u32Timeout)
{
    int32_t i32Ret;
    I2C_Cmd(I2C_UNIT, ENABLE);

    I2C_SWResetCmd(I2C_UNIT, ENABLE);
    I2C_SWResetCmd(I2C_UNIT, DISABLE);
    i32Ret = I2C_Start(I2C_UNIT, u32Timeout);
    if (LL_OK == i32Ret) {

        i32Ret = I2C_TransAddr(I2C_UNIT, u16DevAddr, I2C_DIR_TX, u32Timeout);
        if (LL_OK == i32Ret) {
            i32Ret = I2C_TransData(I2C_UNIT, au8Data, u32Size, u32Timeout);
        }
    }

    (void)I2C_Stop(I2C_UNIT, u32Timeout);
    I2C_Cmd(I2C_UNIT, DISABLE);

    return i32Ret;
}



/**
 * @brief  Master receive data
 *
 * @param  [in] u16DevAddr          The slave address
 * @param  [in] au8Data             The data array
 * @param  [in] u32Size             Data size
 * @param  [in] u32Timeout          Time out count
 * @retval int32_t:
 *            - LL_OK:              Success
 *            - LL_ERR_TIMEOUT:     Time out
 */
int32_t I2C_Master_Receive(uint16_t u16DevAddr, uint8_t au8Data[], uint32_t u32Size, uint32_t u32Timeout)
{
    int32_t i32Ret;

    I2C_Cmd(I2C_UNIT, ENABLE);
    I2C_SWResetCmd(I2C_UNIT, ENABLE);
    I2C_SWResetCmd(I2C_UNIT, DISABLE);
    i32Ret = I2C_Start(I2C_UNIT, u32Timeout);
    if (LL_OK == i32Ret) {
        if (1UL == u32Size) {
            I2C_AckConfig(I2C_UNIT, I2C_NACK);
        }

        i32Ret = I2C_TransAddr(I2C_UNIT, u16DevAddr, I2C_DIR_RX, u32Timeout);

        if (LL_OK == i32Ret) {
            i32Ret = I2C_MasterReceiveDataAndStop(I2C_UNIT, au8Data, u32Size, u32Timeout);
        }

        I2C_AckConfig(I2C_UNIT, I2C_ACK);
    }

    if (LL_OK != i32Ret) {
        (void)I2C_Stop(I2C_UNIT, u32Timeout);
    }
    I2C_Cmd(I2C_UNIT, DISABLE);
    return i32Ret;
}

3.2 SHT20部分

// 定义命令
/* Define slave device address for example */
#define DEVICE_ADDR                     (0x40U)

#define SHT20_T      (0xF3) // 触发温度测量,保持主模式

#define SHT20_RH    (0xF5) // 触发湿度测量,保持主模式


// 从SHT20读取数据

void SHT20_ReadData(uint8_t command, uint16_t *data)

{

    uint8_t cmd = command;


    // 发送测量命令
	 /* Send I2C address */

    (void)I2C_Master_Transmit(DEVICE_ADDR, &cmd, 1, TIMEOUT);


    // 等待测量完成(根据数据手册,最大等待时间取决于分辨率,这里等待足够时间)

    DDL_DelayMS(85UL); // 足够的时间用于14位温度或12位湿度测量

    (void)I2C_Master_Receive(DEVICE_ADDR, u8RxBuf, 2, TIMEOUT);


    // 组合接收到的两个字节为16位数据

    *data = ((uint16_t)u8RxBuf[0] << 8) | u8RxBuf[1];

}


// 计算实际温度值

float SHT20_CalculateTemperature(uint16_t rawData)

{

    // 忽略状态位(最低两位),保留14位温度数据

    rawData &= 0xFFFC;

    return -46.85 + 175.72 * ((float)rawData / 65536.0);

}


// 计算实际湿度值

float SHT20_CalculateHumidity(uint16_t rawData)

{

    // 忽略状态位(最低两位),保留12位湿度数据

    rawData &= 0xFFFC;

    return -6.0 + 125.0 * ((float)rawData / 65536.0);

}

// 温度读取函数示例
void SHT20_ReadTemperature(void) 
{
    // 读取温度

	SHT20_ReadData(SHT20_T, &rawTemp);

    temperature = SHT20_CalculateTemperature(rawTemp);


    // 读取湿度

    SHT20_ReadData(SHT20_RH, &rawHumidity);

    humidity = SHT20_CalculateHumidity(rawHumidity);

//	printf("temperature = %.2f,humidity = %.2f",temperature,humidity);
}

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐