专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

DS18B20+PIC测温用1602显示温度C程序

作者:佚名   来源:mcuc   点击数:  更新时间:2013年10月31日   【字体:

//熟悉使用单片机运用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);  //查表写数据
  }
}

//***********************************************
//函 数 名: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();  //调用温度显示函数
  }
}

关闭窗口

相关文章