搜索
bottom↓
回复: 76

【原创】RC充放电实现温度测量,前一段时间用过的,总结一下

  [复制链接]

出0入4汤圆

发表于 2011-3-28 23:52:27 | 显示全部楼层 |阅读模式
首先检讨一下,用的cpu是本人很不喜欢的甚至讨厌的stc某一系列的,不为别的,就因为
祖父祖母的,太扯淡了。言归正传。。
一提到温度测量,我们通常往往都会想到AD采样,但是在一些对测量精度要求不是很高的场合,

我们是不是可以换一种思路,抛弃AD,用其他的方式来实现呢,呵呵,正好接触到一个项目,所

以打算挑战一下,没错,就是RC充放电来实现温度测量。

先看一下基本的电路连接:

0 (原文件名:RC0.PNG)

图O:cpu拿出三个GPIO管脚,分别连接热敏电阻、100K高精电阻R1、泄流电阻R2,然后

通过一只电容器连接到GND。在这里电容器可以理解成一只小电池,而且还是一只可

充电电池。

1 (原文件名:RC1.PNG)
图1:将RT设置成高阻太(输入),这样热敏电阻相当于断开(虚线),R1设置成输出,泄流电阻R2

设置成输出,如果cpu内部有上拉的话,最好打开,或者配置成强推挽,具体情况根据所选则的cpu而定。

这样R2给电容器充电,程序中一直检测R1管脚,直到R1管脚为高 while(R1 == 1);其实电容器被不一定被充满

电,只要满足R1管脚处的电平对于cpu来说是个高电平就足以。

2 (原文件名:RC2.PNG)
图2:保持RT继续高阻(断开),将R1设置成输出,输出0(低电平),R2设置成输入,此时电容通过100K

高精度电阻进行放电,程序中一直检测R2管脚,直到R2管脚为低电平 while(R2 == 0);记录时间T1,T1就是

电容器通过100k电阻放电所需要的时间。

图3:过程跟图一是一模一样的,给电容器充电(不一定充满),原因你懂的;

3 (原文件名:RC3.PNG)


4 (原文件名:RC4.PNG)
图4:将R1设置成高阻(断开),RT设置成输出,并且输出低电平,将R2设置成输出;此时电容器通过RT进行放电,程序中一直检测R2管脚,直到R2管脚为低电平 while(R2 == 0);记录时间T2,T2就是电容器通过100k电阻放电所需要的时间。



到此,我们就可以算出热敏电阻RT的阻值了:

6 (原文件名:RC6.PNG)


