搜索
bottom↓
回复: 22

使用RC冲放电的温度计

[复制链接]

出0入0汤圆

发表于 2008-4-27 07:26:37 | 显示全部楼层 |阅读模式
______
IN)----|__100_|-------
             ______       |     | |
REF)----|__10K_|------------| |---(GND)
             ______       |     | |
RX)---------|__RT _|-------


(原文件名:测温.jpg)
使用夏普传真上拆的LCD的测试图;
这是主程序,不含RT转换函数和LCD显示,稍加修改就能用:
#include <avr/io.h> //MCU为ATmega48
#include <stdio.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <avr/sleep.h>

#include "lcd.h"
#include "lcdTimer.h"
#include "r2t.h"

#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

//电阻测试引脚
#define RESPOR PORTD
#define RESDDR DDRD
#define RESPIN PIND

#define INP 2
#define RXP 1
#define RFP 0

//开始计时
#define STARCT() TCCR1B = 0x01;        //1=不分频;2=8分频内部计数器
unsigned char buff[17];

#define TESTN        10        //测试平均数

int Vout;

ISR(SIG_OUTPUT_COMPARE0A)
{
        uint ms;
        ms++;
        if(ms > Vout)  LCD_write_char(15,'1');
        else  LCD_write_char(15,'0');
       
        if(ms > 5000) ms = 0;
                       
}
ISR(SIG_INTERRUPT0)
{
        //停止计数
        TCCR1B = 0;       
        EIMSK &=  ~_BV(INT0);                //禁用外部中断0
}
void resinit(void)
{
        ///////////////////////////////////////////
        /////////////电阻测试初始化////////////////
       
        //端口设置为输入
        RESPOR &= ~(_BV(RFP) | _BV(INP) | _BV(RXP));
        RESDDR &= ~(_BV(RFP) | _BV(INP) | _BV(RXP));
       
        //定时器设置
        TCCR1A = 0x00;
        //TCCR1B = 0x02;        //8分频内部计数器
        TCCR1C = 0x00;
        //TIMSK1 |= _BV(TOIE1);        //开定时中断;
        TIFR1 |= _BV(TOV1);                //清定时中断;
       
        //输入中断设置
        EICRA = 0x2;                //外部中断0为引脚下降沿触发
        EIFR  |=  _BV(INT0);
        EIMSK |=  _BV(INT0);                //允许外部中断0
}
void testrf(void)
        //测试基准电阻
{
        ////////////////电阻时间测试//////////////////

        //端口设置为输入
        RESPOR &= ~(_BV(RFP) | _BV(INP) | _BV(RXP));
        RESDDR &= ~(_BV(RFP) | _BV(INP) | _BV(RXP));
        //放电
        RESDDR |= _BV(INP);
        RESPOR |= _BV(INP);
        Delay_10ms(50);
        RESDDR &= ~_BV(INP);
        RESPOR &= ~_BV(INP);
                       
        //清零
        TCNT1 = 0;
               
        //开外部中断
        EIMSK |= _BV(INT0);
        EIFR  |=  _BV(INT0);
        EIMSK |=  _BV(INT0);                //允许外部中断0
               
        //充电
        RESPOR &= ~_BV(RFP);
        RESDDR |= _BV(RFP);
       
        //开始计数
        STARCT();
               
        //等待转换结果
        while((RESPIN & _BV(INP)))
        {
                set_sleep_mode(0);
        }
}       
void testrx(void)
        //测试输入电阻
{
        ////////////////电阻时间测试//////////////////

        //端口设置为输入
        RESPOR &= ~(_BV(RFP) | _BV(INP) | _BV(RXP));
        RESDDR &= ~(_BV(RFP) | _BV(INP) | _BV(RXP));
        //放电
        RESDDR |= _BV(INP);
        RESPOR |= _BV(INP);
        Delay_10ms(50);
        RESDDR &= ~_BV(INP);
        RESPOR &= ~_BV(INP);
                       
        //清零
        TCNT1 = 0;
               
        //开外部中断
        EIMSK |= _BV(INT0);
        EIFR  |=  _BV(INT0);
        EIMSK |=  _BV(INT0);                //允许外部中断0
               
        //充电
        RESPOR &= ~_BV(RXP);
        RESDDR |= _BV(RXP);
       
        //开始计数
        STARCT();
               
        //等待转换结果
        while((RESPIN & _BV(INP))) set_sleep_mode(0);
}       
int main(void)
{
        timers_init();                //初始化系统定时器
    LCD_init();                 //初始化LCD1602
        write_command(0x01);  //清屏--对应清屏指令
        Delay_10ms(2);
        resinit();                        //初始化电阻测试
        sei();
       
        while(1)
        {
                float tmprf,tmprx,tmp;
                uint bufrf[TESTN],bufrx[TESTN],h,l;
                uchar i,tn;
               
                if(++tn >=TESTN) tn = 0;
                testrf();
                bufrf[tn] = TCNT1;
               
                testrx();
                bufrx[tn] = TCNT1;
               
               
                tmprf = 0;
                for(i=0;i<TESTN;i++)
                {
                        tmprf += bufrf;
                }
                tmprf /= TESTN;
               
                tmprx = 0;
                for(i=0;i<TESTN;i++)
                {
                        tmprx += bufrx;
                }
                tmprx /= TESTN;
                tmp = (tmprx * 10)/tmprf;
               
                h = r2t(tmp)/10;
                l = r2t(tmp)%10;
               
//                sprintf(buff,"R=%d,T=%d.%dC",(int)(tmp*10),h,l);
                sprintf(buff,"O=%d,T=%d.%d   ",Vout,h,l);
            LCD_write_string(0,buff);
               
//                Vout = pid(r2t(tmp),Vout,200);
//                if(Vout >=5000) Vout = 5000;
//                if(Vout <=0) Vout=0;
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2008-4-28 18:59:19 | 显示全部楼层
遇到老乡了!呵呵;
这一个在室温段可以接近0.2℃的精度,是一个产品的测试代码

出0入0汤圆

 楼主| 发表于 2008-4-30 07:07:26 | 显示全部楼层
有一些MCU本身有硬件的RC型AD,可以简化测试,我得这个程序使用的中断处理的,电阻较小的时候误差较大,在产品中已经修改了,是用IO直接驱动LCD的,在2。5-3。6V可以获得比较好的效果和精度,以前直接驱动LED时会有测量干扰比较大的情况,现在没有试过;
用NTC最大的特点是价格便宜,PT1000的精度很高稳定性也好,只是最便宜的也要十几,NTC国产的1%精度精度约0.3℃在20只对比时基本在0.2℃以下,采用进口的0.5%的NTC(要几元一只)接近精度0.1℃,当然工作于200℃以下还行如果到近300的时候几个小时之后就不准了,相比PT1000稳定性相差太多了,估计楼上的朋友用于暖气表时温度不会太高,可以考虑用NTC降低成本,在电线比较长的时候NTC也有较小的误差,PT的要达到精度需要考虑补偿了

出0入0汤圆

 楼主| 发表于 2008-4-30 12:13:30 | 显示全部楼层
AVR的AD大多是10位的,注定了测试的分辨率,假设传感器是可以变换为线性输出的电压信号,那在-20+80℃的测温范围可以得到0.1的分辨率,如果再宽的话就不行了,至少需要想些办法;RC振荡型会对环境有较高的要求,尤其是精密的电容器,也就是温度系数了,再者他需要其他元件配合,廉价的555可以做到,只是精度很低,精度高的价格又高,有时不如直接用高分辨率的ADIC;RC冲放电是比较折中的方法,精度主要依靠基准电阻和定时器,速度会比较慢,对于较小的电阻会有较大的误差,主要来源是IO电阻,会和环境电源电压有关;还有就是电容的吸收误差了,通常CBB的小些
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-28 19:35

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

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