制冷片温差测量

温度数据采集处理:

主要原理是使用ADC采集模拟量并转化为数字量, 并由89C52单片机通过串口通信发送给计算机

外围电路图:

image-20201013215847395

image-20201013215606799

image-20201013220048634

  1. 使用PT100作为作为温度传感器
  2. 使用1/4w色环电阻作为分压电阻
  3. 使用XPT2046作为ADC
  4. 使用89C52作为MCU

数据采集步骤:

  1. 连接外部电路
  2. 设置串口波特率4800
  3. 串口发送 1, 控制MCU开始采集数据
  4. 打开设备电源, 快速调节制冷片电流至指定值
  5. 待数据稳定后(约1min~1min30s), 串口发送 2, 控制MCU停止数据采集
  6. 保存串口数据, 开始数据处理

数据处理:

串口接收的数据为xpt2046采集后的未经处理的值, 通过额外的C++ 程序将这些数据转化为温度:

物理量意义:

image-20201013221422395

计算公式:

image-20201013222436244

一些常量的测量值(实验平台不同, 数值不同):

image-20201013222444682

通过Excel将温度数据转化为折线图:

image-20201013222643223

通过Matlab将数据拟合成光滑曲线:

待完成

数据采集+通信程序源码:

MCU与ADC之间的驱动程序这里不做展开分析, 直接放上源码:

xpt2046.h

#ifndef __XPT2046_H_
#define __XPT2046_H_
#define u1 unsigned char
#define u2 unsigned int

sbit din=P3^4;
sbit cs=P3^5;
sbit dclk=P3^6;
sbit dout=P3^7;


void delay5us(void);   //误差 0us
u2 adread(u1 com);
u2 readdata();
void senddata(u1 com);



#endif


xpt2046.c

#include "reg52.h"
#include "xpt2046.h"


void senddata(u1 com)
{
	u1 f1;
	cs=0;
	dclk=0;
	for(f1=0;f1<8;f1++)
	{
		com=com<<1;
		din=CY;
		dclk=1;
		dclk=0;
	}
}

u2 readdata()
{
	u2 dat;
	u1 f2;
	cs=0;
	dclk=0;
	for(f2=0;f2<12;f2++)
	{
		dat=dat<<1;
		dat=dat|dout;
		dclk=1;
		dclk=0;
	}
	return dat;
}

u2 adread(u1 com)
{
	u1 f1;
	u2 addat;
	senddata(com);
	for(f1=6;f1>0;f1--);
	dclk=1;
	dclk=0;
	addat=readdata();
	cs=1;
	return addat;

}

AD转换(XPT2046).c

//头文件引入//
#include "reg52.h"
#include "xpt2046.h"
#include "stdio.h"
#define u1 unsigned char
#define u2 unsigned int

sbit a1=P2^2;
sbit a2=P2^3;
sbit a3=P2^4;


u1 code c1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
u1 v[4];
u1 flag=0,flag2=0,flag3;
float t2;
u2 dat,dat2;
void datapro();

