基于51单片机的MLX90614红外测温源程序

更新时间:2023-04-20 03:31:46 阅读: 评论:0


2023年4月20日发(作者:ex泰勒展开)基于51单片机的MLX90614红外测温源程序如下:

//-------------------------------------------------------------------------

//说明:显示分为2 部分:数码管显示,液晶屏显示

//按1 键数码管显示,此时液晶屏保持静止

//复位时或按除1 键外其他键时,液晶屏显示,数码管熄灭

//-------------------中学生心理健康教育 ------------------------------------------------------

#include

#include

#define uint unsigned int

#define uchar unsigned char

#define Nack_number 10

//**************端口定义**************************************************

uchar flag; //LCD 控制线接口

sbit RS=P0^6; //RS 端

sbit RW=P0^7; //读写成人段子 端

sbit LCDE=P3^5; //使能端

//mlx90614 端口定义

----------------------- Page 3-----------------------

sbit SCK=P3^7; //时钟线

sbit SDA=P3^6; //数据线

sbit DPY1 = P3^2; //温度显示第1 个数码管段选

sbit DPY2 = P3^3; //温度显示第2 个数码管段选

sbit DPY3 = P3^4; //温度显示第3 个数码管段选

sbit row1 = P0^3; //矩阵键盘第1 列

sbit row2 = P0^4; //矩阵键盘第2 列

sbit row3 = P0^5; //矩阵键盘第3 列

sbit cow1 = P0^0; //矩阵键盘第1 行

sbit cow2 = P0^1; //矩阵键盘第2 行

sbit cow3 = P0^2; //矩阵键盘第3 行

//************数据定义****************************************************

bdata uchar flag1; //可位寻址数据

sbit bit_out=flag1^7;

sbit bit_in=flag1^0;

uchar tempH,tempL,err;

void CALTEMP(uint TEMP);

void ReadKey(void);

void initInt();

void delay1(uint z);

void show();

----------------------- Page 4-----------------------

uchar key_num;

uchar mah[5];

/********数码管码值定义*******************************************************/

uchar code LED01[]={ //LED 显示代码,0-9 共阳 不带小数点的

0xC0,0xF9,0xA4,0xB0,

0x99,0x92,0x82,0xF8,

0x80,0x90};

uchar code LED02[]={ //LED 显示代码,0-9 共阳 带小数点的

0x40,0x79,0x24,0x30,

0x19,0x12,0x02,0x78,

0x00,0x10};

/**********全局变量定义******************************************************/

bit b20ms,b100ms; //定时标志位

uchar c20ms,c100ms; //定时毫秒数

//************************** 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 Rerverd1Addr 0x0f //保留

#define Rerverd2Addr 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 nd_bit(void); //MLX90614 发送位子程序

----------------------- Page 7-----------------------

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; //温度变量

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); //延时再读取温度显示

}

}

}

//------------------字符串显示程序--------------------------

void Print(uchar *str) //字符串显示程序

{

while(*str!='0') //直到字符串结束

{



dat_wrt(*str); //转成ASCII 码

str++; //指向下一个字符

}

}

//--------------输入转换并显示(用于LCD1602)--------------------

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); //显示温度个位

}

el if(a>=10) //温度超过10 度

{

dat_wrt(0x30+a%100/10); //显示温度十位

dat_wrt(0x30+a%10); //显示温度个位

}

el //温度不超过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 位数

}

el水对人体的重要性 //温度小数点后第1 位数等于0

{

dat_wrt(0x30); //显示温度小数点后第1 位数0

dat_wrt(0x30+b); //显示温度小数点后第2 位数

}

}

el //温度为负

{

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); //显示温度个位

}

el //温度高于负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 位数

}

el //温度小数点后第1 位数等于0

{

dat_wrt(0x30); //显示温度小数点后第1 位数0

dat_wrt(0x30+b); //显示温度小数点后第2 位数

}

}

}

//--------------------根据十六进制计算温度------------------------------

void CALTEMP(uint TEMP)

{

uint T;

uint a,b;

uchar A4,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;

}

el if(a>=10)

{

A4=0;

A5=a/10;

a=a%10;

A6=a;

}

el

{

A4=0;

A5=0;

A6=a;

}

if(b>=10)

{

A7=b/10;

b=b%10;

A8=b;

}

el

{

A7=0;

A8=b;

}

}

el

{

T=27315-T;

a=T/100;

b=T-a*100;

A4=9;

if(a>=10)

{



A5=a/10;

a=a%10;

A6=a;

}

el

{

A5=0;

A6=a;

}

if(b>=10)

{

A7=b/10;

b=b%10;

A8=b;

}

el

{

A7=0;

A8=b;

}

}

