專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

DS18B20+PIC測溫用1602顯示溫度C程序

作者:佚名   來源:mcuc   點擊數(shù):  更新時間:2013年10月31日   【字體:

//熟悉使用單片機運用DS18B20溫度傳感器測試溫度,并用1602顯示屏顯示溫度
//1、第一行顯示:Temperature
//2、第二行顯示:實測溫度值
//**************************************************

//**************************************************
//硬件設(shè)置:
//1、SW2,SW4開關(guān)全部斷開
//2、插上DS18B20溫度傳感器
//**************************************************

//**************************************************
//*****************定義頭文件**********************
//**************************************************
#include<PIC.h>
#include "delay.h"

//**************************************************
//******************定義配置位*********************
//**************************************************
__CONFIG(0x3545);       
//FLASH代碼不保護,RB6和RB7為調(diào)試模式,F(xiàn)LASH不寫保護,數(shù)據(jù)代碼不保護
//RB3為數(shù)字IO口,低電壓復(fù)位使能,上電延時開,看門狗開,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;  //溫度整數(shù)變量,溫度小數(shù)變量
uint temperature;        //轉(zhuǎn)換后的溫度值BCD碼形式
uchar temp[7];           //轉(zhuǎn)換后溫度存放變量

//**************************************************
//******************定義數(shù)據(jù)***********************
//**************************************************
//顯示:  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}; 

//***********************************************
//函 數(shù) 名:delayms(uchar time);
//入口參數(shù):time
//出口參數(shù):無
//函數(shù)作用:毫秒延時
//說    明:
//***********************************************
void delayms(uchar time)
{
  uint i;
  while(time--)
  {
    for(i=93;i>0;i--){;}
  }
}

//***********************************************
//函 數(shù) 名:port_init();
//入口參數(shù):無
//出口參數(shù):無
//函數(shù)作用:端口初始化
//說    明:
//***********************************************
void port_init(void)
{
  ADCON1=0X07;   //設(shè)置RA,RE口為數(shù)字口
  TRISA=0X00;    //設(shè)置RA口為輸出口
  TRISD=0X00;    //設(shè)置RD口為輸出口
  TRISE=0X00;    //設(shè)置RE口為輸出口
  OPTION=0X8F;   //分頻給WDT,分頻比為128
}

//***********************************************
//函 數(shù) 名:lcd_enable();
//入口參數(shù):無
//出口參數(shù):無
//函數(shù)作用:LCD寫使能
//說    明:
//***********************************************
void lcd_enable(void)
{
  RS=0;         //寫命令
  RW=0;         //寫操作
  E=0;          //低電平信號
  delayms(10);  //低電平信號保持
  E=1;          //拉高電平信號
}

//***********************************************
//函 數(shù) 名:lcd_writebyte(uchar data);
//入口參數(shù):data
//出口參數(shù):無
//函數(shù)作用:LCD寫一個字節(jié)數(shù)據(jù)
//說    明:
//***********************************************
void lcd_writebyte(uchar data)
{
  PORTD=data;   //向RD口寫數(shù)據(jù)
  RS=1;         //寫數(shù)據(jù)
  RW=0;         //寫操作
  E=0;          //低電平信號
  delayms(10);  //低電平信號保持
  E=1;          //拉高電平信號
}

//***********************************************
//函 數(shù) 名:lcd_writedata(const uchar *ptt);
//入口參數(shù):*ptt
//出口參數(shù):無
//函數(shù)作用:LCD寫數(shù)據(jù)塊函數(shù)
//說    明:
//***********************************************
void lcd_writedata(const uchar *ptt)
{
  uchar i;
  for(i=0;i<16;i++)         //寫16個字節(jié)數(shù)據(jù)
  {
    lcd_writebyte(ptt);  //查表寫數(shù)據(jù)
  }
}

//***********************************************
//函 數(shù) 名:lcd_init();
//入口參數(shù):無
//出口參數(shù):無
//函數(shù)作用:LCD初始化
//說    明:
//***********************************************
void lcd_init(void)
{
  PORTD=0X01;    //清除顯示
  lcd_enable();
  PORTD=0X38;    //8位2行5*7點陣
  lcd_enable();
  PORTD=0X0e;    //顯示開,光標(biāo)開,閃爍
  lcd_enable();
  PORTD=0X06;    //文字不動,光標(biāo)右移
  lcd_enable();
}

//***********************************************
//函 數(shù) 名:ds18b20_reset();
//入口參數(shù):無
//出口參數(shù):無
//函數(shù)作用:DS18B20復(fù)位
//說    明:
//***********************************************
void ds18b20_reset(void)
{
  uchar x=1;
  while(x)
  { 
    DQ_IO=0;       //設(shè)置RE0為輸出口
    DQ=0;          //RE0輸出低電平
    DelayUs(201);  //延時503us(最短480us低電平信號)
    DQ_IO=1;       //釋放總線,進入接收(設(shè)置RE0為輸入口)
    DelayUs(29);   //延時70us(18b20檢測到上升沿時,等待15-60us)
    if(DQ){x=1;}   //有應(yīng)答信號,跳出
    else {x=0;}    //沒有應(yīng)答信號,繼續(xù)復(fù)位(低電平持續(xù)在60-240us)
    DelayUs(172);  //延時430us
   }
}

