MLX90614红外测温代码.docx
《MLX90614红外测温代码.docx》由会员分享,可在线阅读,更多相关《MLX90614红外测温代码.docx(25页珍藏版)》请在冰豆网上搜索。
MLX90614红外测温代码
1.通过本实验掌握MLX90614的原理。
2.通过实验掌握数码管基本原理
3.通过实验掌握矩阵键盘的使用
4.通过实验掌握1602的使用
二.实验内容
通过MLX90614非接触式测得物体温度
三.实验器材
1.主控屏+5V电源
2.DCP-PRJ09红外测温仪
四.实验原理图
五.实验步骤
1.接上电源
2.运行KeiluVision软件,新建一个工程,新建一个工程文件。
将文件添加到工程中并编译,如有错,请更改直到编译成功,如有错,请更改直到编译成功
4.用编程器将生成的HEX文件烧写到单片机中,或用STC单片机专用的串口烧写软件,通过MAX232串口烧写到单片机中(只能用于STC单片机)。
或用仿真器来执行程序,将程序下载到仿真器中,具体方法请参考仿真器的使用一节。
用编程器将生成的HEX文件烧写到单片机中。
5.程序下完后可以看到液晶屏有温度显示,用手掌覆盖红外传感器上方2cm处,看到此时液晶屏温度即为手掌的表面温度。
6.按下1键可以看到数码管显示,用手掌覆盖红外传感器上方2cm处,看到此时数码管温度即为手掌的表面温度。
此时液晶屏温度保持不变。
7.按下除1键其他键,此时液晶屏又重新显示温度。
实验代码如下:
//----------------------------//说明:
显示分为2部分:
数码管显示,液晶屏显示
//按1键数码管显示,此时液晶屏保持静止
//复位时或按除1键外其他键时,液晶屏显示,数码管熄灭
//-------------------------------------------------------------------------
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#defineNack_number10
//**************端口定义**************************************************
ucharflag;//LCD控制线接口
sbitRS=P0^6;//RS端
sbitRW=P0^7;//读写端
sbitLCDE=P3^5;//使能端
//mlx90614端口定义
sbitSCK=P3^7;//时钟线
sbitSDA=P3^6;//数据线
sbitDPY1=P3^2;//温度显示第1个数码管段选
sbitDPY2=P3^3;//温度显示第2个数码管段选
sbitDPY3=P3^4;//温度显示第3个数码管段选
sbitrow1=P0^3;//矩阵键盘第1列
sbitrow2=P0^4;//矩阵键盘第2列
sbitrow3=P0^5;//矩阵键盘第3列
sbitcow1=P0^0;//矩阵键盘第1行
sbitcow2=P0^1;//矩阵键盘第2行
sbitcow3=P0^2;//矩阵键盘第3行
//************数据定义****************************************************
bdataucharflag1;//可位寻址数据
sbitbit_out=flag1^7;s
bitbit_in=flag1^0;
uchartempH,tempL,err;
voidCALTEMP(uintTEMP);
voidReadKey(void);
voidinitInt();
voiddelay1(uintz);
voidshow();
ucharkey_num;
ucharmah[5];
/********数码管码值定义*******************************************************/
ucharcodeLED01[]={//LED显示代码,0-9共阳不带小数点的
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
ucharcodeLED02[]={//LED显示代码,0-9共阳带小数点的
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
/**********全局变量定义******************************************************/
bitb20ms,b100ms;//定时标志位
ucharc20ms,c100ms;//定时毫秒数
//**************************LCD1602***********************************
//向LCD写入命令或数据*****************************************************
#defineLCD_COMMAND0//命令
#defineLCD_DATA1//数据
#defineLCD_CLEAR_SCREEN0x01//清屏
#defineLCD_HOMING0x02//光标返回原点
//设置显示模式*******0x08+*********************************************
#defineLCD_SHOW0x04//显示开一.实验目的
#defineLCD_HIDE0x00//显示关
#defineLCD_CURSOR0x02//显示光标
#defineLCD_NO_CURSOR0x00//无光标
#defineLCD_FLASH0x01//光标闪动
#defineLCD_NO_FLASH0x00//光标不闪动
//设置输入模式**********0x04+********************************************
#defineLCD_AC_UP0x02//光标右移AC+
#defineLCD_AC_DOWN0x00//默认光标左移AC-
#defineLCD_MOVE0x01//画面可平移
#defineLCD_NO_MOVE0x00//默认画面不移动
//**************************mlx90614***********************************
//commandmode命令模式
#defineRamAccess0x00//对RAM操作
#defineEepomAccess0x20//对EEPRAM操作
#defineMode0x60//进入命令模式
#defineExitMode0x61//退出命令模式
#defineReadFlag0xf0//读标志
#defineEnterSleep0xff//进入睡眠模式
//ramaddressreadonlyRAM地址(只读)
#defineAbmientTempAddr0x03//周围温度
#defineIR1Addr0x04
#defineIR2Addr0x05
#defineLineAbmientTempAddr0x06//环境温度
/*0x00000x4074165000.01/单元
-40125*/
#defineLineObj1TempAddr0x07//目标温度,红外温度
/*0x27ad-0x7fff0x3559226100.02/单元
-70.01-382.190.01452.2*/
#defineLineObj2TempAddr0x08
//eepomaddressEEPROM地址
#defineTObjMaxAddr0x00//测量范围上限设定
#defineTObjMinAddr0x01//测量范围下限设定
#definePWMCtrlAddr0x02//PWM设定
#defineTaRangeAddr0x03//环境温度设定
#defineKeAddr0x04//频率修正系数
#defineConfigAddr0x05//配置寄存器
#defineSMbusAddr0x0e//器件地址设定
#defineReserverd1Addr0x0f//保留
#defineReserverd2Addr0x19//保留
#defineID1Addr0x1c//ID地址1
#defineID2Addr0x1d//ID地址2
#defineID3Addr0x1e//ID地址3
#defineID4Addr0x1f//ID地址4
//************函数声明*****************************************************
voidstart();//MLX90614发起始位子程序
voidstop();//MLX90614发结束位子程序
ucharReadByte(void);//MLX90614接收字节子程序
voidsend_bit(void);//MLX90614发送位子程序
voidSendByte(ucharnumber);//MLX90614接收字节子程序
voidread_bit(void);//MLX90614接收位子程序
voiddelay(uintN);//延时程序
uintreadtemp(void);//读温度数据
voidinit1602(void);//LCD初始化子程序
voidbusy(void);//LCD判断忙子程序
voidcmd_wrt(ucharcmd);//LCD写命令子程序
voiddat_wrt(uchardat);//LCD写数据子程序
voiddisplay(uintTem);//显示子程序
voidPrint(uchar*str);//字符串显示程序
//*************主函数*******************************************
voidmain()
{
uintTem;//温度变量
initInt();
SCK=1;
SDA=1;
delay(4);
SCK=0;
delay(1000);
SCK=1;
init1602();//初始化LCD
while
(1)
{
while(b100ms)//每100ms扫描一次键盘
{
b100ms=0;
ReadKey();
}
if(key_num==1)//按下1键时,进行数码管显示
{
Tem=readtemp();
CALTEMP(Tem);
show();
}
if(key_num!
=1)//液晶屏显示
{
Tem=readtemp();//读取温度
cmd_wrt(0x01);//清屏
Print("Temperature:
");//显示字符串Temperature:
且换行
display(Tem);//显示温度
Print("^C");//显示摄氏度
delay(100000);//延时再读取温度显示
}
}
}
voidPrint(uchar*str)//字符串显示程序
{
while(*str!
='\0')//直到字符串结束
{
dat_wrt(*str);//转成ASCII码
str++;//指向下一个字符
}
}
//--------------输入转换并显示(用于LCD1602)--------------------
voiddisplay(uintTem)
{
uintT,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);//显示温度个位
}elseif(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位数
}
}
}
//--------------------根据十六进制计算温度--------------------------------------------------------
voidCALTEMP(uintTEMP)
{
uintT;
uinta,b;
ucharA4,A5,A6,A7,A8;
T=TEMP*2;
if(T>=27315)
{
T=T-27315;
a=T/100;
b=T-a*100;
if(a>=100)
{
A4=a/100;
a=a%100;
A5=a/10;
a=a%10;
A6=a;
}
elseif(a>=10)
{
A4=0;
A5=a/10;
a=a%10;
A6=a;
}
else
{
A4=0;
A5=0;
A6=a;
}
if(b>=10)
{
A7=b/10;
b=b%10;
A8=b;
}
else
{
A7=0;
A8=b;
}
}
else
{
T=27315-T;
a=T/100;
b=T-a*100;
A4=9;
if(a>=10)
{
A5=a/10;
a=a%10;
A6=a;
}
else
{
A5=0;
A6=a;
}
if(b>=10)
{
A7=b/10;
b=b%10;
A8=b;
}
else
{
A7=0;
A8=b;
}
}
mah[4]=A4;
mah[3]=A5;
mah[2]=A6;
mah[1]=A7;
mah[0]=A8;}
//------------------------------
voidstart(void)//停止条件是SCK=1时,SDA由1到0
{
SDA=1;
delay(4);
SCK=1;
delay(4);
SDA=0;
delay(4);
SCK=0;
delay(4);
}
//------------------------------
voidstop(void)//停止条件是SCK=1时,SDA由0到1
{
SCK=0;
delay(4);
SDA=0;
delay(4);
SCK=1;
delay(4);
SDA=1;
}
//---------发送一个字节---------
voidSendByte(ucharnumber)
{
uchari,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次
gotoRepeat;//重发
}
else
{
gotoexit;//退出
}
}
else
{
gotoexit;
}
Repeat:
start();//重新开始
gotoSend_again;//重发
exit:
;//退出
}
//-----------发送一个位---------
voidsend_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);
}
//----------接收一个字节--------
ucharReadByte(void)
{
uchari,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();
returndat;//带回接收数据
}
//----------接收一个位----------
voidread_bit(void)
{
SDA=1;//数据端先置1
bit_in=1;
SCK=1;//上升沿
delay(4);delay(4);
bit_in=SDA;//读数据
_nop_();
SCK=0;
delay(4);delay(4);
}
//------------------------------
uintreadtemp(void)
{
SCK=0;
start();//开始条件
SendByte(0x00);//发送从地址00RS=0;//指向指令寄存器
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显示子函数***********************
voidinit1602(void)//初始化LCD
{
cmd_wrt(0x01);//清屏
cmd_wrt(0x0c);//开显示,不显示光标,不闪烁
cmd_wrt(0x06);//完成一个字符码传送后,光标左移,显示不发生移位
cmd_wrt(0x38);//16×2显示,5×7点阵,8位数据接口
}
voidbusy(void)//LCD忙标志判断
{
flag=0x80;//赋初值高位为1禁止
while(flag&0x80)//读写操作使能位禁止时等待继续检测
{
P1=0xff;
RS=0;//指向地址计数器
RW=1;//读
LCDE=1;//信号下降沿有效
flag=P1;//读状态位高位为状态
LCDE=0;
}
}
voidcmd_wrt(ucharcmd)//写命令子函数
{
LCDE=0;
busy();//检测读写操作使能吗
P1=cmd;//命令
RS=0;//指向命令计数器
RW=0;//写
LCDE=1;//高电平有效
LCDE=0;
}
voiddat_wrt(uchardat)//写数据子函数
{
busy();//检测读写操作使能吗
LCDE=0;
if(flag==16)
{
RS=0;//指向指令寄存器
RW=0;//写
P1=0XC0;//指向第二行
LCDE=1;//高电平有效
LCDE=0;
}
RS=1;//指向数据寄存器
RW=0;//写
P1=dat;//写数据
LCDE=1;//高电平有效
LCDE=0;
}
//------------延时--------------
voiddelay(uintn)
{
uintj;
for(j=0;j{
_nop_();
}
}
//------------定时器初始化函数----------------
voidinitInt()
{
TMOD=0x10;//定时器1方式1
TH1=(65536-1000)/256;//定时器1设置1ms定时
TL1=(65536-1000