|
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (17.78 KB, 下載次數(shù): 44)
下載附件
2018-6-10 02:11 上傳
0.png (10.46 KB, 下載次數(shù): 36)
下載附件
2018-6-10 02:11 上傳
0.png (15.05 KB, 下載次數(shù): 36)
下載附件
2018-6-10 02:11 上傳
單片機(jī)源程序如下:
- #include <reg52.h> //包括一個(gè)52標(biāo)準(zhǔn)內(nèi)核的頭文件
- #include<intrins.h> //包含_nop_()函數(shù)定義的頭文件
- #define uchar unsigned char //定義一下方便使用
- #define uint unsigned int
- #define ulong unsigned long
- #define RdCommand 0x01 //定義ISP的操作命令
- #define PrgCommand 0x02
- #define EraseCommand 0x03
- #define Error 1
- #define Ok 0
- #define WaitTime 0x01 //定義CPU的等待時(shí)間
- sfr ISP_DATA=0xe2; //寄存器申明
- sfr ISP_ADDRH=0xe3;
- sfr ISP_ADDRL=0xe4;
- sfr ISP_CMD=0xe5;
- sfr ISP_TRIG=0xe6;
- sfr ISP_CONTR=0xe7;
- char a_a;
- sbit key1=P1^1;//參數(shù)加
- sbit key3=P1^2;//參數(shù)減
- sbit key2=P1^0;//參數(shù)設(shè)置按鍵
- sbit DQ=P3^3;
- sbit LED=P2^7;
- sbit alarm=P3^4;//蜂鳴器管腳定義
- sbit TX=P3^5; //超聲波模塊管腳定義(發(fā)射脈沖引腳定義)
- sbit RX=P3^6; //超聲波模塊管腳定義 (回波引腳定義)
- sbit RS=P2^0; //液晶寄存器選擇位,將RS位定義為P2.0引腳
- sbit RW=P2^1; //液晶讀寫(xiě)選擇位,將RW位定義為P2.1引腳
- sbit E=P2^2; //液晶使能信號(hào)位,將E位定義為P2.2引腳
- sbit BF=P0^7; //液晶忙碌標(biāo)志位,,將BF位定義為P0.7引腳
- unsigned char code digit[ ]={"0123456789"}; //定義字符數(shù)組顯示數(shù)字
- uint time=0,timer=0,S=0;
- uchar menu;//參數(shù)調(diào)整液晶顯示參數(shù)
- uchar ge,shi,bai,qian,flag; //距離數(shù)據(jù)轉(zhuǎn)換
- uchar num1,num2;//上下限參數(shù)定義
- uchar H_bai,H_shi,H_ge;//上限參數(shù)值分解顯示定義
- uchar L_bai,L_shi,L_ge;//下限參數(shù)值分解顯示定義
- uint temp1,temp2;//上下限參數(shù)轉(zhuǎn)換,用于報(bào)警值比較判斷
- uchar time0; //設(shè)置全局變量,專(zhuān)門(mén)用于嚴(yán)格延時(shí)
- uchar TL; //儲(chǔ)存暫存器的溫度低位
- uchar TH; //儲(chǔ)存暫存器的溫度高位
- uchar TN; //儲(chǔ)存溫度的整數(shù)部分
- uchar TD; //儲(chǔ)存溫度的小數(shù)部分
- uchar WD_temp;
- /* ================ 打開(kāi) ISP,IAP 功能 ================= */
- void ISP_IAP_enable(void)
- {
- EA = 0; /* 關(guān)中斷 */
- ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */
- ISP_CONTR = ISP_CONTR | WaitTime; /* 寫(xiě)入硬件延時(shí) */
- ISP_CONTR = ISP_CONTR | 0x80; /* ISPEN=1 */
- }
- /* =============== 關(guān)閉 ISP,IAP 功能 ================== */
- void ISP_IAP_disable(void)
- {
- ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
- ISP_TRIG = 0x00;
- EA = 1; /* 開(kāi)中斷 */
- }
- /* ================ 公用的觸發(fā)代碼 ==================== */
- void ISPgoon(void)
- {
- ISP_IAP_enable(); /* 打開(kāi) ISP,IAP 功能 */
- ISP_TRIG = 0x46; /* 觸發(fā)ISP_IAP命令字節(jié)1 */
- ISP_TRIG = 0xb9; /* 觸發(fā)ISP_IAP命令字節(jié)2 */
- _nop_();
- }
- /* ==================== 字節(jié)讀 ======================== */
- unsigned char byte_read(unsigned int byte_addr)
- {
- EA = 0;
- ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址賦值 */
- ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
- ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位 */
- ISP_CMD = ISP_CMD | RdCommand; /* 寫(xiě)入讀命令 */
- ISPgoon(); /* 觸發(fā)執(zhí)行 */
- ISP_IAP_disable(); /* 關(guān)閉ISP,IAP功能 */
- EA = 1;
- return (ISP_DATA); /* 返回讀到的數(shù)據(jù) */
- }
- /* ================== 扇區(qū)擦除 ======================== */
- void SectorErase(unsigned int sector_addr)
- {
- unsigned int iSectorAddr;
- iSectorAddr = (sector_addr & 0xfe00); /* 取扇區(qū)地址 */
- ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
- ISP_ADDRL = 0x00;
- ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位 */
- ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */
- ISPgoon(); /* 觸發(fā)執(zhí)行 */
- ISP_IAP_disable(); /* 關(guān)閉ISP,IAP功能 */
- }
- /* ==================== 字節(jié)寫(xiě) ======================== */
- void byte_write(unsigned int byte_addr, unsigned char original_data)
- {
- EA = 0;
- ISP_ADDRH = (unsigned char)(byte_addr >> 8); /* 取地址 */
- ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
- ISP_CMD = ISP_CMD & 0xf8; /* 清低3位 */
- ISP_CMD = ISP_CMD | PrgCommand; /* 寫(xiě)命令2 */
- ISP_DATA = original_data; /* 寫(xiě)入數(shù)據(jù)準(zhǔn)備 */
- ISPgoon(); /* 觸發(fā)執(zhí)行 */
- ISP_IAP_disable(); /* 關(guān)閉IAP功能 */
- EA =1;
- }
- void write_eeprom() //內(nèi)部eeprom寫(xiě)函數(shù)
- {
- SectorErase(0x2000); //清空
- SectorErase(0x2c00);
- SectorErase(0x2e00);
- byte_write(0x2c00,num1);
- byte_write(0x2c01,num2);
- byte_write(0x2060,0x01);
- }
- /******************把數(shù)據(jù)從單片機(jī)內(nèi)部eeprom中讀出來(lái)*****************/
- void read_eeprom()
- {
- num1=byte_read(0x2c00);
- num2=byte_read(0x2c01);
- a_a=byte_read(0x2060);
- }
- /**************開(kāi)機(jī)自檢eeprom初始化*****************/
- void init_eeprom()
- {
- a_a=byte_read(0x2060);
- if(a_a!=1) //新的單片機(jī)初始單片機(jī)內(nèi)問(wèn)eeprom
- {
- a_a=1;
- write_eeprom(); //保存數(shù)據(jù)
- }
- }
- //*****************I2C函數(shù)設(shè)置**********************//
- /*****************************************************
- 函數(shù)功能:將DS18B20傳感器初始化,讀取應(yīng)答信號(hào)
- 出口參數(shù):flag
- ***************************************************/
- bit Init_DS18B20(void)
- {
- bit flag; //儲(chǔ)存DS18B20是否存在的標(biāo)志,flag=0,表示存在;flag=1,表示不存在
- DQ = 1; //先將數(shù)據(jù)線拉高
- for(time0=0;time0<2;time0++);//略微延時(shí)約6微秒
- DQ = 0; //再將數(shù)據(jù)線從高拉低,要求保持480~960us
- for(time0=0;time0<200;time0++) //略微延時(shí)約600微秒
- ; //以向DS18B20發(fā)出一持續(xù)480~960us的低電平復(fù)位脈沖
- DQ = 1; //釋放數(shù)據(jù)線(將數(shù)據(jù)線拉高)
- for(time0=0;time0<10;time0++)
- ; //延時(shí)約30us(釋放總線后需等待15~60us讓DS18B20輸出存在脈沖)
- flag=DQ; //讓單片機(jī)檢測(cè)是否輸出了存在脈沖(DQ=0表示存在)
- for(time0=0;time0<200;time0++) //延時(shí)足夠長(zhǎng)時(shí)間,等待存在脈沖輸出完畢
- ;
- return (flag); //返回檢測(cè)成功標(biāo)志
- }
- /*****************************************************
- 函數(shù)功能:從DS18B20讀取一個(gè)字節(jié)數(shù)據(jù)
- 出口參數(shù):dat
- ***************************************************/
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat; //儲(chǔ)存讀出的一個(gè)字節(jié)數(shù)據(jù)
- for (i=0;i<8;i++)
- {
- DQ =1; // 先將數(shù)據(jù)線拉高
- _nop_(); //等待一個(gè)機(jī)器周期
- DQ = 0; //單片機(jī)從DS18B20讀書(shū)據(jù)時(shí),將數(shù)據(jù)線從高拉低即啟動(dòng)讀時(shí)序
- dat>>=1;
- _nop_(); //等待一個(gè)機(jī)器周期
- DQ = 1; //將數(shù)據(jù)線"人為"拉高,為單片機(jī)檢測(cè)DS18B20的輸出電平作準(zhǔn)備
- for(time0=0;time0<2;time0++); //延時(shí)約6us,使主機(jī)在15us內(nèi)采樣
- if(DQ==1)
- dat|=0x80; //如果讀到的數(shù)據(jù)是1,則將1存入dat
- else
- dat|=0x00;//如果讀到的數(shù)據(jù)是0,則將0存入dat
- //將單片機(jī)檢測(cè)到的電平信號(hào)DQ存入r[i]
- for(time0=0;time0<8;time0++); //延時(shí)3us,兩個(gè)讀時(shí)序之間必須有大于1us的恢復(fù)期
- }
- return(dat); //返回讀出的十進(jìn)制數(shù)據(jù)
- }
- /*****************************************************
- 函數(shù)功能:向DS18B20寫(xiě)入一個(gè)字節(jié)數(shù)據(jù)
- 入口參數(shù):dat
- ***************************************************/
- WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=0; i<8; i++)
- {
- DQ =1; // 先將數(shù)據(jù)線拉高
- _nop_(); //等待一個(gè)機(jī)器周期
- DQ=0; //將數(shù)據(jù)線從高拉低時(shí)即啟動(dòng)寫(xiě)時(shí)序
- DQ=dat&0x01; //利用與運(yùn)算取出要寫(xiě)的某位二進(jìn)制數(shù)據(jù),
- //并將其送到數(shù)據(jù)線上等待DS18B20采樣
- for(time0=0;time0<10;time0++);//延時(shí)約30us,DS18B20在拉低后的約15~60us期間從數(shù)據(jù)線上采樣
- DQ=1; //釋放數(shù)據(jù)線
- for(time0=0;time0<1;time0++);//延時(shí)3us,兩個(gè)寫(xiě)時(shí)序間至少需要1us的恢復(fù)期
- dat>>=1; //將dat中的各二進(jìn)制位數(shù)據(jù)右移1位
- }
- for(time0=0;time0<4;time0++); //稍作延時(shí),給硬件一點(diǎn)反應(yīng)時(shí)間
- }
- //液晶函數(shù)設(shè)置************************************/
- /*****************************************************
- 函數(shù)功能:延時(shí)1ms
- (3j+2)*i=(3×33+2)×10=1010(微秒),可以認(rèn)為是1毫秒
- ***************************************************/
- void delay1ms()
- {
- unsigned char i,j;
- for(i=0;i<10;i++)
- for(j=0;j<33;j++)
- ;
- }
- /*****************************************************
- 函數(shù)功能:延時(shí)若干毫秒
- 入口參數(shù):n
- ***************************************************/
- void delay(unsigned char n)
- {
- unsigned char i;
- for(i=0;i<n;i++)
- delay1ms();
- }
- /*****************************************************
- 函數(shù)功能:判斷液晶模塊的忙碌狀態(tài)
- 返回值:result。result=1,忙碌;result=0,不忙
- ***************************************************/
- unsigned char BusyTest(void)
- {
- bit result;
- RS=0; //根據(jù)規(guī)定,RS為低電平,RW為高電平時(shí),可以讀狀態(tài)
- RW=1;
- E=1; //E=1,才允許讀寫(xiě)
- _nop_(); //空操作
- _nop_();
- _nop_();
- _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- result=BF; //將忙碌標(biāo)志電平賦給result
- E=0; //將E恢復(fù)低電平
- return result;
- }
- /*****************************************************
- 函數(shù)功能:將模式設(shè)置指令或顯示地址寫(xiě)入液晶模塊
- 入口參數(shù):dictate
- ***************************************************/
- void WriteInstruction (unsigned char dictate)
- {
- while(BusyTest()==1); //如果忙就等待
- RS=0; //根據(jù)規(guī)定,RS和R/W同時(shí)為低電平時(shí),可以寫(xiě)入指令
- RW=0;
- E=0; //E置低電平(根據(jù)表8-6,寫(xiě)指令時(shí),E為高脈沖,
- // 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
- _nop_();
- _nop_(); //空操作兩個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- P0=dictate; //將數(shù)據(jù)送入P0口,即寫(xiě)入指令或地址
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- E=1; //E置高電平
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- E=0; //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開(kāi)始執(zhí)行命令
- }
- /*****************************************************
- 函數(shù)功能:指定字符顯示的實(shí)際地址
- 入口參數(shù):x
- ***************************************************/
- void WriteAddress(unsigned char x)
- {
- WriteInstruction(x|0x80); //顯示位置的確定方法規(guī)定為"80H+地址碼x"
- }
- /*****************************************************
- 函數(shù)功能:將數(shù)據(jù)(字符的標(biāo)準(zhǔn)ASCII碼)寫(xiě)入液晶模塊
- 入口參數(shù):y(為字符常量)
- ***************************************************/
- void WriteData(unsigned char y)
- {
- while(BusyTest()==1);
- RS=1; //RS為高電平,RW為低電平時(shí),可以寫(xiě)入數(shù)據(jù)
- RW=0;
- E=0; //E置低電平(根據(jù)表8-6,寫(xiě)指令時(shí),E為高脈沖,
- // 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"
- P0=y; //將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫(xiě)入液晶模塊
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- E=1; //E置高電平
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //空操作四個(gè)機(jī)器周期,給硬件反應(yīng)時(shí)間
- E=0; //當(dāng)E由高電平跳變成低電平時(shí),液晶模塊開(kāi)始執(zhí)行命令
- }
- /*****************************************************
- 函數(shù)功能:對(duì)LCD的顯示模式進(jìn)行初始化設(shè)置
- ***************************************************/
- void LcdInitiate(void)
- {
- delay(15); //延時(shí)15ms,首次寫(xiě)指令時(shí)應(yīng)給LCD一段較長(zhǎng)的反應(yīng)時(shí)間
- WriteInstruction(0x38); //顯示模式設(shè)置:16×2顯示,5×7點(diǎn)陣,8位數(shù)據(jù)接口
- delay(5); //延時(shí)5ms ,給硬件一點(diǎn)反應(yīng)時(shí)間
- WriteInstruction(0x38);
- delay(5);
- WriteInstruction(0x38); //連續(xù)三次,確保初始化成功
- delay(5);
- WriteInstruction(0x0c); //顯示模式設(shè)置:顯示開(kāi),無(wú)光標(biāo),光標(biāo)不閃爍
- delay(5);
- WriteInstruction(0x06); //顯示模式設(shè)置:光標(biāo)右移,字符不移
- delay(5);
- WriteInstruction(0x01); //清屏幕指令,將以前的顯示內(nèi)容清除
- delay(5);
- WriteAddress(0);//從第一行開(kāi)始顯示
- WriteData('J'); //將萬(wàn)位數(shù)字的字符常量寫(xiě)入LCD
- WriteData('L'); //將萬(wàn)位數(shù)字的字符常量寫(xiě)入LCD
- WriteData(':'); //將萬(wàn)位數(shù)字的字符常量寫(xiě)入LCD
- WriteAddress(7);//從第一行開(kāi)始顯示
- WriteData('C'); //將萬(wàn)位數(shù)字的字符常量寫(xiě)入LCD
- WriteData('M'); //將萬(wàn)位數(shù)字的字符常量寫(xiě)入LCD
- WriteAddress(0x40);
- WriteData('H');
- WriteData(':');
- WriteAddress(0x40+5);
- WriteData('C');
- WriteData('M');
- WriteAddress(0x40+9);
- WriteData('L');
- WriteData(':');
- WriteAddress(0x40+14);
- WriteData('C');
- WriteData('M');
- WriteAddress(15);
- WriteData(0xdf);
- }
- //假如溫度25攝氏度時(shí),聲速位346m/s
- //時(shí)鐘周期為T(mén)0=1/11.0592M,則機(jī)器周期為1/11.0592*12us=1.08us,定時(shí)器計(jì)時(shí)為time0(定時(shí)的數(shù)量就是時(shí)鐘周期數(shù))
- //實(shí)際時(shí)間t=time0*1.08
- //距離S=vt/2=v*time0*1.08/2/1000000=算出來(lái)的值是米
- void Conut(void)
- {
- float vv;
- time=TH0*256+TL0; //TH0左移8位后與TL0相加
- TH0=0;
- TL0=0;
- vv=(331.5+0.607*TN);//聲速VV和聲速TN的關(guān)系
- S=((time*vv*1/200)/10); //注意除以10相當(dāng)于算出來(lái)的值單位毫米,*1.08是因?yàn)榫д?1.0592,如果是12MHZ就是*1
- /*time=TH0*256+TL0; //TH0左移8位后與TL0相加
- TH0=0;
- TL0=0;
- S=((time*1.87)/10); //注意除以10相當(dāng)于算出來(lái)的值單位毫米 */
- if((S>=4000)||(flag==1)) //超出測(cè)量范圍(4米)
- {
- flag=0;
- qian=0;
- bai=0;
- shi=0;
- ge=0;
- delay(10);
- }
- else
- {
- qian=S/1000;
- bai=S%1000/100;
- shi=S%1000%100/10;
- ge=S%1000%10 %10;
- }
- }
- /*****************************************************
- 函數(shù)功能:顯示溫度的整數(shù)部分
- 入口參數(shù):x
- ***************************************************/
- void display_temp1(unsigned char x)
- {
- unsigned char j,k,l; //j,k,l分別儲(chǔ)存溫度的百位、十位和個(gè)位
- j=x/100; //取百位
- k=(x%100)/10; //取十位
- l=x%10; //取個(gè)位
- WriteAddress(11); //寫(xiě)顯示地址,將在第2行第7列開(kāi)始顯示
- //WriteData(digit[j]); //將百位數(shù)字的字符常量寫(xiě)入LCD
- WriteData(digit[k]); //將十位數(shù)字的字符常量寫(xiě)入LCD
- WriteData(digit[l]); //將個(gè)位數(shù)字的字符常量寫(xiě)入LCD
- delay(50); //延時(shí)1ms給硬件一點(diǎn)反應(yīng)時(shí)間
- }
- /*****************************************************
- 函數(shù)功能:顯示溫度的小數(shù)數(shù)部分
- 入口參數(shù):x
- ***************************************************/
- void display_temp2(unsigned char x)
- {
- WriteAddress(14); //寫(xiě)顯示地址,將在第2行第11列開(kāi)始顯示
- WriteData(digit[x]); //將小數(shù)部分的第一位數(shù)字字符常量寫(xiě)入LCD
- delay(50); //延時(shí)1ms給硬件一點(diǎn)反應(yīng)時(shí)間
- }
- /*****************************************************
- 函數(shù)功能:做好讀溫度的準(zhǔn)備
- ***************************************************/
- void ReadyReadTemp(void)
- {
- Init_DS18B20(); //將DS18B20初始化
- WriteOneChar(0xCC); // 跳過(guò)讀序號(hào)列號(hào)的操作
- WriteOneChar(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
- for(time=0;time<150;time++)
- ; //溫度轉(zhuǎn)換需要一點(diǎn)時(shí)間
- Init_DS18B20(); //將DS18B20初始化
- WriteOneChar(0xCC); //跳過(guò)讀序號(hào)列號(hào)的操作
- WriteOneChar(0xBE); //讀取溫度寄存器,前兩個(gè)分別是溫度的低位和高位
- }
- void alarming()//蜂鳴器報(bào)警子函數(shù)
- {
- alarm=0;
- LED=0;
- delay(50);
- alarm=1;
- LED=1;
- delay(100);
- }
- /***************按鍵設(shè)置****************************/
- void key_shezhi()
- {
- if(key2==0)//如果上下限參數(shù)調(diào)整按鍵按下
- {
- delay(30);
- if(key2==0)
- {
- menu++;//設(shè)置頁(yè)面調(diào)整
- if(menu>2)//如果設(shè)置完下限值后,液晶回歸正常顯示
- {
- menu=0;
- LcdInitiate();//更新初始化顯示
- delay(20);//適當(dāng)延時(shí)
- }
- }
- while(!key2);
- }
- if(menu==0)
- {
- ET0=1; //打開(kāi)定時(shí)中斷
- ET1=1;
- WriteAddress(3);
- WriteData(digit[qian]);//更新顯示實(shí)時(shí)測(cè)距的距離
- delay(20);
- WriteData(digit[bai]);//更新顯示實(shí)時(shí)測(cè)距的距離
- delay(20);
- WriteData(digit[shi]);//更新顯示實(shí)時(shí)測(cè)距的距離
- delay(20);
- //WriteData('.');//增加一個(gè)小數(shù)點(diǎn),用于毫米和厘米的切換指示
- //delay(20);
- //WriteData(digit[ge]); //更新顯示實(shí)時(shí)測(cè)距的距離
- //delay(20);
- ET0=0; //關(guān)閉定時(shí)中斷,執(zhí)行溫度讀取
- ET1=0;
- ReadyReadTemp(); //讀溫度準(zhǔn)備
- TL=ReadOneChar(); //先讀的是溫度值低位
- TH=ReadOneChar(); //接著讀的是溫度值高位
- TN=TH*16+TL/16; //實(shí)際溫度值=(TH*256+TL)/16,即:TH*16+TL/16
- //這樣得出的是溫度的整數(shù)部分,小數(shù)部分被丟棄了
- TD=(TL%16)*10/16; //計(jì)算溫度的小數(shù)部分,將余數(shù)乘以10再除以16取整,
- //這樣得到的是溫度小數(shù)部分的第一位數(shù)字(保留1位小數(shù))
- if((TN==85)&&(WD_temp==0))//18B20芯片開(kāi)電首次讀取的溫度是85,本程序避開(kāi)85的問(wèn)題
- {
- TN=0;
- }
- else if(TN!=85)
- {
- WD_temp=1;//開(kāi)電首次85避開(kāi)
- }
- ET0=1; //溫度處理完后打開(kāi)定時(shí)中斷
- ET1=1;
- display_temp1(TN); //顯示溫度的整數(shù)部分
- display_temp2(TD); //顯示溫度的小數(shù)部分
- WriteAddress(13);
- WriteData('.');
- H_bai=num1/100;//更新顯示調(diào)整后的上限值
- H_shi=num1%100/10;//更新顯示調(diào)整后的上限值
- H_ge=num1%100%10; //更新顯示調(diào)整后的上限值
- WriteAddress(0x40+2);//更新顯示調(diào)整后的上限值
- WriteData(digit[H_bai]);//更新顯示調(diào)整后的上限值
- WriteData(digit[H_shi]);//更新顯示調(diào)整后的上限值
- WriteData(digit[H_ge]);//更新顯示調(diào)整后的上限值
- L_bai=num2/100; //更新顯示調(diào)整后的下限值
- L_shi=num2%100/10;//更新顯示調(diào)整后的下限值
- L_ge=num2%100%10;//更新顯示調(diào)整后的下限值
- WriteAddress(0x40+11);//更新顯示調(diào)整后的下限值
- WriteData(digit[L_bai]); //更新顯示調(diào)整后的下限值
- WriteData(digit[L_shi]);//更新顯示調(diào)整后的下限值
- WriteData(digit[L_ge]); //更新顯示調(diào)整后的下限值
- if(S>=temp1)//報(bào)警設(shè)置
- {
- alarming();//如果距離大于上限值報(bào)警
- }
- else if(S<temp2)
- {
- alarming();//如果距離小于下限值報(bào)警
- }
- else
- {
- alarm=1;//關(guān)閉報(bào)警
- }
- }
- if(menu==1)//切換液晶上限設(shè)置
- {
- ET0=0;//把定時(shí)中斷暫時(shí)關(guān)閉
- ET1=0;
- if(key1==0)//加按鍵
- {
- delay(30);
- if(key1==0)
- {
- num1++;
- if(num1==400)//上限4米
- {
- num1=0;
- }
- if(num1<num2)//調(diào)整上限值得時(shí)候,上限值不能小于下限值
- {
- num1=num2;//否則等于下限值
- }
- }
- while(!key1);//等待按鍵釋放
- }
- if(key3==0)//減按鍵
- {
- delay(30);
- if(key3==0)
- {
- if((num1>0)&&(num1>num2))//如果同時(shí)滿(mǎn)足num1大于零和上限值大于下限值,可以減減
- {
- num1--;
- }
- }
- while(!key3);//等待按鍵釋放
- }
- write_eeprom();
- delay(2);
- delay(2);
- H_bai=num1/100;//上限值轉(zhuǎn)換用于液晶顯示
- H_shi=num1%100/10;//上限值轉(zhuǎn)換用于液晶顯示
- H_ge=num1%100%10;//上限值轉(zhuǎn)換用于液晶顯示
-
- delay(20);//延時(shí)消除光標(biāo)重影
- WriteAddress(0x40+2);//定位位置用于顯示更新上限值
- WriteData(digit[H_bai]);//上限值更新顯示
- WriteData(digit[H_shi]);//上限值更新顯示
- WriteData(digit[H_ge]);//上限值更新顯示
- WriteAddress(0x40+4);//移到上限值得個(gè)位數(shù),用于光標(biāo)顯示
- WriteInstruction(0x0e);//光標(biāo)顯示,不閃爍
- }
- if(menu==2)//下限值調(diào)整設(shè)置
- {
- ET0=0;
- ET1=0;
- if(key1==0)
- {
- delay(30);
- if(key1==0)
- {
- if(num2<num1)
- {
- num2++;
- }
- }
- while(!key1);
- }
- if(key3==0)
- {
- delay(30);
- if(key3==0)
- {
- if((num1>=num2)&&(num2>0))
- {
- num2--;
- }
- }
- while(!key3);
-
- }
- write_eeprom();
- delay(2);
- L_bai=num2/100;
- L_shi=num2%100/10;
- L_ge=num2%100%10;
- delay(20);//延時(shí)消除光標(biāo)重影
- WriteAddress(0x40+11);
- WriteData(digit[L_bai]);
- WriteData(digit[L_shi]);
- WriteData(digit[L_ge]);
- WriteAddress(0x40+13);//移到個(gè)位,光標(biāo)閃爍
- WriteInstruction(0x0e);
- }
- }
- void main(void) // 主程序
- {
- LED=1;
- key1=1;//按鍵初始化
- key2=1;//按鍵初始化
- key3=1;//按鍵初始化
- TMOD=0x11; //設(shè)置定時(shí)器0和1工作方式為1(0001 0001)
- TH0=0; //裝初值
- TL0=0; //裝初值
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;
- EA=1; //開(kāi)總中斷
- ET0=1; //開(kāi)定時(shí)器0中斷
- ET1=1; //開(kāi)定時(shí)器1中斷
- TR1=1; //啟動(dòng)定時(shí)器1
- TX=0;
- RX=0;
- LcdInitiate(); //調(diào)用LCD初始化函數(shù)
- delay(10); //延時(shí)10ms,給硬件一點(diǎn)反應(yīng)時(shí)間
- init_eeprom(); //初始化eeprom
- delay(10);
- read_eeprom(); //讀取eeprom數(shù)據(jù)
- delay(10);
- while(1) //程序循環(huán)
- {
- key_shezhi(); //循環(huán)調(diào)用按鍵設(shè)置函數(shù)
- temp1=num1*10;//由于num1單位是厘米,S單位是毫米,要*10轉(zhuǎn)換成統(tǒng)一單位進(jìn)行比較,用于報(bào)警設(shè)置
- temp2=num2*10;
- }
- }
- void zd0() interrupt 1 //T0中斷用來(lái)計(jì)數(shù)器溢出,超過(guò)測(cè)距范圍
- {
- flag=1; //中斷溢出標(biāo)志
- }
- void zd3() interrupt 3 //T1中斷
- {
- TH1=(65536-50000)/256; //重新裝初值高8位 約0.05s
- TL1=(65536-50000)%256;//重新裝初值低8位
- timer++;//
- if(timer>=5)//中斷5次約0.25s
- {
- TR1=0; //關(guān)閉定時(shí)器1
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;
- timer=0;
- TX=1;//先吧TX拉高//給個(gè)高位脈沖
- _nop_();//延時(shí)
- _nop_();//延時(shí)
- _nop_();//延時(shí)
- _nop_();//延時(shí)
- _nop_();//延時(shí)
- _nop_();//延時(shí)
- _nop_();//延時(shí)
- _nop_();//延時(shí)
- _nop_();//延時(shí)
- _nop_();//延時(shí)
- TX=0; //拉低
- while(!RX); //當(dāng)RX為零時(shí)等待
- TR0=1; //啟動(dòng)定時(shí)器0,開(kāi)啟計(jì)數(shù)
- while(RX); //當(dāng)RX為1計(jì)數(shù)并等待
- TR0=0; //關(guān)閉定時(shí)器0 關(guān)閉計(jì)數(shù)//計(jì)時(shí)完畢
- Conut(); //調(diào)用距離計(jì)算函數(shù),計(jì)算距離
- TR1=1; //啟動(dòng)定時(shí)器1
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
211 超聲波測(cè)距仿真(溫度補(bǔ)償).zip
(420.11 KB, 下載次數(shù): 74)
2018-6-6 10:58 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|