⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 红外测温仪.c

📁 红外测温仪
💻 C
字号:
#include<at89x51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define Nack_number 10
//**************端口定义**************************************************
uchar flag;    								//LCD控制线接口
sbit RS=P2^0;   							//RS端
sbit RW=P2^1;  								//读写端
sbit LCDE=P2^2;  							//使能端
											//mlx90614端口定义
sbit SCK=P2^3;								//时钟线
sbit SDA=P2^4;								//数据线
//************数据定义****************************************************
bdata uchar flag1;							//可位寻址数据
sbit bit_out=flag1^7;
sbit bit_in=flag1^0;
uchar tempH,tempL,err;

//**************************  LCD1602  ***********************************
//向LCD写入命令或数据*****************************************************
#define LCD_COMMAND			0      			//命令
#define LCD_DATA			1      			// 数据
#define LCD_CLEAR_SCREEN	0x01      		// 清屏
#define LCD_HOMING  		0x02      		// 光标返回原点
//设置显示模式******* 0x08+   *********************************************
#define LCD_SHOW			0x04    		//显示开
#define LCD_HIDE			0x00    		//显示关
#define LCD_CURSOR			0x02 			//显示光标
#define LCD_NO_CURSOR		0x00    		//无光标
#define LCD_FLASH			0x01    		//光标闪动
#define LCD_NO_FLASH		0x00    		//光标不闪动
//设置输入模式********** 0x04+ ********************************************
#define LCD_AC_UP			0x02     		//光标右移 AC+
#define LCD_AC_DOWN			0x00      		//默认 光标左移 AC-
#define LCD_MOVE			0x01      		//画面可平移
#define LCD_NO_MOVE			0x00      		//默认 画面不移动

//**************************  mlx90614  ***********************************
//command mode  命令模式
#define RamAccess	0x00					//对RAM操作
#define EepomAccess	0x20					//对EEPRAM操作
#define	Mode		0x60					//进入命令模式
#define ExitMode	0x61					//退出命令模式
#define	ReadFlag	0xf0					//读标志
#define EnterSleep	0xff					//进入睡眠模式
//ram address	read only RAM地址(只读)
#define AbmientTempAddr		0x03			//周围温度
#define	IR1Addr				0x04
#define	IR2Addr				0x05
#define LineAbmientTempAddr	0x06  			//环境温度
/*0x0000	0x4074	 16500 	0.01/单元
     -40	   125*/
#define LineObj1TempAddr	0x07			//目标温度,红外温度
/*0x27ad-0x7fff	 0x3559 22610	0.02/单元
  -70.01-382.19  0.01   452.2*/
#define	LineObj2TempAddr	0x08
//eepom address  EEPROM地址
#define TObjMaxAddr		0x00				//测量范围上限设定
#define TObjMinAddr		0x01				//测量范围下限设定
#define PWMCtrlAddr		0x02				//PWM设定
#define TaRangeAddr		0x03				//环境温度设定
#define KeAddr			0x04				//频率修正系数
#define ConfigAddr		0x05				//配置寄存器
#define SMbusAddr		0x0e				//器件地址设定
#define Reserverd1Addr	0x0f				//保留
#define Reserverd2Addr	0x19				//保留
#define ID1Addr			0x1c				//ID地址1
#define ID2Addr			0x1d				//ID地址2
#define ID3Addr			0x1e				//ID地址3
#define ID4Addr			0x1f				//ID地址4

//************函数声明*****************************************************
void start(); 								//MLX90614发起始位子程序
void stop(); 								//MLX90614发结束位子程序
uchar ReadByte(void); 						//MLX90614接收字节子程序
void send_bit(void); 						//MLX90614发送位子程序
void SendByte(uchar number); 				//MLX90614接收字节子程序
void read_bit(void); 						//MLX90614接收位子程序
void delay(uint N); 						//延时程序
uint readtemp(void); 						//读温度数据
void init1602(void); 						//LCD初始化子程序
void busy(void); 							//LCD判断忙子程序
void cmd_wrt(uchar cmd); 					//LCD写命令子程序
void dat_wrt(uchar dat); 					//LCD写数据子程序
void display(uint Tem); 					//显示子程序
void Print(uchar *str); 					//字符串显示程序

