基于51单片机的热电偶测温系统仿真

仿真图:

仿真

功能简介:

采用51单片机作为控制器,最小系统由晶振和复位电路组成
液晶显示采用LCD1602用于显示该项目的参数信息
具有多个功能按键,分别是设置、加、减和退出按键
采用AD623放大器将传感器信号放大,之后送入MAX1240将模拟信号转换为数字信号再送入单片机处理

芯片/模块的特点:

AD623特点:
差分放大器设计:AD623采用差分放大器架构,能够对差分信号进行放大。这使得它适用于测量和放大微弱差分信号的应用。

高增益:AD623具有高增益特性,可以提供大幅度的信号放大。它可以根据应用需求设置不同的增益值,从几十倍到几千倍不等。

低功耗:AD623采用低功耗设计,在工作时功耗较低。这使得它适用于对功耗要求较高的电池供电应用。

宽工作电压范围:AD623能够在宽广的电源电压范围内工作,通常为单一供电电压范围(3V至12V)。这使得它适用于各种不同电源供电系统的应用。

高共模抑制比(CMRR):AD623具有高CMRR,可以抑制共模信号对输出的干扰。这使得它适用于高噪声环境下的应用,提供清晰的信号放大。

可调零漂和增益:AD623具有可调节的零漂和增益功能,可以通过外部电阻调整。这使得它适应不同的应用需求和电路配置。

低输入偏置电流:AD623具有低输入偏置电流,可以减少对信号源的负载影响,提供更准确和稳定的信号放大。

MAX1240特点:
12位分辨率:MAX1240具有12位的分辨率,能够将模拟输入信号转换为12位的数字输出。这使得它能够提供较高的精度和细微的细节捕捉能力。

4通道输入:MAX1240具有4个模拟输入通道,可以同时转换不同的模拟输入信号。这使得它适用于监测、采集多个信号源的应用。

串行输出:MAX1240的输出数据通过串行接口进行传输,可以方便地与其他数字设备进行通信。这种串行输出使得数据传输更加简单和可靠。

内部参考电压:MAX1240集成了内部参考电压源,可以提供稳定且精确的参考电压。这样可以简化系统设计,并提高转换的准确性。

低功耗:MAX1240采用低功耗设计,在工作时功耗较低。这使得它适用于对功耗要求较高的电池供电应用,延长设备的电池寿命。

外部触发模式:MAX1240支持外部触发模式,可以通过外部信号触发转换过程。这使得它适应需要根据特定事件或时序进行转换的应用。

多种封装形式:MAX1240可以提供不同的封装形式,如多引脚直插式封装(DIP)和表面贴装技术(SMT)封装。这使得它适应不同应用的安装需求

主程序:

#include <reg52.h>
#include <string.h>
#include <math.h>
#include "intrins.h"

#define ROW1 0x80
#define ROW2 0xC0
#define Ts_CONST 1		//AD采样时间系数,采样时间为0.1xTs_CONST(s)

#define NOACT 0
#define FC 1
#define Start_AD 2
#define Cal_Temperature 3

#define Kpt 0.02732644	 //AD芯片max1240的采样值到温度值的转化系数


void LCD_Init(void);
void ClearDisp(unsigned char Row);
void Display(unsigned char Addr, unsigned char *pstr);
void DecToASC(unsigned int Dec,unsigned char *p, unsigned char n);
void Disp_Initize(void);
void Write_CMD(unsigned char CMD);

unsigned int AD_MAX1240(void);

sbit RS=P2^7;
sbit RW=P2^5;
sbit E=P2^6;

sbit SDA=P1^0;
sbit SCL=P1^1;
sbit CS=P1^2;

sbit Key=P3^5;
sbit up=P3^4;
sbit down=P3^6;



unsigned char DispBuf[16];

unsigned char RunState=NOACT;
unsigned int AD_Reslut,tsflag,ts=1;


float  fz,tmp,tmp1,Pt;

void delay(unsigned int j)//延时jms
{
    unsigned int m,n;
    for(n=0;n<j;n++)
      {
       for(m=0;m<120;m++);
       }
}