mah[4]=A4;

mah[3]=A5;

mah[2]=A6;

mah[1]=A7;

mah[0]=A8;

}

//------------------------------

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; francs //可以重发次数

Send_again:

dat=number;

for(i=0;i<8;i++) //8 位依次发送

{

if(dat&0x80) //取最高位

{

bit_out=1; //发1

}

el

{

bit_out=0; //发0

}

nd_bit(); //发送一个位

dat=dat<<1; //左移一位

}

read_bit(); //接收1 位应答信号

if(bit_in==1) //无应答时重发

{

stop();

if(n!=0)

{

n--; //可以重发Nack_number=10 次

goto Repeat; //重发

}

el

{

goto exit; //退出

}

}

el

{

goto exit;

}

Repeat:



start(); //重新开始

goto Send_again; //重发

exit: ; //退出

}

//-----------发送一个位---------

void nd_bit(void)

{

if(bit_out==1)

{

SDA=1; //发1

}

el

{

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

nd_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 显示,57 点阵,8 位数据接口

}

void busy(void) //LC正能量演讲稿 D 忙标志判断

{

flag=0x80; //赋初值 高位为1 禁止

while(flag&0x80) //读写操作使能位禁止时等待 继续检测

{

P1=0xff;

RS=0; //指向地址计数器

RW=1; //读

LCDE=1; 打字技巧 //信号下降沿有效

flag=P1; //读状态位 高位为状态

LCDE=0;

}

}

void cmd_wrt(uchar cmd) //写命令子函数

{

LCDE=0;

busy(); //检测读写操作使能吗

P1=cmd; //命令

RS=0; //指向命令计数器

RW=0; //写

LCDE=1; //高电平有效

LCDE=0;

}

void dat_wrt(uchar dat) //写数据子函数

{

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;

}

//------------延时--------------

void delay(uint n)

{

uint j;

for(j=0;j
{

_nop_();

}

}

//------------定时器初始化函数----------------

void initInt()

{

TMOD = 0x10; //定时器1 方式1

TH1=(65536-1000)/256; //定时器1 设置1ms 定时

TL1=(65536-1000)%256;

EA=1; //开总中断

ET1 = 1;

//开定时器T1 中断

TR1 = 1; //启动定时器T1

}

//------------定时器中断处理函数-------------------

void timer1handle() interrupt 3 //定时器3 1ms 中断

{

TH1=(65536-1000)/256;

TL1=(65536-1000)%256;

c20ms++;

c100ms++;

if(c20ms >= 20) //20ms 计时器

{

c20ms = 0;

b20ms = 1;

}

if(c100ms >= 5我想对您说作文 0) //100ms 计时器

{

c100ms = 0;

b100ms = 1;

}

}

//--------------------------温度显示函数------------------------

void show()

{

DPY1=0;

P2=LED01[mah[3]]; //转换8 位数显示,不带小数点的

delay1(2);

P2=0xFF;

DPY1=1;

DPY2=0;

P2=LED02[mah[2]]; //转换8 位数显示,带小数点的

delay1(2);

P2=0xFF;

DPY2=1;

DPY3=0;

P2=LED01[mah[1]]; //转换8 位数显示,不带小数点的

delay1(2);

P2=0xFF;

DPY3=1;

}

void ReadKey(void)

{

row1=0; //矩阵键盘第1列,将第一列拉低,扫描是否有按键按下,第一列按键包括:1,4,7

row2=1;

row3=1;

cow1=1;

cow2=1;

cow3=1;

_nop_();

if(!(cow1&cow2&cow3)) //如果有按键按下,就返回,且判断是哪个按键值,否则继续扫描下一列

{

if(cow1==0)

key_num=1;

if(cow2==0)

key_num=4;

if(cow3==0)

key_num=7;

return;

}

row1=1; //矩阵键盘第1列,将第一列拉低,扫描是否有按键按下,第一列按键包括:2,5,8

row2=0;

row3=1;

cow1=1;

cow2=1;

cow3=1;

_nop_();

if(!(cow1&cow2&cow3))

{

if(cow1==0)

key_num=2;

if(cow2==0)

key_num=5;

if(cow3==0)

key_num=8;

return;

}

row1=1; //矩阵键盘第1列,将第一列拉低,扫描是否有按键按下,第一列按键包括:3,6

row2=1;

row3=0;

cow1=1;

cow2=1;

_nop_();

if(!(cow1&cow2))

{

if(cow1==0)

key_num=3;

if(cow2==0)

key_num=6;

return;

}

}

//--------------------------数码管显示延时函数------------------------

void delay1(uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}


本文发布于:2023-04-20 03:31:46,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/838727.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:mlx90614
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图