湿敏电阻CM-R / HR202应用 原理图 IO输出交流 AD采样


【本文发布于https://blog.csdn.net/Stack_/article/details/113827555,未经许可不得转载,转载须注明出处】




在学校里学习时,测量温湿度多用DHT22模块,因为这模块容易上手。但是这个模块很贵,且各DHT22模块温湿度数值不统一还容易坏:手上的几个DHT22湿度误差最大能到20%,且有个别久放之后读到的湿度一直是99%。性价比太低。
用热敏电阻和湿敏电阻测量温湿度是个值得研究的方案。
热敏电阻测温实现起来不难,难在湿敏电阻的使用经验分享是少之又少,花了不少功夫去查资料、研究。

【该文章的方案仅实现了用电阻测量温湿度,不考虑精度】



一、IO测电阻法

数据手册提供的这张电路图,其测量湿敏电阻阻值的过程简单来说就是:
1、所有IO设为输出,拉低,将电容余电放尽;
2、检测电平IO和湿敏电阻IO设为输入,10K电阻IO设为输出并拉高,同时开始计时。电容充电中;
3、检测电平IO变为高电平时(检测电平IO有上升沿中断功能更好),停止计时,记录下这个时间T1;
4、重复1、2、3的步骤,只是步骤2的通过10K电阻充电改为通过湿敏电阻充电,记录下充电时间T2;
5、根据关系式T1 / 10K = T2 / R湿敏,计算出湿敏电阻阻值,查表得到湿度值。

(充放电都确保电流流经湿敏电阻,满足交流的要求应该能大大延长湿敏电阻寿命)

【参考资料】

湿敏电阻CM-R / HR202应用 原理图 IO输出交流 AD采样_第1张图片

官方电路图



==============================================================================



上述方法我未实践过,只实践过下面这个:采用IO模拟交流输出,AD采样的方法。【参考资料】


二、AD测电阻

湿敏电阻CM-R / HR202应用 原理图 IO输出交流 AD采样_第2张图片

DEMO板原理图



湿敏电阻CM-R / HR202应用 原理图 IO输出交流 AD采样_第3张图片

DEMO板

.
.


/**
  * @brief  产生1KHz交流方波
  * @note   固定电阻端和湿敏电阻端IO此高彼低产生交流方波
  * 此函数在main中循环,循环中没有死等的延时,time2_cnt在250us定时中断中递增
  * 如果单片机速度足够快,该函数可直接放置于250us中断中执行
  * @param  None
  * @retval None
  * @author PWH 
  * @ CSDN Tyrion.Mon
  * @date   2021/2
  */
void humd_create_1KHzAndStartAdc(void)
{
	static uint32_t time = 0;
	static uint8_t flag = 1;

	if ((time2_cnt - time) > 0)	//time2_cnt每250us加1
	{
		time = time2_cnt;
		if (flag == 1)	//1KHz开始,固定电阻端拉高,湿敏电阻端拉低
		{
			flag = 2;
			SENSOR_HUMID_10K_GPIO->ODR |= (uint8_t)SENSOR_HUMID_10K_PIN;
			SENSOR_HUMID_RH_GPIO->ODR &= (uint8_t)(~SENSOR_HUMID_RH_PIN);
			return;
		}
		else if (flag == 2)	//高电平二分之一处采样
		{
			flag = 3;
			if (humdHasStart == 1)
			{
				/* Clear the ADC1 channels */
				ADC1->CSR &= (uint8_t)(~ADC1_CSR_CH);
				/* Select the ADC1 channel */
				ADC1->CSR |= (uint8_t)(ADC1_CHANNEL_3);
				ADC1->CR1 |= ADC1_CR1_ADON;
				humdHasStart = 2;
			}
			return;
		}
		else if (flag == 3)	//翻转,固定电阻端拉低,湿敏电阻端拉高
		{
			flag = 4;
			SENSOR_HUMID_RH_GPIO->ODR |= (uint8_t)SENSOR_HUMID_RH_PIN;
			SENSOR_HUMID_10K_GPIO->ODR &= (uint8_t)(~SENSOR_HUMID_10K_PIN);
			return;
		}
		else if (flag == 4)
		{
			flag = 1;
			return;
		}
	}
}

产生1KHz方波


湿敏电阻CM-R / HR202应用 原理图 IO输出交流 AD采样_第4张图片

95%时的1KHz方波

湿敏电阻CM-R / HR202应用 原理图 IO输出交流 AD采样_第5张图片

60%左右湿度的1KHz方波



