芯源半导体CW32
直播中

hehung

8年用户 659经验值
擅长:嵌入式技术
私信 关注
[经验]

【CW32饭盒派开发板试用体验】6.硬件I2C之连接HS300X读取温湿度数据

【CW32饭盒派开发板试用体验】1. 开箱啦

【CW32饭盒派开发板试用体验】2. 使用扩展板串口UART3以及scanf重定向到串口

【CW32饭盒派开发板试用体验】3. 使用BTIM实现任务调度器

【CW32饭盒派开发板试用体验】4. ADC采样摇杆模块X轴和Y轴输出

【CW32饭盒派开发板试用体验】5. 极简方式移植FreeRTOS成功

1 HS3003介绍

HS3003是瑞萨的一款温湿度传感器,基于IIC通信。其通信原理比较简单,可以直接参考HS300x的数据手册。

其IIC地址为0x44,想知道其原理,可以参考我之前发布的帖子【RA4M2设计挑战赛】2. 硬件IIC读取HS3003的温湿度数据

2 硬件连接

因为采用IIC接口,所以需要使用到单片机的IIC接线,可以使用软件IIC和硬件IIC,因为CS32F030带有两路IIC接口,所以选择使用硬件IIC来进行通信,速度快而且操作方便。

查看原理图,看到了扩展板有引出IIC插口,所以就拿来使用了,HS3003直接插上就可以正常使用。

接线如下:

  • SCL - PB6
  • SDA - PB7

对应I2C1。

1685798177420.png

1686145322989.png

1685798116331.png

3 软件开发

知道了硬件连接,接下来开始进行软件开发。

参考官方提供的I2C的示例工程,在此基础上做了如下更新。

3.1 修改Slave地址

官方的I2C中的驱动代码,将I2C地址定死了,我们需要修改地址为(0x44<<1),因为HS3003的地址为0x44,而驱动代码的地址为7位地址加上读写位,所以我们需要将真实地址右移一位。
1686144435643.png

3.2 驱动代码

3.2.1 初始化

初始化代码如下,初始化引脚PB6,PB7复用为I2C。设置通信速率为400K,通信速率计算公式:时钟频率/(8*(设定值+1)),时钟频率为64000000,想要通信速率为400K,则需要设定值为19,即十六进制的0x13(I2C_InitStruct.I2C_Baud = 0x13;)。

void I2c_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	I2C_InitTypeDef I2C_InitStruct;

	__RCC_GPIOB_CLK_ENABLE();
	// COnfigure the systems
	__RCC_I2C1_CLK_ENABLE();

	// Configure the I2c1 port pin 
	PB06_AFx_I2C1SCL();
	PB07_AFx_I2C1SDA();
	GPIO_InitStructure.Pins = GPIO_PIN_6 | GPIO_PIN_7;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD; //GPIO_MODE_OUTPUT_PP; //
	GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
	GPIO_Init(CW_GPIOB, &GPIO_InitStructure);

	// Initialize the I2c1
    I2C_InitStruct.I2C_BaudEn = ENABLE;
	I2C_InitStruct.I2C_Baud = 0x13;  //400K=(64000000/(8*(19+1))
    I2C_InitStruct.I2C_FLT = DISABLE;
    I2C_InitStruct.I2C_AA = DISABLE;

	I2C1_DeInit(); 
	I2C_Master_Init(CW_I2C1,&I2C_InitStruct);//初始化模块
	I2C_Cmd(CW_I2C1,ENABLE);  //模块使能
}

3.2.2 HS3003驱动代码

  • Hs300x_StartSample为开始采样代码:即只发送HS3003地址表示开始采样
  • Hs300x_ReadData为读取采样结果,开始采样和读取采样结果之间需要一个35ms左右的延时,因为采样精度越高,时间消耗越长,本文使用HS3003的默认设置,最高采样精度,需要大约33ms左右。
  • Hs300x_DataConvert为温湿度转换,将采样结果转换为温湿度数值并通过串口打印。
static uint8_t Hs300x_DataConvert(uint32_t read_data, s_Hs300xDataType *cal_result)
{
	uint32_t humi_data;
	uint32_t temp_data;

    if (((read_data & HS300X_STATUS_MASK) >> HS300X_STATUS_POS) == HS300X_DATA_VALID)
	{
		// Data is valid
		humi_data = (read_data & HS300X_HUMI_DATA_MASK) >> HS300X_HUMI_DATA_POS;
		temp_data = (read_data & HS300X_TEMP_DATA_MASK) >> HS300X_TEMP_DATA_POS;

		// Calculate the humidity: humi_data/(2^14-1) * 100
		cal_result->humi = (double)humi_data/(double)(HS300X_DATA_FACTOR) * 100.0;
		// Calculate the temperature: temp_data/(2^14-1) * 165 - 40
		cal_result->temp = (double)temp_data/(double)(HS300X_DATA_FACTOR) * 165.0 - 40;
#ifdef HS300X_DEBUG
		printf("humidity:%f, temperature:%f\n", cal_result->humi, cal_result->temp);
#endif

		return 1;
	}
	else
	{
		return 0;
	}
}

void Hs300x_StartSample(void)
{
	uint8_t data = 0;

	// Send Hs30x address
	I2C_MasterSendDataToSlave(CW_I2C1, &data, 0);
}

s_Hs300xDataType Hs300x_ReadData(void)
{
    uint8_t data[4];  // one address + 4bytes data
	uint32_t data_u32;
	s_Hs300xDataType humi_temp;

	// Read measurement from sensor HS300X
	I2C_MasterRecDataFromSlave(CW_I2C1, data, 4);
	// Convert the data to 32bit
	data_u32 = (uint32_t)((data[0] << 24U) | 
	                      (data[1] << 16U) | 
	                      (data[2] << 8U) | 
	                      (data[3]));
	// Read the temperature and hunidity
	(void)Hs300x_DataConvert(data_u32, &humi_temp);

//#ifdef HS300X_DEBUG
	printf ("HS300X origin data1:%x%x%x%x\r\n", data[0],data[1],data[2],data[3]);
	// printf("HS300X origin data2:%x\n", data_u32);
	printf ("Temp:%f--Humi:%f\r\n", humi_temp.temp, humi_temp.humi);
//#endif

	return humi_temp;
}

3.2.3 主函数

主函数实现如下:

int main()
{
	RCC_Configuration();  // 64MHz clock
	UART_init();          // UART initialization
	I2c_Init();

	while(1)
	{
		Hs300x_StartSample();
		delay();
		Hs300x_ReadData();
		delay();
	}
}

4 实验效果

如下是试验结果,可以看到,温湿度采集成功,将手放到传感器上,温湿度数值会变大。
1686143864183.png

更多回帖

发帖
×
20
完善资料,
赚取积分