传感器集成温度传感器(DS1820)温度特性实验
生活随笔
收集整理的這篇文章主要介紹了
传感器集成温度传感器(DS1820)温度特性实验
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
實(shí)驗(yàn)?zāi)M電路圖(簡(jiǎn)略):
?在proteus原理圖的繪制中需要用到的元器件:
?程序源碼:
#include<reg51.h> //預(yù)處理命令,定義SFR的頭 #include <math.h> #define uchar unsigned char //定義縮寫字符uchar #define uint unsigned int //定義縮寫字符uint #define lcd_data P0 //定義LCD1602接口 P0 sbit DQ =P1^7; //將DQ位定義為P1.7引腳 sbit lcd_RS=P2^0; //將RS位定義為P2.0引腳 sbit lcd_RW=P2^1; //將RW位定義為P2.1引腳 sbit lcd_EN=P2^2; //將EN位定義為P2.2引腳 sbit PWM=P3^7; //將PWM定義為P3.7引腳 sbit D=P3^6; //將d定義為P3.6引腳,轉(zhuǎn)向選擇位 uchar t[2],speed,temperature; //用來存放溫度值,測(cè)溫程序就是通過這個(gè)數(shù)組與主函數(shù)通信的 uchar DS18B20_is_ok; uchar TempBuffer1[12]={0x20,0x20,0x20,0x20,0xdf,0x43,'\0'}; uchar tab[16]={0x20,0x20,0x20,0x54,0x20,0x4d,0x6f,0x6e,0x69,0x74,0x6f,0x72,'\0'};//顯示"T Monitor" /**********lcd顯示子程序************/void delay_20ms(void) /*延時(shí)20ms函數(shù)*/ {uchar i,temp; //聲明變量i,tempfor(i = 20;i > 0;i--) //循環(huán){temp = 248; //給temp賦值248while(--temp); //temp減1是否等于0,否則繼續(xù)執(zhí)行該行temp = 248; //給temp賦值248 while(--temp); //temp減1是否等于0,否則繼續(xù)執(zhí)行該行} } void delay_38us(void) /*延時(shí)38us函數(shù)*/ { uchar temp; //聲明變量temptemp = 18; //給temp賦值while(--temp); //temp減1是否等于0,否則繼續(xù)執(zhí)行該行 } void delay_1520us(void) /*延時(shí)1520us函數(shù)*/ { uchar i,temp; //聲明變量i,tempfor(i = 3;i > 0;i--) //循環(huán){temp = 252; //給temp賦值while(--temp); //temp減1是否等于0,否則繼續(xù)執(zhí)行該行} } uchar lcd_rd_status( ) /*讀取lcd1602的狀態(tài),主要用于判斷忙*/ {uchar tmp_sts; //聲明變量tmp_stslcd_data = 0xff; //初始化P3口lcd_RW = 1; //RW =1 讀 lcd_RS = 0; //RS =0 命令,合起來表示讀命令(狀態(tài))lcd_EN = 1; //EN=1,打開EN,LCD1602開始輸出命令數(shù)據(jù),100nS之后命令數(shù)據(jù)有效tmp_sts = lcd_data; //讀取命令到tmp_stslcd_EN = 0; //關(guān)掉LCD1602lcd_RW = 0; //把LCD1602設(shè)置成寫return tmp_sts; //函數(shù)返回值tmp_sts } void lcd_wr_com(uchar command ) /*寫一個(gè)命令到LCD1602*/ {while(0x80&lcd_rd_status()); //寫之前先判斷LCD1602是否忙,看讀出的命令的最高位是否為1,為1表示忙,繼續(xù)讀,直到不忙lcd_RW = 0;lcd_RS = 0; //RW=0,RS=0 寫命令lcd_data = command; //把需要寫的命令寫到數(shù)據(jù)線上lcd_EN = 1; lcd_EN = 0; //EN輸出高電平脈沖,命令寫入 } void lcd_wr_data(uchar sjdata ) /*寫一個(gè)顯示數(shù)據(jù)到lcd1602*/ {while(0x80&lcd_rd_status()); //寫之前先判斷l(xiāng)cd1602是否忙,看讀出的命令的最高位是否為1,為1表示忙,繼續(xù)讀,直到不忙lcd_RW = 0;lcd_RS = 1; //RW=0,RS=1 寫顯示數(shù)據(jù)lcd_data = sjdata ; //把需要寫的顯示數(shù)據(jù)寫到數(shù)據(jù)線上lcd_EN = 1;lcd_EN = 0; //EN輸出高電平脈沖,命令寫入lcd_RS = 0; } void Init_lcd(void) /*初始化lcd1602*/ {delay_20ms(); //調(diào)用延時(shí)lcd_wr_com(0x38); //設(shè)置16*2格式,5*8點(diǎn)陣,8位數(shù)據(jù)接口delay_38us(); //調(diào)用延時(shí)lcd_wr_com(0x0c); //開顯示,不顯示光標(biāo)delay_38us(); //調(diào)用延時(shí)lcd_wr_com(0x01); //清屏delay_1520us(); //調(diào)用延時(shí)lcd_wr_com(0x06); //顯示一個(gè)數(shù)據(jù)后光標(biāo)自動(dòng)+1 } void GotoXY(uchar x, uchar y) //設(shè)定位置,x為行,y為列 {if(y==0) //如果y=0,則顯示位置為第一行l(wèi)cd_wr_com(0x80|x);if(y==1)lcd_wr_com(0xc0|x); //如果y=1,則顯示位置為第二行 }void Print(uchar *str) //顯示字符串函數(shù) {while(*str!='\0') //判斷字符串是否顯示完{lcd_wr_data(*str); //寫數(shù)據(jù)str++; } } void LCD_Print(uchar x, uchar y, uchar *str)//x為行值,y為列值,str是要顯示的字符串 {GotoXY(x,y); //設(shè)定顯示位置Print(str); //顯示字符串 }/*****************系統(tǒng)顯示子函數(shù)*****************/void covert1() //溫度轉(zhuǎn)化程序 {uchar x=0x00; //變量初始化if(t[1]>0x07) //判斷正負(fù)溫度{ TempBuffer1[0]=0x2d; //0x2d為"-"的ASCII碼t[1]=~t[1]; //負(fù)數(shù)的補(bǔ)碼t[0]=~t[0]; //換算成絕對(duì)值x=t[0]+1; //加1t[0]=x; //把x的值送入t[0]if(x>255) //如果x大于255t[1]++; //t[1]加1}else TempBuffer1[0]=0x2b; //0xfe為變"+"的ASCII碼t[1]<<=4; //將高字節(jié)左移4位t[1]=t[1]&0x70; //取出高字節(jié)的3個(gè)有效數(shù)字位x=t[0]; //將t[0]暫存到X,因?yàn)槿⌒?shù)部分還要用到它x>>=4; //右移4位x=x&0x0f; //和前面兩句就是取出t[0]的高四位 t[1]=t[1]|x; //將高低字節(jié)的有效值的整數(shù)部分拼成一個(gè)字節(jié)temperature=t[1];TempBuffer1[1]=t[1]/100+0x30;//加0x30 為變 0~9 ASCII碼if(TempBuffer1[1]==0x30) //如果百位為0TempBuffer1[1]=0xfe; //百位數(shù)消隱TempBuffer1[2]=(t[1]%100)/10+0x30;//分離出十位TempBuffer1[3]=(t[1]%100)%10+0x30;//分離出個(gè)位 } /*******************DS18B20函數(shù)**********************/void delay_18B20(uint i) //延時(shí)程序 {while(i--); } void Init_DS18B20(void) //ds18b20初始化函數(shù) {uchar x=0;DQ = 1; //DQ復(fù)位delay_18B20(8); //稍做延時(shí)DQ = 0; //單片機(jī)將DQ拉低delay_18B20(80); //精確延時(shí)大于480usDQ = 1; //拉高總線delay_18B20(14);x=DQ; //稍做延時(shí)后 如果x=0則初始化成功 x=1則初始化失敗delay_18B20(20); } uchar ReadOneChar(void) //ds18b20讀一個(gè)字節(jié)函數(shù) {unsigned char i=0;unsigned char dat0 = 0;for (i=8;i>0;i--){DQ = 0; //讀前總線保持為低dat0>>=1;DQ = 1; //開始讀總線釋放if(DQ) //從DS18B20總線讀得一位dat0|=0x80;delay_18B20(4); //延時(shí)一段時(shí)間}return(dat0); //返回?cái)?shù)據(jù) } void WriteOneChar(uchar dat1) //ds18b20寫一個(gè)字節(jié)函數(shù) {uchar i=0;for (i=8; i>0; i--){DQ = 0; //開始寫入DS18B20總線要處于復(fù)位(低)狀態(tài)DQ = dat1&0x01; //寫入下一位 delay_18B20(5);DQ = 1; //重新釋放總線dat1>>=1; //把一個(gè)字節(jié)分成8個(gè)BIT環(huán)移給DQ} } void ReadTemperature() //讀取ds18b20當(dāng)前溫度 { delay_18B20(80); //延時(shí)一段時(shí)間Init_DS18B20(); WriteOneChar(0xCC); // 跳過讀序號(hào)列號(hào)的操作WriteOneChar(0x44); // 啟動(dòng)溫度轉(zhuǎn)換delay_18B20(80); // 延時(shí)一段時(shí)間Init_DS18B20(); //DS18B20初始化WriteOneChar(0xCC); //跳過讀序號(hào)列號(hào)的操作WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度delay_18B20(80); //延時(shí)一段時(shí)間t[0]=ReadOneChar(); //讀取溫度值低位t[1]=ReadOneChar(); //讀取溫度值高位 } void delay_motor(uchar i) //延時(shí)函數(shù) {uchar j,k; //變量i、k為無符號(hào)字符數(shù)據(jù)類型for(j=i;j>0;j--) //循環(huán)延時(shí)for(k=200;k>0;k--); //循環(huán)延時(shí) } /*******************電機(jī)轉(zhuǎn)動(dòng)程序*******************/void motor(uchar tmp) { uchar x;if(TempBuffer1[0]==0x2b) //溫度為正數(shù){if(tmp<25) //溫度小于25度{D=0; //電機(jī)停止轉(zhuǎn)動(dòng)PWM=0;}else if(tmp>50) //溫度大于50度,全速轉(zhuǎn)動(dòng){D=0; //D置0PWM=1; //正轉(zhuǎn),PWM=1x=250; //時(shí)間常數(shù)為xdelay_motor(x); //調(diào)延時(shí)函數(shù)PWM=0; // PWM=0x=5; //時(shí)間常數(shù)為xdelay_motor(x); //調(diào)延時(shí)函數(shù)}else{D=0; //D置0PWM=1; //正轉(zhuǎn),PWM=1x=5*tmp; //時(shí)間常數(shù)為xdelay_motor(x); //調(diào)延時(shí)函數(shù)PWM=0; // PWM=0x=255-5*tmp; //時(shí)間常數(shù)為255-xdelay_motor(x); //調(diào)延時(shí)函數(shù)}}else if (TempBuffer1[0]==0x2d) //溫度小于0,反轉(zhuǎn){D=1; PWM=0; // PWM=0x=5*tmp; //時(shí)間常數(shù)為tmpdelay_motor(x); //調(diào)延時(shí)函數(shù)PWM=1; // PWM=1x=255-5*tmp; //時(shí)間常數(shù)為255- tmpdelay_motor(x); //調(diào)延時(shí)函數(shù)} } void delay(unsigned int x) //延時(shí)函數(shù)名 {unsigned char i; //定義變量i的類型while(x--) //x自減1{for(i=0;i<123;i++){;} //控制延時(shí)的循環(huán)} } /*************************main主程序*********************/ void main(void) { delay_20ms(); //系統(tǒng)延時(shí)20ms啟動(dòng)ReadTemperature(); //啟動(dòng)DS18B20Init_lcd(); //調(diào)用LCD初始化函數(shù)LCD_Print(0,0,tab); //液晶初始顯示delay(1000); //延時(shí)一段時(shí)間while(1){ ReadTemperature(); //讀取溫度,溫度值存放在一個(gè)兩個(gè)字節(jié)的數(shù)組中, delay_18B20(100); covert1(); //數(shù)據(jù)轉(zhuǎn)化LCD_Print(4,1,TempBuffer1); //顯示溫度motor(temperature); //電機(jī)轉(zhuǎn)動(dòng)} }運(yùn)行即可通過示波器觀察到在不同溫度的情況下,輸出方波的高低情況。
?
總結(jié)
以上是生活随笔為你收集整理的传感器集成温度传感器(DS1820)温度特性实验的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python空气质量分析与预测_干货!如
- 下一篇: 远程读卡器web客户端(nodejs+w