|
- //熟悉使用單片機運用DS18B20溫度傳感器測試溫度,并用1602顯示屏顯示溫度
- //1、第一行顯示:Temperature
- //2、第二行顯示:實測溫度值
- //**************************************************
- //**************************************************
- //硬件設置:
- //1、SW2,SW4開關全部斷開
- //2、插上DS18B20溫度傳感器
- //**************************************************
- //**************************************************
- //*****************定義頭文件**********************
- //**************************************************
- #include<PIC.h>
- #include "delay.h"
- //**************************************************
- //******************定義配置位*********************
- //**************************************************
- __CONFIG(0x3545);
- //FLASH代碼不保護,RB6和RB7為調試模式,FLASH不寫保護,數據代碼不保護
- //RB3為數字IO口,低電壓復位使能,上電延時開,看門狗開,4M晶體XT振蕩器
- //**************************************************
- //******************定義常量***********************
- //**************************************************
- #define uchar unsigned char
- #define uint unsigned int
- //**************************************************
- //***************定義DS18B20引腳*******************
- //**************************************************
- #define DQ RE0
- #define DQ_IO TRISE0
- //**************************************************
- //******************定義LCD引腳*********************
- //**************************************************
- #define RS RA1
- #define RW RA2
- #define E RA3
-
- //**************************************************
- //******************定義變量***********************
- //**************************************************
- uchar lowtemp,hightemp; //低8位溫度變量,高8位溫度變量
- uchar zhengshu,xiaoshu; //溫度整數變量,溫度小數變量
- uint temperature; //轉換后的溫度值BCD碼形式
- uchar temp[7]; //轉換后溫度存放變量
- //**************************************************
- //******************定義數據***********************
- //**************************************************
- //顯示: Temperature
- //顯示:WWW.PICAVR.COM
- const uchar name[16]=
- //{0x20,0x20,0x20,0x54,0x65,0x6d,0x70,0x65,0x72,0x61,0x74,0x75,0x72,0x65,0x20,0x20};
- {0x20,0x57,0x57,0x57,0x2E,0x50,0x49,0x43,0x41,0x56,0x52,0x2E,0x43,0x4F,0x4D,0x20};
-
- //***********************************************
- //函 數 名:delayms(uchar time);
- //入口參數:time
- //出口參數:無
- //函數作用:毫秒延時
- //說 明:
- //***********************************************
- void delayms(uchar time)
- {
- uint i;
- while(time--)
- {
- for(i=93;i>0;i--){;}
- }
- }
- //***********************************************
- //函 數 名:port_init();
- //入口參數:無
- //出口參數:無
- //函數作用:端口初始化
- //說 明:
- //***********************************************
- void port_init(void)
- {
- ADCON1=0X07; //設置RA,RE口為數字口
- TRISA=0X00; //設置RA口為輸出口
- TRISD=0X00; //設置RD口為輸出口
- TRISE=0X00; //設置RE口為輸出口
- OPTION=0X8F; //分頻給WDT,分頻比為128
- }
- //***********************************************
- //函 數 名:lcd_enable();
- //入口參數:無
- //出口參數:無
- //函數作用:LCD寫使能
- //說 明:
- //***********************************************
- void lcd_enable(void)
- {
- RS=0; //寫命令
- RW=0; //寫操作
- E=0; //低電平信號
- delayms(10); //低電平信號保持
- E=1; //拉高電平信號
- }
- //***********************************************
- //函 數 名:lcd_writebyte(uchar data);
- //入口參數:data
- //出口參數:無
- //函數作用:LCD寫一個字節數據
- //說 明:
- //***********************************************
- void lcd_writebyte(uchar data)
- {
- PORTD=data; //向RD口寫數據
- RS=1; //寫數據
- RW=0; //寫操作
- E=0; //低電平信號
- delayms(10); //低電平信號保持
- E=1; //拉高電平信號
- }
- //***********************************************
- //函 數 名:lcd_writedata(const uchar *ptt);
- //入口參數:*ptt
- //出口參數:無
- //函數作用:LCD寫數據塊函數
- //說 明:
- //***********************************************
- void lcd_writedata(const uchar *ptt)
- {
- uchar i;
- for(i=0;i<16;i++) //寫16個字節數據
- {
- lcd_writebyte(ptt[i]); //查表寫數據
- }
- }
- //***********************************************
- //函 數 名:lcd_init();
- //入口參數:無
- //出口參數:無
- //函數作用:LCD初始化
- //說 明:
- //***********************************************
- void lcd_init(void)
- {
- PORTD=0X01; //清除顯示
- lcd_enable();
- PORTD=0X38; //8位2行5*7點陣
- lcd_enable();
- PORTD=0X0e; //顯示開,光標開,閃爍
- lcd_enable();
- PORTD=0X06; //文字不動,光標右移
- lcd_enable();
- }
- //***********************************************
- //函 數 名:ds18b20_reset();
- //入口參數:無
- //出口參數:無
- //函數作用:DS18B20復位
- //說 明:
- //***********************************************
- void ds18b20_reset(void)
- {
- uchar x=1;
- while(x)
- {
- DQ_IO=0; //設置RE0為輸出口
- DQ=0; //RE0輸出低電平
- DelayUs(201); //延時503us(最短480us低電平信號)
- DQ_IO=1; //釋放總線,進入接收(設置RE0為輸入口)
- DelayUs(29); //延時70us(18b20檢測到上升沿時,等待15-60us)
- if(DQ){x=1;} //有應答信號,跳出
- else {x=0;} //沒有應答信號,繼續復位(低電平持續在60-240us)
- DelayUs(172); //延時430us
- }
- }
- //***********************************************
- //函 數 名:ds18b20_writebyte(uchar data);
- //入口參數:data
- //出口參數:無
- //函數作用:DS18B20寫一個字節數據
- //說 明:
- //***********************************************
- void ds18b20_writebyte(uchar data)
- {
- uchar i,temp;
- for(i=8;i>0;i--) //寫8位數據
- {
- temp=data&0x01; //先寫低位數據
- DQ_IO=0; //設置RE0為輸出口
- DQ=0; //RE0輸出低電平
- DelayUs(1); //延時6us(15us之內把數據送到總線上)
- if(temp){DQ_IO=1;} //設置RE0為輸入口(寫1時序)
- DelayUs(25); //延時61us(總線采樣時間15-60us)
- DQ_IO=1; //設置RE0為輸入口(寫0時序)
- DelayUs(1); //延時6us(寫第二位時間間隙大于1us)
- data=data>>1; //右移一位
- }
- }
- //***********************************************
- //函 數 名:ds18b20_readbyte();
- //入口參數:無
- //出口參數:無
- //函數作用:DS18B20讀一個字節數據
- //說 明:
- //***********************************************
- unsigned char ds18b20_readbyte(void)
- {
- uchar i,data=0; //讀出溫度
- for(i=8;i>0;i--) //讀8位數據
- {
- data=data>>1; //數據先右移一位
- DQ_IO=0; //設置RE0為輸出口
- DQ=0; //RE0輸出低電平
- DelayUs(1); //延時6us(低電平時間大于1us)
- DQ_IO=1; //拉高總線,產生讀時間間隙(設置RE0為輸入口)
- DelayUs(1); //延時6us(從拉低電平開始15us之內完成讀位)
- if(DQ){data=data|0x80;} //先讀高位數據,高位為1
- else {data=data|0x00;} //高位為0
- DelayUs(25); //延時61us(從拉低電平開始60-120us之內釋放總線)
- }
- return(data);
- }
- //***********************************************
- //函 數 名:read_ds18b20_data();
- //入口參數:無
- //出口參數:無
- //函數作用:讀DS18B20測試的溫度數據
- //說 明:
- //***********************************************
- void read_ds18b20_data(void)
- {
- DQ_IO=1; //設置RE0為輸入口
- ds18b20_reset(); //調用復位函數
- ds18b20_writebyte(0XCC); //跳過ROM匹配
- ds18b20_writebyte(0X44); //發送溫度變換命令
- ds18b20_reset(); //再次復位
- ds18b20_writebyte(0XCC); //跳過ROM匹配
- ds18b20_writebyte(0XBE); //發送讀溫度命令
- lowtemp=ds18b20_readbyte(); //讀出低8位溫度值
- hightemp=ds18b20_readbyte(); //讀出高8位溫度值
- DQ_IO=1; //釋放總線
- zhengshu=((lowtemp>>4)|(hightemp<<4))&0X3F;
- xiaoshu=lowtemp<<4;
- temp[0]=(zhengshu/100)%10; //整數百位
- temp[1]=(zhengshu/10)%10; //整數十位
- temp[2]=zhengshu%10; //整數個位
- temperature=0;
- if(xiaoshu&0x80) //下面是把小數部分轉換為BCD碼形式
- {
- temperature+=5000;
- }
- if(xiaoshu&0x40)
- {
- temperature+=2500;
- }
- if(xiaoshu&0x20)
- {
- temperature+=1250;
- }
- if(xiaoshu&0x10)
- {
- temperature+=625;
- }
- temp[3]=(temperature/1000)%10; //十分位
- temp[4]=(temperature/100)%10; //百分位
- temp[5]=(temperature/10)%10; //千分位
- temp[6]=temperature%10; //萬分位
- DelayUs(1); //延時6us
- }
- //***********************************************
- //函 數 名:lcd_display_temp();
- //入口參數:無
- //出口參數:無
- //函數作用:LCD顯示測試溫度程序
- //說 明:
- //***********************************************
- void lcd_display_temp(void)
- {
- PORTD=0X80; //設置第1行顯示地址
- lcd_enable();
- lcd_writedata(name); //調用顯示函數
- PORTD=0XC0; //設置第2行顯示地址
- lcd_enable(); //調用寫使能函數
- lcd_writebyte(0x20);
- lcd_writebyte(0x20);
- lcd_writebyte(0x20);
- if(temp[0]==0)
- {
- lcd_writebyte(0x20);
- }
- else
- {
- lcd_writebyte(temp[0]+0x30);
- }
- lcd_writebyte(temp[1]+0x30);
- lcd_writebyte(temp[2]+0x30);
- lcd_writebyte(0x2e);
- lcd_writebyte(temp[3]+0x30);
- lcd_writebyte(temp[4]+0x30);
- lcd_writebyte(temp[5]+0x30);
- lcd_writebyte(temp[6]+0x30);
- lcd_writebyte(0x20);
- lcd_writebyte(0x43);
- lcd_writebyte(0x20);
- lcd_writebyte(0x20);
- lcd_writebyte(0x20);
- }
- //***********************************************
- //函 數 名:main();
- //入口參數:無
- //出口參數:無
- //函數作用:MAIN函數
- //說 明:
- //***********************************************
- void main(void)
- {
- port_init(); //調用端口初始化函數
- lcd_init(); //調用LCD初始化函數
- while(1)
- {
- read_ds18b20_data(); //調用溫度轉換函數
- CLRWDT(); //清看門狗
- lcd_display_temp(); //調用溫度顯示函數
- }
- }
復制代碼
|
|