【GD32片上i2c外设应用】温湿度传感器htu21d


本篇是对GD32的I2C外设应用,温湿度芯片是htu21d,gd32芯片是gd32f350k8u6,基于gd32的标准外设库进行开发。

一、温湿度传感器htu21d介绍

1.1 参数

只列举芯片温湿度测量的精度,功耗、时序等参数请参考手册。

1.1.1 湿度参数

在这里插入图片描述

1.1.2 温度参数

在这里插入图片描述

1.2 芯片i2c协议

1.2.1 器件地址

器件的7位地址为0x40,编程的时候需加上读写方向位,为0x80。
在这里插入图片描述

1.2.2 读取温湿度

在这里插入图片描述

1.2.3 芯片复位

在这里插入图片描述

二、gd32的i2c外设介绍

I2C接口是一种内部电路,允许与外部I2C接口进行通信,外部I2C接口是一种工业标准的两线串行接口,用于连接外部硬件。这两条串行线被称为串行数据线(SDA)和串行时钟线(SCL)。I2C模块提供不同的数据传输速率:标准模式高达100 KHz,快速模式高达400 KHz,快速模式plus高达1 MHz。I2C模块还具有仲裁检测功能,以防止多个主机同时尝试向I2C总线传输数据的情况。在I2C接口中还提供了一个CRC-8计算器,用于对I2C数据进行包错误检查。

  • 最多两个I2C总线接口可支持主从模式,频率高达1 MHz(快速模式增强)
  • 提供仲裁功能,可选PEC(包错误检查)生成和检查
  • 支持7位和10位寻址模式以及通用呼叫寻址模式

三、编程

3.1 宏定义和变量

#define HTU21D_ADDR    0x80
#define HTU21D_TEMP    0xf3
#define HTU21D_HUMI    0Xf5
#define HTU21D_SOFTWARE_RESET  0xfe

3.2 gd32初始化i2c外设和htu21d初始化

3.2.1 gd32 i2c初始化

//IO引脚配置
void gpio_config(void)
{
    
    
    /* enable GPIOB clock */
    rcu_periph_clock_enable(RCU_GPIOB);
    /* enable I2C0 clock */
    rcu_periph_clock_enable(RCU_I2C0);

    /* connect PB6 to I2C0_SCL */
    gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_6);
    /* connect PB7 to I2C0_SDA */
    gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_7);
    /* configure GPIO pins of I2C0 */
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
}

//I2C外设配置
void i2c_config(void)
{
    
    
    /* enable I2C clock */
    rcu_periph_clock_enable(RCU_I2C0);
    /* configure I2C clock */
    i2c_clock_config(I2C0,I2C0_SPEED,I2C_DTCY_2);
    /* configure I2C address */
    i2c_mode_addr_config(I2C0,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,HTU21D_ADDR);
    /* enable I2C0 */
    i2c_enable(I2C0);
    /* enable acknowledge */
    i2c_ack_config(I2C0,I2C_ACK_ENABLE);
}

3.2.2 htu21d初始化

void htu21d_init(void)
{
    
    
	/* wait until I2C bus is idle */
	while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY));
	i2c_start_on_bus(I2C0);
	/* wait until SBSEND bit is set */
	while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)){
    
    };
	/* send slave address to I2C bus */
	i2c_master_addressing(I2C0, HTU21D_ADDR, I2C_TRANSMITTER);
	
	/* wait until ADDSEND bit is set */
	while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)){
    
    };
	
	/* clear the ADDSEND bit */
	i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);
    
    /* wait until the transmit data buffer is empty */
    while( SET != i2c_flag_get(I2C0, I2C_FLAG_TBE)){
    
    };
	i2c_data_transmit(I2C0, HTU21D_SOFTWARE_RESET);
	/* wait until BTC bit is set */
	while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)){
    
    };
	i2c_stop_on_bus(I2C0);
	/* wait until the stop condition is finished */
	while(I2C_CTL0(I2C0)&0x0200){
    
    };
	delay_1ms(15);
}

3.2 温湿度测量

float htu21d_measure(uint8_t _ucOrder)
{
    
    
	uint8_t ucMsb,ucLsb,checksum;//checksum校验和没有用上
	volatile float f_Temp,f_Humi,f_RetVal;
	i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);

	 /* wait until I2C bus is idle */
  	while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)){
    
    };
	i2c_start_on_bus(I2C0);
	/* wait until SBSEND bit is set */
	while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)){
    
    };

	i2c_master_addressing(I2C0, HTU21D_ADDR, I2C_TRANSMITTER);

    /* wait until ADDSEND bit is set */
    while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)){
    
    };
    
    /* clear the ADDSEND bit */
    i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);
    
    /* wait until the transmit data buffer is empty */
    while( SET != i2c_flag_get(I2C0, I2C_FLAG_TBE)){
    
    };
	i2c_data_transmit(I2C0, _ucOrder);
	/* wait until BTC bit is set */
	while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)){
    
    };
	/* send a stop condition to I2C bus */

	delay_1ms(80);

	i2c_start_on_bus(I2C0);
	/* wait until SBSEND bit is set */
	while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)){
    
    };
	 
	/* send slave address to I2C bus */
	i2c_master_addressing(I2C0, HTU21D_ADDR, I2C_RECEIVER);

	/* wait until ADDSEND bit is set */
	while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)){
    
    };
	
	/* clear the ADDSEND bit */
	i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);
	/* send a stop condition to I2C bus */

	delay_1ms(5);
	if(i2c_flag_get(I2C0, I2C_FLAG_RBNE)){
    
    
		ucMsb = i2c_data_receive(I2C0);
	}
	if(i2c_flag_get(I2C0, I2C_FLAG_RBNE)){
    
    
		ucLsb = i2c_data_receive(I2C0);
	}
	i2c_ack_config(I2C0, I2C_ACK_DISABLE);
	if(i2c_flag_get(I2C0, I2C_FLAG_RBNE)){
    
    	
		checksum = i2c_data_receive(I2C0);
	}
	i2c_stop_on_bus(I2C0);
	/* wait until the stop condition is finished */
	while(I2C_CTL0(I2C0)&0x0200);

	/* enable acknowledge */
	i2c_ack_config(I2C0, I2C_ACK_ENABLE);

	i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);

	ucLsb &= 0xfc;		//设置分辨率,最低两位为0,温度:14位;湿度:12位 	
	f_RetVal = ucMsb * 256 + ucLsb;/*MSB=(MSB<<=8)+LSB;即将MSB移位到高8位*/

	if(_ucOrder == HTU21D_TEMP)
	{
    
    
	 f_Temp = (175.72)*f_RetVal/65536-46.85;//温度:T= -46.85 + 175.72 * ST/2^16
	 return f_Temp;
	}
	else if(_ucOrder == HTU21D_HUMI)
	{
    
    
	 f_Humi = (f_RetVal*125)/65536-6;//湿度: RH%= -6 + 125 * SRH/2^16
	 return f_Humi;
	}
	else
		return 0;
} 

3.3 测试程序

	htu21d_init();
	f_RetVal = htu21d_measure(HTU21D_TEMP);//得到温度值
	printf("The htu measure temp is :%4.2fC ",f_RetVal);
	printf("");
	htu21d_init();
	f_RetVal= htu21d_measure(HTU21D_HUMI);		//得到湿度值
	printf("The htu measure humi is :%4.2fRH \r\n",f_RetVal);

四、测试

烧录程序后,打印出测量得到的温湿度数据正常。
在这里插入图片描述

五、例程

例程

猜你喜欢

转载自blog.csdn.net/weixin_43810563/article/details/115361693