//*************主函数*******************************************
void main()
{
	uint Tem;								//温度变量
	SCK=1;
	SDA=1;
	delay(4);
	SCK=0;
	delay(1000);
	SCK=1;
	init1602();								//初始化LCD
	while(1)
	{
		Tem=readtemp();						//读取温度
		cmd_wrt(0x01);						//清屏
		Print("  Temperature:    ");		//显示字符串  Temperature: 且换行
		display(Tem);						//显示温度
		Print(" ^C");						//显示摄氏度
		delay(10000);						//延时再读取温度显示
	}
}
void Print(uchar *str)						//字符串显示程序
{
	while(*str!='\0')						//直到字符串结束
	{
		dat_wrt(*str);						//转成ASCII码  
		str++;								//指向下一个字符
	}
}

//*********输入转换并显示*********
void display(uint Tem)
{
	uint T,a,b;
	T=Tem*2;
	if(T>=27315)							//温度为正
	{
		T=T-27315;							//
		a=T/100;							//温度整数
		b=T-a*100;							//温度小数
		if(a>=100)							//温度超过100度
		{
			dat_wrt(0x30+a/100);			//显示温度百位
			dat_wrt(0x30+a%100/10);			//显示温度十位
			dat_wrt(0x30+a%10);				//显示温度个位
		}
		else if(a>=10)						//温度超过10度
		{
			dat_wrt(0x30+a%100/10);			//显示温度十位
			dat_wrt(0x30+a%10);				//显示温度个位
		}
		else								//温度不超过10度
		{
			dat_wrt(0x30+a);				//显示温度个位
		}
		dat_wrt(0x2e);						//显示小数点
		if(b>=10)							//温度小数点后第1位数不等于0
		{
		dat_wrt(0x30+b/10);					//显示温度小数点后第1位数
		dat_wrt(0x30+b%10);					//显示温度小数点后第2位数
		}
		else								//温度小数点后第1位数等于0
		{
			dat_wrt(0x30);					//显示温度小数点后第1位数0
			dat_wrt(0x30+b);				//显示温度小数点后第2位数
		}
	}
	else									//温度为负
	{
		T=27315-T;
		a=T/100;
		b=T-a*100;
		dat_wrt(0x2d);						//显示负号
		if(a>=10)							//温度低于负10度
		{
			dat_wrt(0x30+a/10);				//显示温度十位
			dat_wrt(0x30+a%10);				//显示温度个位
		}
		else								//温度高于负10度
		{
			dat_wrt(0x30+a);				//显示温度个位
		}
		dat_wrt(0x2e);						//显示小数点
		if(b>=10)							//温度小数点后第1位数不等于0
		{
			dat_wrt(0x30+b/10);				//显示温度小数点后第1位数
			dat_wrt(0x30+b%10);				//显示温度小数点后第2位数
		}
		else								//温度小数点后第1位数等于0
		{
			dat_wrt(0x30);					//显示温度小数点后第1位数0
			dat_wrt(0x30+b);				//显示温度小数点后第2位数
		}
	}
}
//************************************
void start(void)							//停止条件是 SCK=1时,SDA由1到0
{
	SDA=1;
	delay(4);
	SCK=1;
	delay(4);
	SDA=0;
	delay(4);
	SCK=0;
	delay(4);
}
//------------------------------
void stop(void)								//停止条件是 SCK=1时,SDA由0到1
{
	SCK=0;
	delay(4);
	SDA=0;
	delay(4);
	SCK=1;
	delay(4);
	SDA=1;
}
//---------发送一个字节---------
void SendByte(uchar number)
{
	uchar i,n,dat;
	n=Nack_number;							//可以重发次数
Send_again:
	dat=number;
	for(i=0;i<8;i++) 						//8位依次发送
	{
		if(dat&0x80)   						//取最高位
		{
			bit_out=1;    					//发1
		}
		else
		{
			bit_out=0;    					//发0
		}		
		send_bit();    						//发送一个位
		dat=dat<<1;    						//左移一位
	}	
	read_bit();   							//接收1位 应答信号
	if(bit_in==1)     						//无应答时重发
	{
		stop();
		if(n!=0)
		{
			n--;    						//可以重发Nack_number=10次
			goto Repeat;					//重发
		}
		else
		{
			goto exit;						//退出
		}		
	}
	else
	{
		goto exit;
	}		
Repeat:
	start();								//重新开始
	goto Send_again;						//重发
	exit: ;									//退出
}
//-----------发送一个位---------
void send_bit(void)
{
	if(bit_out==1)
	{
		SDA=1;   							//发1
	}	
	else
	{
		SDA=0;   							//发0
	}
	_nop_();
	SCK=1;   								//上升沿
	delay(4);delay(4);
	SCK=0;
	delay(4);delay(4);
}
//----------接收一个字节--------
uchar ReadByte(void)
{
	uchar i,dat;
	dat=0;									//初值为0
	for(i=0;i<8;i++)
	{
		dat=dat<<1;							//左移
		read_bit();							//接收一位
		if(bit_in==1)
		{
			dat=dat+1;						//为1时对应位加1
		}		
	}
	SDA=0;									//发送应答信号0
	send_bit();
	return dat;								//带回接收数据
}
//----------接收一个位----------
void read_bit(void)
{
	SDA=1;									//数据端先置1
	bit_in=1;
	SCK=1;									//上升沿
	delay(4);delay(4);
	bit_in=SDA;								//读数据
	_nop_();
	SCK=0;
	delay(4);delay(4);
}