void main(void)
{	LCD_Init();
	ClearDisp(ROW1);

	Disp_Initize();

	CS=1;
	SDA=1;
	SCL=0;

	TMOD=0x11;
	TF0=0;		//开始程序前先延时65ms,等待max1240上电,以保证AD采样准确
				
	TH0=0;
	TL0=0;
	TR0=1;
	while(!TF0);
	TF0=0;
	TR0=0;

	TH0=0x3C;		//12M晶振时延时50ms
	TL0=0xB0;
	ET0=1;
	TR0=1;

	EX1=1;
	IT1=1;

	EA=1;

	while(1)
		switch(RunState)
		{	case NOACT:
				break;
			case FC:	//F0计算及显示
				fz=pow(10,(tmp-121.0000)/10);
				DecToASC(fz,DispBuf,1);
				DispBuf[1]='.';
				DecToASC((fz-(unsigned int)fz)*1000,DispBuf+2,3);
				DispBuf[5]='\0';
				Display(0x80+11,DispBuf);
					
				

				RunState=NOACT;
				break; 
			case Start_AD:                          //开始AD采样

				AD_Reslut=AD_MAX1240();

				RunState=Cal_Temperature;
				break;
			case Cal_Temperature: 				    //将AD值转化为温度并进行线性化
			{ 
				
				Pt=AD_Reslut*Kpt;
				Pt+=100;	  //温度值
					

				tmp=Pt/100;
				tmp=1-tmp;
				tmp=2.31e-6L*tmp;
				tmp+=1.527480889e-5L;
				tmp=sqrt(tmp);
				tmp+=-3.9083e-3L;
				tmp/=-1.155e-6L;//AD采样值线性化修正
				tmp1=tmp;
				tmp=(tmp+tmp1)/2;//取平均温度
				tmp=((float)((unsigned int)(tmp*10)))/10 ;

				DecToASC(tmp,DispBuf,3);
				DispBuf[3]='.';
				DecToASC((tmp-(unsigned int)tmp)*10,DispBuf+4,1);
				DispBuf[5]='\0';
				Display(0xC0+2,DispBuf); //显示函数
			  }
	
				RunState=NOACT;
				break;
		}
}
/*******************************************************************************/
unsigned int AD_MAX1240(void)	//读取AD,AD芯片为串口数据形式
{	unsigned int adtmp=0;	
	unsigned char i;

	CS=0;
	while(!SDA);

	SCL=1;
	adtmp<<=1;
	SCL=0;

	for(i=0;i<12;i++)
	{	SCL=1;
		adtmp<<=1;
		if(SDA==1)adtmp++;
		SCL=0;
	}

	CS=1;

	return adtmp;
}
/*******************************************************************************/
void Disp_Initize(void)				//LCD初始化,将Ts,F0,t等提示字符显示在屏幕上
{	//unsigned char *p;

	
	
	DispBuf[0]='T';	
	DispBuf[1]='s';
	DispBuf[2]='=';
	DecToASC(ts,DispBuf+3,2);
	DispBuf[5]='s';
	
	DispBuf[8]='f' ;
	DispBuf[9]='0'	;
	DispBuf[10]='='	;
	DispBuf[16]='\0';
	Display(0x80,DispBuf);
	DispBuf[0]='t';
	DispBuf[1]='=';
	DispBuf[2]='\0';
	Display(0xc0,DispBuf);
}
/*******************************************************************************/
void INT1_ISR(void) interrupt 2			  //切换采样时间的中断函数,用于开关量识别和改变Ts(采样时间)
{	
	EA=0;
	TR0=0;
	ET0=0;
	strcpy(DispBuf,"     ");
	Display(0x80+11,DispBuf);

	while(1)
	{
		
		if(up==0)
		{
			delay(100);
			if(up==0)
			ts++;

		}

		
		if(down==0)
		
		{   delay(100);
			if(down==0)
			ts--;
		}
		
		if(ts>60)
		ts=1;			 
		if(ts<=0)
		ts=60;
		DecToASC(ts,DispBuf,2);
		DispBuf[2]='s';
		DispBuf[3]='\0';
		Display(0x80+3,DispBuf);
		if(Key==0)
		break;

	}
	EA=1;
	TR0=1;
	ET0=1;
	
}
/*******************************************************************************/
void T0_ISR(void) interrupt 1	 //定时中断程序
{	static unsigned char T0_CNT=Ts_CONST;
	//static bit Flag=0;

	TH0=0x3C;
	TL0=0xB0;

	//Flag=!Flag;

	//if(Flag)return;

	T0_CNT--;
	tsflag++;

	if(!T0_CNT)
	{	T0_CNT=Ts_CONST;
		RunState=Start_AD; //AD采样
	}
	if(tsflag>=ts*20)
	{
		tsflag=0;
		RunState =FC;	   //Ts到时进行F0值运算


	}
}
/*******************************************************************************/
void DecToASC(unsigned int Dec,unsigned char *p, unsigned char n)	//将Dec变量编程可以在1602上直接显示的ASICII值
{	unsigned char i;

	p+=n;
	p--;

	for(i=0;i<n;i++)
	{	*p=Dec%10+0x30;
		p--;
		Dec/=10;
	}
}
/*LCD显示*******************************************************************************/
void Check_Busy(void)
{//	return;
	do
	{	P0=0xFF;
		E=0;
		RS=0;
		RW=1;
		E=1;

		_nop_();
	}while(P0&0x80);

	E=0;
}
/*******************************************************************************/
void Write_CMD(unsigned char CMD)
{	
	Check_Busy();
	E=0;
	RS=0;
	RW=0;
	P0=CMD;
	E=1;
	_nop_();
	E=0;
}
/*******************************************************************************/
void Write_Data(unsigned char Data)
{
	Check_Busy();
	E=0;
	RS=1;
	RW=0;
	P0=Data;
	E=1;
	_nop_();
	E=0;
}
/*******************************************************************************/
void LCD_Init(void)
{
	Write_CMD(0x38);
	Write_CMD(0x0C);
	Write_CMD(0x06);
	Write_CMD(0x01);  //清屏
}
/*******************************************************************************/
void Display(unsigned char Addr, unsigned char *pstr)
{  
	Write_CMD(Addr);
	while(*pstr)
		Write_Data(*pstr++);
}

设计文件:
链接:https://pan.baidu.com/s/1tx3oigFJyCcHdiSEHM4KOw?pwd=4blo

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值