001        /**
002         *青岛昊阳智能微控技术有限公司
003         *
004         * 温度采集
005         * 参考电阻为100 K
006         * @param
007         *              unsigned char channel:采集哪个通道的温度   
008         *              NTP_OUTSIDE: 温控器外部温度探头
009         *              NTP_INSIDE: 温控器内部探头
010         *@return
011         *              ERROR_NTP_PARA_ERROR:参数错误
012         *              ERROR_NTP_LOST_ERROR:温度探头丢失
013         *              非负:采集到的温度值
014         *
015         * @brief
016         *              by kaka,2011,2,20         
017         */
018         
019          
020        #define NTP_CHECK (1)
021        short ntp_100k_get_temperature(unsigned char channel){
022            double x, y, z;
023            unsigned long temperature_cnt_a, temperature_cnt_b;
024            unsigned char tmp;
025         
026            if(channel == NTP_INSIDE){
027                SET_P2(7, IO_PORT_TRI_IN); //参考电阻 输入
028                SET_P2(6, IO_PORT_PULL_OUT); // 泄流电阻输出
029                SET_P4(4, IO_PORT_TRI_IN); // 热敏电阻输入
030         
031                RFL0 = 0; //泄流电阻输出0
032                while(RE0);   // 一直等到电容空
033                
034                RFL0 = 1; //泄流电阻输出1
035                while(!RE0);      // 一直等到电容满
036         
037                SET_P2(7, IO_PORT_NO_PULL_IO); //参考电阻 输出
038                SET_P2(6, IO_PORT_TRI_IN); // 泄流电阻输入
039                SET_P4(4, IO_PORT_TRI_IN);// 热敏电阻输入
040             
041                RE0 = 0; //参考电阻输出0, 给电容放电
042                temperature_cnt_a = 1;
043                while(RFL0){ // 等到电容电量放空
044                    temperature_cnt_a ++;
045                    if(temperature_cnt_a > NTP_MAX_COUNTER){
046                        return ERROR_NTP_LOST_ERROR;
047                    }
048                }
049         
050                SET_P2(7, IO_PORT_TRI_IN); //参考电阻 输入
051                SET_P2(6, IO_PORT_PULL_OUT); // 泄流电阻输出
052                SET_P4(4, IO_PORT_TRI_IN); // 热敏电阻输入
053         
054                RFL0 = 0; //泄流电阻输出0
055                while(RE0);   // 一直等到电容空
056         
057                RFL0 = 1; //泄流电阻输出1
058                while(!RE0);      // 一直等到电容满
059                
060                SET_P2(7, IO_PORT_TRI_IN); //参考电阻 输入
061                SET_P2(6, IO_PORT_TRI_IN); // 泄流电阻输入
062                SET_P4(4, IO_PORT_NO_PULL_IO);// 热敏电阻输出
063                RT0 = 0; //通过热敏电阻给电容充电
064                temperature_cnt_b = 1;
065                while(RFL0){
066                    temperature_cnt_b ++;
067                    if(temperature_cnt_b > NTP_MAX_COUNTER){
068                        return ERROR_NTP_LOST_ERROR;
069                    }
070                }
071            }else if(channel == NTP_OUTSIDE){
072                SET_P2(4, IO_PORT_TRI_IN); //参考电阻 输入
073                SET_P2(3, IO_PORT_PULL_OUT); // 泄流电阻输出
074                SET_P2(5, IO_PORT_TRI_IN); // 热敏电阻输入
075             
076                RFL1 = 1; //泄流电阻输出1
077                while(!RE1);      // 一直等到电容放满
078         
079                SET_P2(4, IO_PORT_NO_PULL_IO); //参考电阻 输出
080                SET_P2(3, IO_PORT_TRI_IN); // 泄流电阻输入
081                SET_P2(5, IO_PORT_TRI_IN);// 热敏电阻输入
082             
083                RE1 = 0; //参考电阻输出0, 给电容放电
084                temperature_cnt_a = 1;
085                while((RFL1)){ // 等到电容电量充满
086                    temperature_cnt_a ++;
087                    if(temperature_cnt_a > NTP_MAX_COUNTER){
088                        return ERROR_NTP_LOST_ERROR;
089                    }
090                }
091                SET_P2(4, IO_PORT_TRI_IN); //参考电阻 输入
092                SET_P2(3, IO_PORT_PULL_OUT); // 泄流电阻输出
093                SET_P2(5, IO_PORT_TRI_IN); // 热敏电阻输入
094             
095                RFL1 = 1; //泄流电阻输出1
096                while(!RE1);      // 一直等到电容满
097                
098                SET_P2(4, IO_PORT_TRI_IN); //参考电阻 输入
099                SET_P2(3, IO_PORT_TRI_IN); // 泄流电阻输入
100                SET_P2(5, IO_PORT_NO_PULL_IO);// 热敏电阻输出
101                RT1 = 0; //通过热敏电阻给电容放电
102                temperature_cnt_b = 1;
103                while(RFL1){
104                    temperature_cnt_b ++;
105                    if(temperature_cnt_b > NTP_MAX_COUNTER){
106                        return ERROR_NTP_LOST_ERROR;
107                    }
108                }
109            }else{
110                return ERROR_NTP_PARA_ERROR;
111            }
112         
113            x = 0;
114            y = temperature_cnt_a;
115            z = temperature_cnt_b*100000;
116            x = z / y;  //热敏电阻除以参考电阻
117            tmp = ntp_100k_conversion(x);
118         
119            return tmp;
120        }