根据电路设计和湿度-阻值表算出各温湿度、各阻值下的ADC值。CM-R和HR202的曲线较为相似,据说C5-M3可被CM-R替代【HR202手册】【CM-R手册】

解释一下这里的计算公式:

  • 这单片机的AD是10位的,供电3.3V,ADC量程是0~1023
  • 湿敏电阻和10K分压电阻组成的分压电路是成比例地分压,即湿敏电阻为10K时,湿敏电阻分得3.3V÷(10+10)x10,为20K时分得3.3V÷(20+10)x20,可变化为湿敏电阻分得的电压=20K/(20K+10K)x3.3V
  • 分这3.3V相当于分1024的AD值,于是等效于 湿敏电阻AD值=20K/(20K+10K)x1024
  • 当ADC为12位,1024需要改为4096

湿敏电阻CM-R / HR202应用 原理图 IO输出交流 AD采样_第6张图片

Excel计算出AD值
.

/* 各温度下20% 25% 30% 。。。95%对应的ADC值(10位AD) */
@ CSDN Tyrion.Mon
uint16_t const humd_adc[11][16] =
{
	/* 0℃ */
	1023, 1023, 1022, 1020, 1016, 1009, 997, 972, 937, 881, 810, 713, 630, 531, 438, 350,
	/* 5℃ */
	1023, 1022, 1021, 1019, 1014, 1003, 986, 955, 915, 850, 785, 658, 564, 470, 350, 271,
	/* 10℃ */
	1023, 1022, 1020, 1016, 1009,  994, 970, 935, 889, 823, 739, 622, 512, 421, 332, 259,
	/* 15℃ */
	1022, 1021, 1019, 1014, 1004,  986, 955, 912, 853, 777, 682, 568, 461, 391, 307, 236,
	/* 20℃ */
	1022, 1020, 1018, 1012,  999,  976, 936, 883, 815, 726, 622, 522, 428, 332, 259, 198,
	/* 25℃ */
	1021, 1019, 1016, 1008,  990,  960, 911, 850, 774, 682, 600, 470, 379, 287, 224, 170,
	/* 30℃ */
	1021, 1018, 1014, 1004,  987,  953, 899, 834, 750, 630, 536, 435, 345, 265, 198, 156,
	/* 35℃ */
	1020, 1017, 1012, 1000,  982,  945, 883, 801, 713, 590, 490, 387, 307, 224, 163, 133,
	/* 40℃ */
	1019, 1014, 1008,  993,  971,  919, 856, 768, 664, 552, 435, 350, 265, 191, 141, 109,
	/* 45℃ */
	1018, 1012, 1006,  986,  950,  896, 823, 722, 617, 498, 387, 297, 224, 163, 125,  93,
	/* 50℃ */
	1016, 1009, 1000,  972,  938,  868, 785, 670, 566, 448, 336, 254, 211, 141, 109,  84
};

制表
. . .

/**
  * @brief  计算并查表得出湿度值
  * @note
  * @param  None
  * @retval None
  * @author PWH
  * @ CSDN Tyrion.Mon
  * @date   2021/2
  */
uint16_t humd_get(void)
{
	uint16_t adcVal = 0;
	int8_t i = 0;
	uint16_t tempVal = 0;
	uint8_t row = 0;
	adcVal = humd_getAdcValue();	//当前湿度ADC值
	if (!adcVal)					
	{
		return 0xffff;				//AD转换未完成
	}
	tempVal = temp_get_static();	//当前温度值(为实际温度的10倍)
	if (tempVal & 0x8000)			//温度为负
	{
		row = 0;
	}
	else
	{
		row = tempVal / 10 / 5;
	}
	if (row > 10)
	{
		return 0xffff;
	}
	for (i = 15; i > -1; i--)
	{
		if (adcVal <= humd_adc[row][i])
		{
			return (20 + i * 5) * 10;
		}
	}
	return 0xffff;
}


查表

.
.
湿敏电阻CM-R / HR202应用 原理图 IO输出交流 AD采样_第7张图片

测试结果



在这个温湿度下测试结果很理想,和DHT22的数值很接近:温度误差1℃内,湿度5%内。

【该代码没有引入插值算法,如果需要小数部分以作更为精确的测量,可以到我主页找NTC温度采集的文章,参考里面的插值算法】

【电路设计上切记远离热源,尤其是LDO等电源芯片】

(代码写得很随意,上面的描述已经很全了,我整理的文件并不比上面多多少,上面这个上位机也是我简单编写的,酌情下载)
【硬软、文档、调试上位机】

你可能感兴趣的:(MCU,单片机)