本帖最后由 weishidai 于 2024-9-16 12:29 编辑

收到板子有2周了,恰逢上海迎台风,在家用G401调下SHT30温湿度传感器。
前期准备:G401开发板,SHT30传感器

硬件连接:通过硬件IIC1接口,板子上对应的是PB6(I2c1_scl),PB7(I2c_sda)脚。

122208qd9o6df2ze85oz2z

实物连接如图:

122208uwzw9le0v0nyh9pg

软件部分:国民官方给我们提供很多外设的例子,我们可以参考 122208c0efzt5aea7db3u7

将G401做i2c主设备,sht30做slave,那么需要确定sht30的地址,从手册里可以看到,


122209snw5ot5zw5jwtzwi

地址是0x44,但实际代码里使用时,需要结合读写位,所以定义实际地址为

122209rx5ndkxi5ndiyyp5

硬件使用iic的流程为,先初始化gpio作为iic的功能。

    GPIO_Structure_Initialize(&i2c1_gpio);

    /*PB6 -- SCL; PB7 -- SDA*/

    i2c1_gpio.Pin            = I2Cx_SCL_PIN | I2Cx_SDA_PIN;

    i2c1_gpio.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;

    i2c1_gpio.GPIO_Mode      = GPIO_MODE_AF_OD;

    i2c1_gpio.GPIO_Alternate = GPIO_AF_I2C;

    i2c1_gpio.GPIO_Pull      = GPIO_PULL_UP;

GPIO_Peripheral_Initialize(GPIOx, &i2c1_gpio);

然后初始化i2c master控制器的参数,主要是总线模式,地址,寻址模式,通信速率,最后打开i2c的使能。

    I2C_Initializes_Structure(&i2c1_master);

    i2c1_master.BusMode     = I2C_BUSMODE_I2C;

    i2c1_master.DutyCycle   = I2C_SMDUTYCYCLE_1;

    i2c1_master.OwnAddr1    = 0x44;     // sht30 addr

    i2c1_master.AckEnable   = I2C_ACKEN;

    i2c1_master.AddrMode    = I2C_ADDR_MODE_7BIT;

    i2c1_master.ClkSpeed    = CLK_SPEED_400K; /* 100k */

    I2C_Initializes(I2Cx, &i2c1_master);

I2C_ON(I2Cx);

此时我们可以对外设SHT30进行读写,这个流程是先复位SHT30,命令为

uint8_t SHT30_Reset(void)

{

        uint8_t res = 0;

        res = SHT30_Send_Cmd(SOFT_RESET_CMD);

        //SysTick_Delay_Ms(20);


        return res;


}

其中命令封装到了枚举类型里,

typedef enum{

        SOFT_RESET_CMD = 0x30A2,

        HIGH_ENABLE_CMD = 0x2C06,

        HIGH_1_CMD = 0x2130,

        READ_FOR_PERIODIC_MODE = 0xE000,

}SHT30_CMD;

然后我们可以给SHT30发送周期性的读写命令,每秒读一次,0x2130,其依据是

122209sv8ss6ni8t2igizl

体现在程序里:

uint8_t SHT30_Send_Cmd(uint16_t cmd)

{

        uint8_t cmd_buffer[2];

        cmd_buffer[0] = cmd >> 8;

        cmd_buffer[1] = cmd;

        return i2c_master_send(cmd_buffer, 2);

}

其中i2c_master_send里需要更改i2c slave的地址,

I2C_7bit_Addr_Send(I2C1, SHT30_ADDRESS_WRITE, I2C_DIRECTION_SEND);  

后续我们就可以周期性读取SHT30数据。

while (1)

    {

                        SysTick_Delay_Ms(1000);

                if((res =  SHT30_Read_Dat(recv_dat)) == 0){

                        if(SHT30_Dat_To_Float(recv_dat,&temp,&hum) == 0)

                        {

                                log_info("N32G401 hard iic master temperature = %f, humidity = %f\r\n", temp, hum);

                        }else{

                                log_info("crc check fail.\r\n");

                        }                                                                                                   

                }else{

                        log_info("read SHT30 data error res = %d\r\n",res);

                }

    }

需要注意crc校验

uint8_t SHT30_Dat_To_Float(uint8_t* const dat, float* temperature, float* humidity)

{

        uint16_t recv_temperature = 0;

        uint16_t recv_humidity = 0;

        if(CheckCrc8(dat, 0xFF) != dat[2] || CheckCrc8(&dat[3], 0xFF) != dat[5])

                return 1;

        recv_temperature = ((uint16_t)dat[0]<<8)|dat[1];

        *temperature = -45 + 175*((float)recv_temperature/65535);

        recv_humidity = ((uint16_t)dat[3]<<8)|dat[4];

        *humidity = 100 * ((float)recv_humidity / 65535);

        return 0;

}

实际串口输出效果如图:

122213shic97jzdk9mbvgm