出0入0汤圆

发表于 2011-3-29 00:04:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-29 00:12:36 | 显示全部楼层
不错   标记一下

出0入4汤圆

发表于 2011-3-29 00:14:03 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-3-29 00:16:54 | 显示全部楼层
楼主流程图做得不错

出0入0汤圆

发表于 2011-3-29 07:38:05 | 显示全部楼层
很不错,这样非常方便,而且体积小,不需要电桥和调理电路,一般精度的测量足够了。感谢楼主分享。

出0入0汤圆

发表于 2011-3-29 07:41:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-29 07:58:09 | 显示全部楼层
这个用555是不是会好点,有人说STC的输入触发器有问题(仅是听说),如果接比较器的话就不用校准了

出0入9汤圆

发表于 2011-3-29 08:10:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-29 08:29:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-29 08:40:12 | 显示全部楼层
很形象.我也用过,但是对于热敏电阻的标准值,一直没环境测量,所以变得很被动了.

出50入4汤圆

发表于 2011-3-29 08:48:24 | 显示全部楼层
cool

出0入0汤圆

发表于 2011-3-29 09:22:57 | 显示全部楼层
图很给力

出0入0汤圆

发表于 2011-3-29 09:26:57 | 显示全部楼层
图片很不错

出20入22汤圆

发表于 2011-3-29 09:27:23 | 显示全部楼层
有矛盾的地方,看了晕。

出0入4汤圆

发表于 2011-3-29 09:44:39 | 显示全部楼层
根据顶楼的公式 RT*T2 = R1*T1,R1*T1 是一个固定值,当 RT 变大的时候放电时间会变长,因此 T2 变大,RT*T2 也会变大,这个公式有问题?

出0入0汤圆

发表于 2011-3-29 09:46:25 | 显示全部楼层
记号!!

出0入4汤圆

发表于 2011-3-29 10:23:24 | 显示全部楼层
文章里有几处输入和输出写反了,望楼主编辑一下方便阅读 :)

出0入4汤圆

发表于 2011-3-29 10:55:22 | 显示全部楼层
想问一下,图怎么画的

出0入0汤圆

发表于 2011-3-29 11:08:54 | 显示全部楼层
强~

出0入0汤圆

发表于 2011-3-29 11:12:55 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-29 11:17:41 | 显示全部楼层
好东西,支持

出0入0汤圆

发表于 2011-3-29 11:34:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-29 13:49:07 | 显示全部楼层
mark

出0入4汤圆

 楼主| 发表于 2011-3-29 14:39:49 | 显示全部楼层
回复【18楼】wajlh  
-----------------------------------------------------------------------

图就是用visio画的

出0入4汤圆

 楼主| 发表于 2011-3-29 14:45:46 | 显示全部楼层
回复【15楼】atommann  
-----------------------------------------------------------------------

呵呵,搞错了,谢谢提醒。。

出0入0汤圆

发表于 2011-3-29 14:50:51 | 显示全部楼层
标记

出0入0汤圆

发表于 2011-5-7 11:45:28 | 显示全部楼层
想问下楼主,定时器如何取值比较合适呢·!

如果一直在主程序中跑,中断后,会影响电容放电时间计数吗?

出0入0汤圆

发表于 2011-5-8 22:25:52 | 显示全部楼层
这个要用STC12系例来做吧?

出0入0汤圆

发表于 2011-5-8 22:34:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-8 23:05:24 | 显示全部楼层
图不错!

出0入0汤圆

发表于 2011-5-27 23:22:32 | 显示全部楼层
不错啊,喜欢!

出0入0汤圆

发表于 2011-5-27 23:48:54 | 显示全部楼层
图蛮给力的,不过这个方法哪里看见过。。。

出0入0汤圆

