找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7538|回复: 6
收起左侧

DS18B20的使用程序PIC单片机

[复制链接]
ID:75926 发表于 2015-4-3 01:34 | 显示全部楼层 |阅读模式
#include<pic.h>
__CONFIG(0x1832);        
//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡

#define  uch unsigned char                     //给unsigned char起别名 uch
# define DQ RA2                                //定义18B20数据端口
# define DQ_DIR TRISA2                         //定义18B20D口方向寄存器
# define DQ_HIGH() DQ_DIR =1                   //设置数据口为输入
# define DQ_LOW() DQ = 0; DQ_DIR = 0           //设置数据口为输出
unsigned char  TLV=0 ;                        //采集到的温度高8位
unsigned char  THV=0;                         //采集到的温度低8位
unsigned char TZ=0;                           //转换后的温度值整数部分
unsigned char TX=0;                           //转换后的温度值小数部分
unsigned int wd;                              //转换后的温度值BCD码形式
unsigned char shi;                             //整数十位
unsigned char ge;                              //整数个位
unsigned char shifen;                          //十分位
unsigned char baifen;                          //百分位
unsigned char qianfen;                         //千分位
unsigned char wanfen;                          //万分位
unsigned char table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//0-9的显示代码
//------------------------------------------------
//延时函数
void delay(char x,char y)
{
  char z;
  do{
      z=y;
      do{;}while(--z);
     }while(--x);
}
//其指令时间为:7+(3*(Y-1)+7)*(X-1)如果再加上函数调用的call 指令、页面设定、传递参数花掉的7 个指令。
//则是:14+(3*(Y-1)+7)*(X-1)。
//--------------------------------------------------
//结果显示函数
void display()
{
TRISA=0X00;                            //设置A口全为输出
PORTD=table[shi];                      //显示整数十位
PORTA=0x1f;
delay(10,70);
PORTD=table[ge]&0X7F;                  //显示整数个位,并点亮小数点
PORTA=0x2f;
delay(10,70);
PORTD=table[shifen];                   //显示小数十分位
PORTA=0x37;
delay(10,70);
PORTD=table[baifen];                   //显示小数百分位
PORTA=0x3b;
delay(10,70);
PORTD=table[qianfen];                  //显示小数千分位
PORTA=0x3d;
delay(10,70);
PORTD=table[wanfen];                   //显示小数万分位
PORTA=0x3e;
delay(10,70);
}
//------------------------------------------------
//系统初始化函数
void init()
{
  ADCON1=0X07;                                //设置A口为普通数字口
  TRISA=0X00;                                 //设置A口方向为输出
  TRISD=0X00;                                 //设置D口方向为输出
}
//-----------------------------------------------
//复位DS18B20函数
reset(void)
{
  char presence=1;
  while(presence)
  {
    DQ_LOW() ;                                //主机拉至低电平
    delay(2,70);                              //延时503us
    DQ_HIGH();                                //释放总线等电阻拉高总线,并保持15~60us
    delay(2,8);                               //延时70us
    if(DQ==1) presence=1;                     //没有接收到应答信号,继续复位
    else presence=0;                          //接收到应答信号
    delay(2,60);                              //延时430us
   }
  }
//-----------------------------------------------
//写18b20写字节函数
void write_byte(uch val)
{
uch i;
uch temp;
for(i=8;i>0;i--)
{
   temp=val&0x01;                            //最低位移出
   DQ_LOW();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();                                    //从高拉至低电平,产生写时间隙
   if(temp==1)  DQ_HIGH();                   //如果写1,拉高电平
   delay(2,7);                               //延时63us
   DQ_HIGH();
   NOP();
   NOP();
   val=val>>1;                               //右移一位
  }
}
//------------------------------------------------
//18b20读字节函数
uch read_byte(void)
{
uch i;
uch value=0;                                //读出温度
static bit j;
for(i=8;i>0;i--)
{
   value>>=1;
   DQ_LOW();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();                                   //6us
   DQ_HIGH();                               //拉至高电平
   NOP();
   NOP();
   NOP();  
   NOP();
   NOP();                                  //4us
   j=DQ;
   if(j) value|=0x80;
   delay(2,7);                             //63us
  }
  return(value);
}
//-------------------------------------------------
//启动温度转换函数
void get_temp()
{
int i;
DQ_HIGH();
reset();                                 //复位等待从机应答
write_byte(0XCC);                        //忽略ROM匹配
write_byte(0X44);                        //发送温度转化命令  
for(i=20;i>0;i--)
    {
        
        display();                       //调用多次显示函数,确保温度转换完成所需要的时间
    }
reset();                                 //再次复位,等待从机应答
write_byte(0XCC);                        //忽略ROM匹配
write_byte(0XBE);                        //发送读温度命令
TLV=read_byte();                         //读出温度低8
THV=read_byte();                         //读出温度高8位
DQ_HIGH();                               //释放总线
TZ=(TLV>>4)|(THV<<4)&0X3f;               //温度整数部分
TX=TLV<<4;                               //温度小数部分
if(TZ>100) TZ/100;                       //不显示百位
ge=TZ%10;//个位                          //整数部分个位
shi=TZ/10;//十位                         //整数十位
wd=0;  
if (TX & 0x80) wd=wd+5000;
if (TX & 0x40) wd=wd+2500;
if (TX & 0x20) wd=wd+1250;
if (TX & 0x10) wd=wd+625;                //以上4条指令把小数部分转换为BCD码形式            
shifen=wd/1000;                          //十分位                    
baifen=(wd%1000)/100;                    //百分位
qianfen=(wd%100)/10;                     //千分位
wanfen=wd%10;                            //万分位
NOP();
}
//--------------------------------------------------
//猪函数
void main()
{
   init();                              //调用系统初始化函数
   while(1)
     {
       get_temp();                  //调用温度转换函数
       display();                       //调用结果显示函数
     }
}                                                                                                                    
回复

使用道具 举报

ID:113236 发表于 2016-4-20 16:57 | 显示全部楼层
好东西,值得借鉴
回复

使用道具 举报

ID:59151 发表于 2016-6-7 10:25 | 显示全部楼层
很好的资料,谢谢分享
回复

使用道具 举报

ID:130195 发表于 2016-7-12 16:48 | 显示全部楼层
111123
回复

使用道具 举报

ID:129430 发表于 2016-7-13 16:01 | 显示全部楼层
不可以用。。
回复

使用道具 举报

ID:129162 发表于 2016-7-20 15:18 | 显示全部楼层
我就是写不出来。
回复

使用道具 举报

ID:138119 发表于 2019-7-12 15:38 | 显示全部楼层
时序不对
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表