//子函数定义//
void delayms(u2 xx)		 	          //延时函数定义//
{
	u2 i;								 //延时函数两个参数都要  U2
    u2 o;
    for(o=xx;o>0;o--)
    	for(i=124;i>0;i--);
}
//中断配置//
void sdeploy()
{
	T2CON=0x34;
	IE=IE|0x90;
	PCON=0x00;
	SCON=0x50;
	RCAP2H=0XFF;
	RCAP2L=0XB1;
/*	IP=0X10;	 */
}
void t1intdeploy()
{
	TMOD=TMOD|0x10;
	TH1=0x3C;				   //每50ms溢出一次//
	TL1=0xb0;
	TR1=0;
	IE=IE|0x08;

}
void t1int()interrupt 3
{
    u1 t;
	TF1=0;
	TH1=0x3C;				  
	TL1=0xb0;
	t++;
	if(t==2)
	{
		t=0;
		flag2=1;
	}
}
//数据处理//
void datapro()
{
	dat=adread(0xE4);
	delayms(1);
	dat2=adread(0xD4);
}
//数码管显示函数//
void smgdisplay()
{
	u1 g;
	for(g=0;g<4;g++)
	{
		switch(g)
		{
			case(0):					  //逐个选择case发送段选数据//									 
				a1=0;a2=0;a3=0;
				break;
			case(1):
				a1=1;a2=0;a3=0;
				break;
			case(2):
				a1=0;a2=1;a3=0;
				break;
			case(3):
				a1=1;a2=1;a3=0;
				break;
	
		}
		P0=v[g];
		delayms(1);					   //延时//
		P0=0x00;
		delayms(1);					//消影//		   
    }

}
void judge()
{
	switch(flag)
	{
		case(1):
			ES=0;
			TI=1;
			printf("Open ADC\n");
			while(TI==0);
			TI=0;
			TR1=1;
			flag=0;
			ES=1;
			break;
		case(2):
			ES=0;
			TI=1;
			printf("Close ADC\n");
			while(TI==0);
			TI=0;
			TR1=0;
			flag=0;
			ES=1;
			break;
		case(3):
			ES=0;
			TI=1;
			printf("Error\n");
			while(TI==0);
			TI=0;
			flag=0;
			ES=1;
			break;
	}
}
void main()
{
	t1intdeploy();
	sdeploy();
	v[0]=c1[0];
	v[1]=c1[0];
	v[2]=c1[0];
	v[3]=c1[0];
	while(1)
	{
		judge();
		smgdisplay();
		if(flag2==1)
		{
			datapro();
			v[0]=c1[dat%1000%100%10];
			v[1]=c1[dat%1000%100/10];
			v[2]=c1[dat%1000/100];
			v[3]=c1[dat/1000];
			t2=(float)dat*5.0/4096.0;
			flag2=0;
			ES=0;
			TI=1;
//			printf("The Voltage is %fV\n",t2);
			printf("%d\n%d\n",dat,dat2);
//			printf("%d\n",dat2);
			while(TI==0);
			TI=0;
			ES=1;
		}

	}	
}

//T2中断服务任务分配//
void sint()interrupt 4
{
	u1 a;
	RI=0;
	a=SBUF;	
	switch(a)
	{
		case(0x31):
			flag=1;
			break;
		case(0x32):
			flag=2;
			break;
		default:
			flag=3;
	}
	a=0;	 
}

数据处理源码:

#include <iostream>
#include <bits/stdc++.h>
#include <cstdio>
#include <fstream>
#include <sstream>
#include <time.h>

using namespace std;

int main(int argc, char *argv[]){

	fstream fIn;
	fIn.open ("data.txt",ios_base::in);
	auto fOut=fopen("dataOut1.txt","w+");
	auto fOut2=fopen("dataOut2.txt","w+");

	string lineNow;

	/**
	 * Vcc		输入电压
	 * R1		分压电阻实际阻值
	 * R0_0		测量系统短接阻值
	 * u1		分压电阻电压
	 * u0		PT100电压
	 * r0		PT100电阻
	 * t0		PT100理论计算温度
	 * segDis	单片机原始数据
	 */
	const double Vcc=5.03, R1=99.7, R0_0=3.7;
	double u1, u0, r0, t0;
	int segDis;
	stringstream ss;

	int startTime=clock ();

	getline(fIn,lineNow);
	while(lineNow!="Open ADC"){
		getline(fIn,lineNow);
	}
	getline(fIn,lineNow);
	while(lineNow!="Close ADC"){
		ss<<lineNow;
		ss>>segDis;
		ss.clear();
//		printf("%d\n",segDis);
		u1=segDis*1.0/4096*Vcc;
		u0=Vcc-u1;
		r0=u0/(Vcc-u0)*R1-R0_0;
		t0=(r0/100-1)/0.00390802;
		fprintf(fOut,"%lf\n",t0);
		getline(fIn,lineNow);

		ss<<lineNow;
		ss>>segDis;
		ss.clear();
//		printf("%d\n",segDis);
		u1=segDis*1.0/4096*Vcc;
		u0=Vcc-u1;
		r0=u0/(Vcc-u0)*R1-R0_0;
		t0=(r0/100-1)/0.00390802;
		fprintf(fOut2,"%lf\n",t0);
		getline(fIn,lineNow);
	}
	fIn.close ();
	printf("数据处理结束, 耗时%d mm",clock ()-startTime);

	return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值