发表于 2011-5-28 01:08:46 | 显示全部楼层
楼主是通过电容放电的时间来测的,好像大家一般都是测电容充电时间的,先充电再测放电时间,这过程中会不会因为电容自漏电造成误差?
我也试验过,也通过读取16位定时器的值来验证,不过我是程序菜鸟,目前只会汇编,不会处理16进制的乘除法,特别是要求精度的情况下还要有余数,所以我只是看看定时器的值判断一下而已,通过串口把定时器的值发回电脑串口软件,读回的定时值很稳定,偶尔偏差一个值,用手捏着传感器读数就变了好多,,

出0入0汤圆

发表于 2011-5-28 06:21:26 | 显示全部楼层
"002         *青岛昊阳智能微控技术有限公司 "

it is incredibly complicated.

you can code it much simpler.

出0入0汤圆

发表于 2011-5-28 08:15:53 | 显示全部楼层
mark

出0入4汤圆

 楼主| 发表于 2011-7-6 15:22:08 | 显示全部楼层
回复【34楼】millwood0  
-----------------------------------------------------------------------

Yes, I think “hanyo” better。。

出0入0汤圆

发表于 2011-7-14 21:10:41 | 显示全部楼层
这个真的很不错,以前做过和这个一样的,检测气敏电阻阻值的,用AVR做的,也是这个原理。
图画得很到位。

出0入0汤圆

发表于 2011-7-29 08:38:01 | 显示全部楼层
STC做不到的。

出0入0汤圆

发表于 2011-7-29 08:42:18 | 显示全部楼层
不错,标记一下

出0入0汤圆

发表于 2011-7-29 13:17:41 | 显示全部楼层
标记一下,以后用的到

出0入0汤圆

发表于 2011-7-29 13:24:00 | 显示全部楼层
记录时间T2,T2就是电容器通过100k电阻放电所需要的时间。
应该是"记录时间T2,T2就是电容器通过RT电阻放电所需要的时间。"

出0入0汤圆

发表于 2011-7-29 13:27:47 | 显示全部楼层
哇哦,虽然不是啥新东西。。。不过那几个图画得很好。赞~

【34楼】 millwood0 说的对,代码太过复杂了。

而且,对于有三态IO的单片机来说,两个IO就够了,一个Rt,一个电容,足矣。
说到底都是AD转换。只是形式不同而已。

话说不带AD的单片机也多数都带个比较器,用它做更好。

出0入0汤圆

发表于 2011-7-29 13:44:58 | 显示全部楼层
回复【15楼】atommann
根据顶楼的公式 rt*t2 = r1*t1,r1*t1 是一个固定值,当 rt 变大的时候放电时间会变长,因此 t2 变大,rt*t2 也会变大,这个公式有问题?
-----------------------------------------------------------------------

RT/T2 = R1/T1, 你弄反了.

出0入0汤圆

发表于 2011-7-29 13:47:00 | 显示全部楼层
两个IO精度会下降的. 必须用同一个IINPUT检测"高",用同一个INPUT检测"低",否则精度很差.

出0入4汤圆

发表于 2011-7-30 21:35:05 | 显示全部楼层
回复【43楼】gwdong  
回复【15楼】atommann
根据顶楼的公式 rt*t2 = r1*t1,r1*t1 是一个固定值,当 rt 变大的时候放电时间会变长,因此 t2 变大,rt*t2 也会变大,这个公式有问题?
-----------------------------------------------------------------------
rt/t2 = r1/t1, 你弄反了.
-----------------------------------------------------------------------

gwdong,你没有读懂我的话,我说“根据顶楼的公式 rt*t2 = r1*t1”,这个公式就是顶楼最初的公式,我质疑的就是这个公式有问题。楼主现在的公式是重新修改过的了。

出0入4汤圆

发表于 2011-7-30 21:36:29 | 显示全部楼层
回复【43楼】gwdong  
回复【15楼】<span highlight="search">atommann</span>
根据顶楼的公式 rt*t2 = r1*t1,r1*t1 是一个固定值,当 rt 变大的时候放电时间会变长,因此 t2 变大,rt*t2 也会变大,这个公式有问题?
-----------------------------------------------------------------------
rt/t2 = r1/t1, 你弄反了.
-----------------------------------------------------------------------