//------------------------------
uint readtemp(void)
{
	SCK=0;
	start(); 								//开始条件
	SendByte(0x00); 						//发送从地址00
	SendByte(0x07); 						//发送命令
	start(); 								//开始条件
	SendByte(0x01); 						//读从地址00
	bit_out=0;
	tempL=ReadByte();						//读数据低字节
	bit_out=0;
	tempH=ReadByte();						//读数据高字节
	bit_out=1;
	err=ReadByte();							//读错误信息码
	stop();									//停止条件
	return(tempH*256+tempL);
}
//******************LCD显示子函数***********************
void init1602(void) 						//初始化LCD
{
	cmd_wrt(0x01);							//清屏
	cmd_wrt(0x0c);							//开显示,不显示光标,不闪烁
	cmd_wrt(0x06);							//完成一个字符码传送后,光标左移,显示不发生移位
	cmd_wrt(0x38);							//16×2显示,5×7点阵,8位数据接口
}
void busy(void) 							//LCD忙标志判断
{
	flag=0x80;								//赋初值 高位为1 禁止
	while(flag&0x80)						//读写操作使能位禁止时等待 继续检测
	{
		P0=0xff;
		RS=0; 								//指向地址计数器
		RW=1; 								//读
		LCDE=1; 							//信号下降沿有效
		flag=P0;							//读状态位 高位为状态
		LCDE=0;
	}
}
void cmd_wrt(uchar cmd) 					//写命令子函数
{
	LCDE=0;
	busy();									//检测 读写操作使能吗
	P0=cmd; 								//命令
	RS=0; 									//指向命令计数器
	RW=0; 									//写
	LCDE=1;									//高电平有效
	LCDE=0;
}
void dat_wrt(uchar dat) 					//写数据子函数
{
	busy();									//检测 读写操作使能吗
	LCDE=0;
	if(flag==16)
	{		
		RS=0;								//指向指令寄存器		
		RW=0; 								//写
		P0=0XC0;							//指向第二行
		LCDE=1;								//高电平有效
		LCDE=0;
	}	
	RS=1;									//指向数据寄存器
	RW=0; 									//写
	P0=dat; 								//写数据
	LCDE=1;									//高电平有效
	LCDE=0;
}
//------------延时--------------
void delay(uint n)
{
	uint j;
	for(j=0;j<n;j++)
	{
		_nop_();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -