|
(分享文件)
想在51hei論壇上找,但一直都沒(méi)有找到,在其他網(wǎng)站上找來(lái)了,順便分享過(guò)來(lái)吧,之后想用msp430把這個(gè)紅外測(cè)溫儀做出來(lái),盡可能的加上藍(lán)牙傳輸。歡迎大家交流探討。
一.實(shí)驗(yàn)?zāi)康?
1.通過(guò)本實(shí)驗(yàn)掌握 MLX90614 的原理。
2.通過(guò)實(shí)驗(yàn)掌握數(shù)碼管基本原理
3. 通過(guò)實(shí)驗(yàn)掌握矩陣鍵盤的使用
4.通過(guò)實(shí)驗(yàn)掌握1602 的使用
二.實(shí)驗(yàn)內(nèi)容
通過(guò) MLX90614 非接觸式測(cè)得物體溫度
2.運(yùn)行 Keil uVision軟件,新建一個(gè)工程,新建一個(gè)工程文件。將文件添加到工程中并編譯,如有錯(cuò),請(qǐng)更改直到編譯成功,如有錯(cuò),請(qǐng)更改直到編譯成功
4.用編程器將生成的 HEX 文件燒寫(xiě)到單片機(jī)中,或用 STC 單片機(jī)專用的串口燒寫(xiě)軟件,通過(guò)MAX232 串口燒寫(xiě)到單片機(jī)中(只能用于 STC單片機(jī));蛴梅抡嫫鱽(lái)執(zhí)行程序,將程序下載到仿真器中,具體方法請(qǐng)參考仿真器的使用一節(jié)。用編程器將生成的 HEX 文件燒寫(xiě)到單片機(jī)中。
5. 程序下完后可以看到液晶屏有溫度顯示,用手掌覆蓋紅外傳感器上方2cm 處,看到此時(shí)液晶屏溫度即為手掌的表面溫度。
6.按下1鍵可以看到數(shù)碼管顯示,用手掌覆蓋紅外傳感器上方 2cm 處,看到此時(shí)數(shù)碼管溫度即為手掌的表面溫度。此時(shí)液晶屏溫度保持不變。
7.按下除1鍵其他鍵,此時(shí)液晶屏又重新顯示溫度。
單片機(jī)源程序如下:
- //-------------------------------------------------------------------------
- //說(shuō)明:顯示分為2 部分:數(shù)碼管顯示,液晶屏顯示
- //按1 鍵數(shù)碼管顯示,此時(shí)液晶屏保持靜止
- //復(fù)位時(shí)或按除1 鍵外其他鍵時(shí),液晶屏顯示,數(shù)碼管熄滅
- //-------------------------------------------------------------------------
- #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; //讀寫(xiě)端
- sbit LCDE=P3^5; //使能端
- //mlx90614 端口定義
- ----------------------- Page 3-----------------------
- sbit SCK=P3^7; //時(shí)鐘線
- sbit SDA=P3^6; //數(shù)據(jù)線
- sbit DPY1 = P3^2; //溫度顯示第1 個(gè)數(shù)碼管段選
- sbit DPY2 = P3^3; //溫度顯示第2 個(gè)數(shù)碼管段選
- sbit DPY3 = P3^4; //溫度顯示第3 個(gè)數(shù)碼管段選
- 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 行
- //************數(shù)據(jù)定義****************************************************
- bdata uchar flag1; //可位尋址數(shù)據(jù)
- 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];
- /********數(shù)碼管碼值定義*******************************************************/
- uchar code LED01[]={ //LED 顯示代碼,0-9 共陽(yáng) 不帶小數(shù)點(diǎn)的
- 0xC0,0xF9,0xA4,0xB0,
- 0x99,0x92,0x82,0xF8,
- 0x80,0x90};
- uchar code LED02[]={ //LED 顯示代碼,0-9 共陽(yáng) 帶小數(shù)點(diǎn)的
- 0x40,0x79,0x24,0x30,
- 0x19,0x12,0x02,0x78,
- 0x00,0x10};
- /**********全局變量定義******************************************************/
- bit b20ms,b100ms; //定時(shí)標(biāo)志位
- uchar c20ms,c100ms; //定時(shí)毫秒數(shù)
- //************************** LCD1602 ***********************************
- //向LCD 寫(xiě)入命令或數(shù)據(jù)*****************************************************
- #define LCD_COMMAND 0 //命令
- #define LCD_DATA 1 // 數(shù)據(jù)
- #define LCD_CLEAR_SCREEN 0x01 // 清屏
- #define LCD_HOMING 0x02 // 光標(biāo)返回原點(diǎn)
- //設(shè)置顯示模式******* 0x08+ *********************************************
- #define LCD_SHOW 0x04 //顯示開(kāi)
- #define LCD_HIDE 0x00 //顯示關(guān)
- #define LCD_CURSOR 0x02 //顯示光標(biāo)
- #define LCD_NO_CURSOR 0x00 //無(wú)光標(biāo)
- #define LCD_FLASH 0x01 //光標(biāo)閃動(dòng)
- #define LCD_NO_FLASH 0x00 //光標(biāo)不閃動(dòng)
- //設(shè)置輸入模式********** 0x04+ ********************************************
- #define LCD_AC_UP 0x02 //光標(biāo)右移 AC+
- #define LCD_AC_DOWN 0x00 //默認(rèn)光標(biāo)左移 AC-
- #define LCD_MOVE 0x01 //畫(huà)面可平移
- #define LCD_NO_MOVE 0x00 //默認(rèn) 畫(huà)面不移動(dòng)
- //************************** mlx90614 ***********************************
- //command mode 命令模式
- #define RamAccess 0x00 //對(duì)RAM 操作
- #define EepomAccess 0x20 //對(duì)EEPRAM 操作
- #define Mode 0x60 //進(jìn)入命令模式
- #define ExitMode 0x61 //退出命令模式
- #define ReadFlag 0xf0 //讀標(biāo)志
- #define EnterSleep 0xff //進(jìn)入睡眠模式
- //ram address read only RAM 地址(只讀)
- #define AbmientTempAddr 0x03 //周圍溫度
- #define IR1Addr 0x04
- #define IR2Addr 0x05
- #define LineAbmientTempAddr 0x06 //環(huán)境溫度
- /*0x0000 0x4074 16500 0.01/單元
- -40 125*/
- #define LineObj1TempAddr 0x07 // 目標(biāo)溫度,紅外溫度
- /*0x27ad-0x7fff 0x3559 22610 0.02/單元
- -70.01-382.19 0.01 452.2*/
- #define LineObj2TempAddr 0x08
- //eepom address EEPROM 地址
- #define TObjMaxAddr 0x00 //測(cè)量范圍上限設(shè)定
- #define TObjMinAddr 0x01 //測(cè)量范圍下限設(shè)定
- #define PWMCtrlAddr 0x02 //PWM 設(shè)定
- #define TaRangeAddr 0x03 //環(huán)境溫度設(shè)定
- #define KeAddr 0x04 //頻率修正系數(shù)
- #define ConfigAddr 0x05 //配置寄存器
- #define SMbusAddr 0x0e //器件地址設(shè)定
- #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
- //************函數(shù)聲明*****************************************************
- void start(); //MLX90614 發(fā)起始位子程序
- void stop(); //MLX90614 發(fā)結(jié)束位子程序
- uchar ReadByte(void); //MLX90614 接收字節(jié)子程序
- void send_bit(void); //MLX90614 發(fā)送位子程序
- ----------------------- Page 7-----------------------
- void SendByte(uchar number); //MLX90614 接收字節(jié)子程序
- void read_bit(void); //MLX90614 接收位子程序
- void delay(uint N); //延時(shí)程序
- uint readtemp(void); //讀溫度數(shù)據(jù)
- void init1602(void); //LCD 初始化子程序
- void busy(void); //LCD 判斷忙子程序
- void cmd_wrt(uchar cmd); //LCD 寫(xiě)命令子程序
- void dat_wrt(uchar dat); //LCD 寫(xiě)數(shù)據(jù)子程序
- void display(uint Tem); //顯示子程序
- void Print(uchar *str); //字符串顯示程序
- //*************主函數(shù)*******************************************
- 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 鍵時(shí),進(jìn)行數(shù)碼管顯示
- {
- Tem=readtemp();
- CALTEMP(Tem);
- show();
- }
- if(key_num!=1) //液晶屏顯示
- {
- Tem=readtemp(); //讀取溫度
- cmd_wrt(0x01); //清屏
- Print(" Temperature: "); //顯示字符串 Temperature: 且換行
- display(Tem); //顯示溫度
- Print(" ^C"); //顯示攝氏度
- delay(100000); //延時(shí)再讀取溫度顯示
- }
- }
- }
- //------------------字符串顯示程序--------------------------
- void Print(uchar *str) //字符串顯示程序
- {
- while(*str!='\0') //直到字符串結(jié)束
- {
- dat_wrt(*str); //轉(zhuǎn)成ASCII 碼
- str++; //指向下一個(gè)字符
- }
- }
- //--------------輸入轉(zhuǎn)換并顯示(用于LCD1602)--------------------
- void display(uint Tem)
- {
- uint T,a,b;
- T=Tem*2;
- if(T>=27315) //溫度為正
- {
- T=T-27315; //
- a=T/100; //溫度整數(shù)
- b=T-a*100; //溫度小數(shù)
- if(a>=100) //溫度超過(guò)100 度
- {
- dat_wrt(0x30+a/100); //顯示溫度百位
- dat_wrt(0x30+a%100/10); //顯示溫度十位
- dat_wrt(0x30+a%10); //顯示溫度個(gè)位
- }
- else if(a>=10) //溫度超過(guò)10 度
- {
- dat_wrt(0x30+a%100/10); //顯示溫度十位
- dat_wrt(0x30+a%10); //顯示溫度個(gè)位
- }
- else //溫度不超過(guò)10 度
- {
- dat_wrt(0x30+a); //顯示溫度個(gè)位
- }
- dat_wrt(0x2e); //顯示小數(shù)點(diǎn)
- if(b>=10) //溫度小數(shù)點(diǎn)后第1 位數(shù)不等于0
- {
- dat_wrt(0x30+b/10); //顯示溫度小數(shù)點(diǎn)后第1 位數(shù)
- dat_wrt(0x30+b%10); //顯示溫度小數(shù)點(diǎn)后第2 位數(shù)
- }
- else //溫度小數(shù)點(diǎn)后第1 位數(shù)等于0
- {
- dat_wrt(0x30); //顯示溫度小數(shù)點(diǎn)后第1 位數(shù)0
- dat_wrt(0x30+b); //顯示溫度小數(shù)點(diǎn)后第2 位數(shù)
- }
- }
- else //溫度為負(fù)
- {
- T=27315-T;
- a=T/100;
- b=T-a*100;
- dat_wrt(0x2d); //顯示負(fù)號(hào)
- if(a>=10) //溫度低于負(fù)10 度
- {
- dat_wrt(0x30+a/10); //顯示溫度十位
- dat_wrt(0x30+a%10); //顯示溫度個(gè)位
- }
- else //溫度高于負(fù)10 度
- {
- dat_wrt(0x30+a); //顯示溫度個(gè)位
- }
- dat_wrt(0x2e); //顯示小數(shù)點(diǎn)
- if(b>=10) //溫度小數(shù)點(diǎn)后第1 位數(shù)不等于0
- {
- dat_wrt(0x30+b/10); //顯示溫度小數(shù)點(diǎn)后第1 位數(shù)
- dat_wrt(0x30+b%10); //顯示溫度小數(shù)點(diǎn)后第2 位數(shù)
- }
- else //溫度小數(shù)點(diǎn)后第1 位數(shù)等于0
- {
- dat_wrt(0x30); //顯示溫度小數(shù)點(diǎn)后第1 位數(shù)0
- dat_wrt(0x30+b); //顯示溫度小數(shù)點(diǎn)后第2 位數(shù)
- }
- }
- }
- //--------------------根據(jù)十六進(jìn)制計(jì)算溫度------------------------------
- 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 時(shí),SDA 由1 到0
- {
- SDA=1;
- delay(4);
- SCK=1;
- delay(4);
- SDA=0;
- delay(4);
- SCK=0;
- delay(4);
- }
- //------------------------------
- void stop(void) //停止條件是 SCK=1 時(shí),SDA 由0 到1
- {
- SCK=0;
- delay(4);
- SDA=0;
- delay(4);
- SCK=1;
- delay(4);
- SDA=1;
- }
- //---------發(fā)送一個(gè)字節(jié)---------
- void SendByte(uchar number)
- {
- uchar i,n,dat;
- n=Nack_number; //可以重發(fā)次數(shù)
- Send_again:
- dat=number;
- for(i=0;i<8;i++) //8 位依次發(fā)送
- {
- if(dat&0x80) //取最高位
- {
- bit_out=1; //發(fā)1
- }
- else
- {
- bit_out=0; //發(fā)0
- }
- send_bit(); //發(fā)送一個(gè)位
- dat=dat<<1; //左移一位
- }
- read_bit(); //接收1 位應(yīng)答信號(hào)
- if(bit_in==1) //無(wú)應(yīng)答時(shí)重發(fā)
- {
- stop();
- if(n!=0)
- {
- n--; //可以重發(fā)Nack_number=10 次
- goto Repeat; //重發(fā)
- }
- else
- {
- goto exit; //退出
- }
- }
- else
- {
- goto exit;
- }
- Repeat:
- start(); //重新開(kāi)始
- goto Send_again; //重發(fā)
- exit: ; //退出
- }
- //-----------發(fā)送一個(gè)位---------
- void send_bit(void)
- {
- if(bit_out==1)
- {
- SDA=1; //發(fā)1
- }
- else
- {
- SDA=0; //發(fā)0
- }
- _nop_();
- SCK=1; //上升沿
- delay(4);delay(4);
- SCK=0;
- delay(4);delay(4);
- }
- //----------接收一個(gè)字節(jié)--------
- 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 時(shí)對(duì)應(yīng)位加1
- }
- }
- SDA=0; //發(fā)送應(yīng)答信號(hào)0
- send_bit();
- return dat; //帶回接收數(shù)據(jù)
- }
- //----------接收一個(gè)位----------
- void read_bit(void)
- {
- SDA=1; //數(shù)據(jù)端先置1
- bit_in=1;
- SCK=1; //上升沿
- delay(4);delay(4);
- bit_in=SDA; //讀數(shù)據(jù)
- _nop_();
- SCK=0;
- delay(4);delay(4);
- }
- //------------------------------
- uint readtemp(void)
- {
- SCK=0;
- start(); //開(kāi)始條件
- SendByte(0x00); //發(fā)送從地址00
- SendByte(0x07); //發(fā)送命令
- start(); //開(kāi)始條件
- SendByte(0x01); //讀從地址00
- bit_out=0;
- tempL=ReadByte(); //讀數(shù)據(jù)低字節(jié)
- bit_out=0;
- tempH=ReadByte(); //讀數(shù)據(jù)高字節(jié)
- bit_out=1;
- err=ReadByte(); //讀錯(cuò)誤信息碼
- stop(); //停止條件
- return(tempH*256+tempL);
- }
- //******************LCD 顯示子函數(shù)***********************
- void init1602(void) //初始化LCD
- {
- cmd_wrt(0x01); //清屏
- cmd_wrt(0x0c); //開(kāi)顯示,不顯示光標(biāo),不閃爍
- cmd_wrt(0x06); //完成一個(gè)字符碼傳送后,光標(biāo)左移,顯
- 示不發(fā)生移位
- cmd_wrt(0x38); //16 ×2 顯示,5×7 點(diǎn)陣,8 位數(shù)據(jù)接口
- }
- void busy(void) //LCD 忙標(biāo)志判斷
- {
- flag=0x80; //賦初值 高位為1 禁止
- while(flag&0x80) //讀寫(xiě)操作使能位禁止時(shí)等待 繼續(xù)檢測(cè)
- {
- P1=0xff;
- RS=0; //指向地址計(jì)數(shù)器
- RW=1; //讀
- LCDE=1; //信號(hào)下降沿有效
- flag=P1; //讀狀態(tài)位 高位為狀態(tài)
- LCDE=0;
- }
- }
- void cmd_wrt(uchar cmd) //寫(xiě)命令子函數(shù)
- {
- LCDE=0;
- busy(); //檢測(cè)讀寫(xiě)操作使能嗎
- P1=cmd; //命令
- RS=0; //指向命令計(jì)數(shù)器
- RW=0; //寫(xiě)
- LCDE=1; //高電平有效
- LCDE=0;
- }
- void dat_wrt(uchar dat) //寫(xiě)數(shù)據(jù)子函數(shù)
- {
- busy(); //檢測(cè)讀寫(xiě)操作使能嗎
- LCDE=0;
- if(flag==16)
- {
- RS=0; //指向指令寄存器
- RW=0; //寫(xiě)
- P1=0XC0; //指向第二行
- LCDE=1; //高電平有效
- LCDE=0;
- }
- RS=1; //指向數(shù)據(jù)寄存器
- RW=0; //寫(xiě)
- P1=dat; //寫(xiě)數(shù)據(jù)
- LCDE=1; //高電平有效
- LCDE=0;
- }
- //------------延時(shí)--------------
- void delay(uint n)
- {
- uint j;
- for(j=0;j<n;j++)
- {
- _nop_();
- }
- }
- //------------定時(shí)器初始化函數(shù)----------------
- void initInt()
- {
- TMOD = 0x10; //定時(shí)器1 方式1
- TH1=(65536-1000)/256; //定時(shí)器1 設(shè)置1ms 定時(shí)
- TL1=(65536-1000)%256;
- EA=1; //開(kāi)總中斷
- ET1 = 1; //開(kāi)定時(shí)器T1 中斷
- TR1 = 1; //啟動(dòng)定時(shí)器T1
- }
- //------------定時(shí)器中斷處理函數(shù)-------------------
- void timer1handle() interrupt 3 //定時(shí)器3 1ms 中斷
- {
- TH1=(65536-1000)/256;
- TL1=(65536-1000)%256;
- c20ms++;
- c100ms++;
- if(c20ms >= 20) //20ms 計(jì)時(shí)器
- {
- c20ms = 0;
- b20ms = 1;
- }
- if(c100ms >= 50) //100ms 計(jì)時(shí)器
- {
- c100ms = 0;
- b100ms = 1;
- }
- }
- //--------------------------溫度顯示函數(shù)------------------------
- void show()
- {
- DPY1=0;
- P2=LED01[mah[3]]; //轉(zhuǎn)換8 位數(shù)顯示,不帶小數(shù)點(diǎn)的
- delay1(2);
- P2=0xFF;
- DPY1=1;
- DPY2=0;
- P2=LED02[mah[2]]; //轉(zhuǎn)換8 位數(shù)顯示,帶小數(shù)點(diǎn)的
- delay1(2);
- P2=0xFF;
- DPY2=1;
- DPY3=0;
- P2=LED01[mah[1]]; //轉(zhuǎn)換8 位數(shù)顯示,不帶小數(shù)點(diǎn)的
- delay1(2);
- P2=0xFF;
- DPY3=1;
- }
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
MLX90614紅外測(cè)溫儀實(shí)驗(yàn)指導(dǎo)書(shū)含源碼.pdf
(155.79 KB, 下載次數(shù): 691)
2018-2-7 22:22 上傳
點(diǎn)擊文件名下載附件
MLX90614的中英文資料下載:
http://www.torrancerestoration.com/bbs/dpj-107480-1.html
|
評(píng)分
-
查看全部評(píng)分
|