你看一下楼主在 25 楼的回复。

出0入0汤圆

发表于 2011-7-30 22:07:41 | 显示全部楼层
MARK!!

出0入0汤圆

发表于 2011-11-8 22:24:48 | 显示全部楼层
NTC这个鬼东西用在工业上可靠性很难保证.

出0入0汤圆

发表于 2011-11-9 01:20:12 | 显示全部楼层
mark

出0入228汤圆

发表于 2011-11-9 01:47:04 | 显示全部楼层
顶顶

出0入0汤圆

发表于 2011-11-9 21:59:49 | 显示全部楼层
没有这个必要吧

出0入0汤圆

发表于 2011-12-11 22:11:47 | 显示全部楼层
图片很给力

出0入0汤圆

发表于 2011-12-11 22:49:28 | 显示全部楼层
顶一下,

出145入215汤圆

发表于 2011-12-12 08:22:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-5-29 10:02:40 | 显示全部楼层
好东西,做个记号先。

出0入0汤圆

发表于 2012-5-29 10:16:28 | 显示全部楼层
图很喜欢,哈哈~~

出0入10汤圆

发表于 2012-5-29 12:58:02 | 显示全部楼层
简易的AD转换,这样算比较经济的了

出0入0汤圆

发表于 2012-5-29 22:25:36 | 显示全部楼层
图做的真好

出0入0汤圆

发表于 2012-7-28 21:46:11 | 显示全部楼层
有空试试

出0入0汤圆

发表于 2012-7-29 09:00:55 来自手机 | 显示全部楼层
留个记号…呵呵…以后回去看

出0入0汤圆

发表于 2013-6-16 18:52:34 | 显示全部楼层
谢谢分享,学习了

出0入0汤圆

发表于 2013-8-14 20:39:25 来自手机 | 显示全部楼层
mark……
顶一个…

出0入0汤圆

发表于 2013-8-17 18:10:05 | 显示全部楼层
收藏了,分析的很仔细!

出0入0汤圆

发表于 2013-8-18 08:46:06 | 显示全部楼层
mark ~      

出0入85汤圆

发表于 2013-8-18 09:26:09 | 显示全部楼层
RC的充放电不是不可以,只是RC是非线性的DD,所以温度需要你重新标定的,还有就是RC的充放电太依赖于RC的稳定性,这个问题你想吧

出0入0汤圆

发表于 2013-8-23 14:09:35 | 显示全部楼层
标记一下

出10入95汤圆

发表于 2014-1-9 00:13:06 | 显示全部楼层
图画得很不错呀

出0入0汤圆

发表于 2014-1-9 09:32:35 | 显示全部楼层
好东西........................

出0入53汤圆

发表于 2014-12-22 16:35:20 | 显示全部楼层
longquan 发表于 2011-3-29 07:58
这个用555是不是会好点,有人说STC的输入触发器有问题(仅是听说),如果接比较器的话就不用校准了 ...

555请楼上的晒晒原理图

出0入53汤圆

发表于 2014-12-24 16:53:29 | 显示全部楼层
请问lz 用这种方法那HR202湿敏电阻改如何测量呢

出0入0汤圆

发表于 2014-12-24 18:02:35 | 显示全部楼层
感觉不错,学习下!

出0入4汤圆

发表于 2014-12-25 09:54:20 | 显示全部楼层
楼主,啥也不说,就是吊,就是任性

出0入0汤圆

发表于 2016-2-26 12:30:57 | 显示全部楼层
为什么电容充电不需要充满也可以啊

出0入0汤圆

发表于 2016-3-4 21:59:45 | 显示全部楼层
markmarkmarkmark

出0入4汤圆

发表于 2016-3-7 12:45:13 | 显示全部楼层
好东西,收藏一下

出0入0汤圆

发表于 2016-3-8 08:49:30 | 显示全部楼层
楼主的图通俗易懂.顶
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 06:00

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表