(分享文件)
想在51hei論壇上找,但一直都沒有找到,在其他網站上找來了,順便分享過來吧,之后想用msp430把這個紅外測溫儀做出來,盡可能的加上藍牙傳輸。歡迎大家交流探討。
一.實驗目的
1.通過本實驗掌握 MLX90614 的原理。
2.通過實驗掌握數碼管基本原理
3. 通過實驗掌握矩陣鍵盤的使用
4.通過實驗掌握1602 的使用
二.實驗內容
通過 MLX90614 非接觸式測得物體溫度
0.jpg (19.85 KB, 下載次數: 150)
下載附件
2018-2-8 00:43 上傳
2.運行 Keil uVision軟件,新建一個工程,新建一個工程文件。將文件添加到工程中并編譯,如有錯,請更改直到編譯成功,如有錯,請更改直到編譯成功
4.用編程器將生成的 HEX 文件燒寫到單片機中,或用 STC 單片機專用的串口燒寫軟件,通過MAX232 串口燒寫到單片機中(只能用于 STC單片機)。或用仿真器來執行程序,將程序下載到仿真器中,具體方法請參考仿真器的使用一節。用編程器將生成的 HEX 文件燒寫到單片機中。
5. 程序下完后可以看到液晶屏有溫度顯示,用手掌覆蓋紅外傳感器上方2cm 處,看到此時液晶屏溫度即為手掌的表面溫度。
6.按下1鍵可以看到數碼管顯示,用手掌覆蓋紅外傳感器上方 2cm 處,看到此時數碼管溫度即為手掌的表面溫度。此時液晶屏溫度保持不變。
7.按下除1鍵其他鍵,此時液晶屏又重新顯示溫度。
單片機源程序如下:
- //-------------------------------------------------------------------------
- //說明:顯示分為2 部分:數碼管顯示,液晶屏顯示
- //按1 鍵數碼管顯示,此時液晶屏保持靜止
- //復位時或按除1 鍵外其他鍵時,液晶屏顯示,數碼管熄滅
- //-------------------------------------------------------------------------
- #include<reg52.h>
- #include<intrins.h>
- #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 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 發送位子程序
- ----------------------- 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); //顯示溫度個位
- }
- 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 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;
- }
- else if(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;
- }
- //------------------------------
- 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) //讀寫操作使能位禁止時等待 繼續檢測
- {
- 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<n;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 >= 50) //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;
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
MLX90614紅外測溫儀實驗指導書含源碼.pdf
(155.79 KB, 下載次數: 691)
2018-2-7 22:22 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
MLX90614的中英文資料下載:
http://www.zg4o1577.cn/bbs/dpj-107480-1.html
|