//***********************************************
//函 數(shù) 名:ds18b20_writebyte(uchar data);
//入口參數(shù):data
//出口參數(shù):無
//函數(shù)作用:DS18B20寫一個字節(jié)數(shù)據(jù)
//說    明:
//***********************************************
void ds18b20_writebyte(uchar data)
{
  uchar i,temp;
  for(i=8;i>0;i--)      //寫8位數(shù)據(jù)
  {
    temp=data&0x01;     //先寫低位數(shù)據(jù)
    DQ_IO=0;            //設(shè)置RE0為輸出口
    DQ=0;               //RE0輸出低電平
    DelayUs(1);         //延時6us(15us之內(nèi)把數(shù)據(jù)送到總線上)
    if(temp){DQ_IO=1;}  //設(shè)置RE0為輸入口(寫1時序)
    DelayUs(25);        //延時61us(總線采樣時間15-60us)
    DQ_IO=1;            //設(shè)置RE0為輸入口(寫0時序)
    DelayUs(1);         //延時6us(寫第二位時間間隙大于1us)
    data=data>>1;       //右移一位
  }
}

//***********************************************
//函 數(shù) 名:ds18b20_readbyte();
//入口參數(shù):無
//出口參數(shù):無
//函數(shù)作用:DS18B20讀一個字節(jié)數(shù)據(jù)
//說    明:
//***********************************************
unsigned char ds18b20_readbyte(void)
{
  uchar i,data=0;           //讀出溫度
  for(i=8;i>0;i--)          //讀8位數(shù)據(jù)
  {
    data=data>>1;           //數(shù)據(jù)先右移一位
    DQ_IO=0;                //設(shè)置RE0為輸出口
    DQ=0;                   //RE0輸出低電平
    DelayUs(1);             //延時6us(低電平時間大于1us)
    DQ_IO=1;                //拉高總線,產(chǎn)生讀時間間隙(設(shè)置RE0為輸入口)
    DelayUs(1);             //延時6us(從拉低電平開始15us之內(nèi)完成讀位)
    if(DQ){data=data|0x80;} //先讀高位數(shù)據(jù),高位為1
    else  {data=data|0x00;} //高位為0
    DelayUs(25);            //延時61us(從拉低電平開始60-120us之內(nèi)釋放總線)
  }
  return(data);
}

//***********************************************
//函 數(shù) 名:read_ds18b20_data();
//入口參數(shù):無
//出口參數(shù):無
//函數(shù)作用:讀DS18B20測試的溫度數(shù)據(jù)
//說    明:
//***********************************************
void read_ds18b20_data(void)

  DQ_IO=1;                                   //設(shè)置RE0為輸入口
  ds18b20_reset();                           //調(diào)用復(fù)位函數(shù)
  ds18b20_writebyte(0XCC);                   //跳過ROM匹配 
  ds18b20_writebyte(0X44);                   //發(fā)送溫度變換命令
  ds18b20_reset();                           //再次復(fù)位
  ds18b20_writebyte(0XCC);                   //跳過ROM匹配 
  ds18b20_writebyte(0XBE);                   //發(fā)送讀溫度命令 
  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;                 //整數(shù)百位
  temp[1]=(zhengshu/10)%10;                  //整數(shù)十位
  temp[2]=zhengshu%10;                       //整數(shù)個位
  temperature=0;  
  if(xiaoshu&0x80)                           //下面是把小數(shù)部分轉(zhuǎn)換為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
}

//***********************************************
//函 數(shù) 名:lcd_display_temp();
//入口參數(shù):無
//出口參數(shù):無
//函數(shù)作用:LCD顯示測試溫度程序
//說    明:
//***********************************************
void lcd_display_temp(void)
{
  PORTD=0X80;                    //設(shè)置第1行顯示地址
  lcd_enable();
  lcd_writedata(name);           //調(diào)用顯示函數(shù)
  PORTD=0XC0;                    //設(shè)置第2行顯示地址
  lcd_enable();                  //調(diào)用寫使能函數(shù)
  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);
}

//***********************************************
//函 數(shù) 名:main();
//入口參數(shù):無
//出口參數(shù):無
//函數(shù)作用:MAIN函數(shù)
//說    明:
//***********************************************
void main(void)
{
  port_init();           //調(diào)用端口初始化函數(shù)
  lcd_init();            //調(diào)用LCD初始化函數(shù)
  while(1)
  {
    read_ds18b20_data(); //調(diào)用溫度轉(zhuǎn)換函數(shù)
    CLRWDT();            //清看門狗
    lcd_display_temp();  //調(diào)用溫度顯示函數(shù)
  }
}

關(guān)閉窗口

相關(guān)文章