分享

我修改的18b20驱动

 昵称7658894 2011-09-06
#include"reg52.h"
#include"intrins.h" 
#define unchar unsigned char
#define unint unsigned int
sbit    LS138A=P2^2;       //管脚定义
sbit    LS138B=P2^3;
sbit    LS138C=P2^4;
unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
unsigned long LedOut[4];
unsigned int temple;
void delay2ms(void)   //误差 0us
{
    unsigned char a,b;
    for(b=4;b>0;b--)
        for(a=248;a>0;a--);
    _nop_();  //if Keil,require use intrins.h
}
 

sbit DQ=P3^7;
//DS18B20部分函数变量
unchar tempL,tempH;
unint tmp;
void reset();
void writechar(unchar dat);
unint readchar();
unint readtemperature();
void delay(unint t);
//液晶部分函数和变量
void delay1();
unint tt;
void wrcmd(unchar cmd);
void wrdata(unchar date);
void display();
void lcdchus();
void time(unint t);
unchar temp2[]={"temperature:"};
unchar temp3[]={"000.0"};
//数码管部分
//sbit sda=P0^2;
//sbit scl=P0^3;
//sbit inter=P3^2;
//unint n;
//void shift();
//unchar code  table[]={0x88};
/******************************************************
                写DS18B20开始 
*******************************************************/
/********************************
   延时子函数
********************************/
void delay(unint t)
{
 unint n;
 n=0;
 while(n<t)
 {
   n++;
 }
}
/********************************
 DS18B20复位函数
********************************/
void reset()
{  
 DQ=1; //DQ先置高
 delay(8); //延时
 DQ=0; //发送复位脉冲
 delay(85); //延时(>480us)
 DQ=1; //拉高数据线
 delay(14); //等待(15~60us)这里是等待DS18B20做出回应,如果回应DQ将变低,
 //MCU是在DQ拉高后开始监视DQ的值的。
}
/********************************
 DS18B20写一个字节函数
********************************/
void writechar(unchar dat)
{
   unint i;
   for(i=8;i>0;i--)
   {
  DQ=0; //先将DQ拉低,我们这里先不延时15us先,在下面的 delay(5)一起延了,
         //因为时序图它是一直保持低电平的
  DQ=dat&0x01;//去数据的最低位,应为DS18B20是从低到高读的
  delay(5);//延时在60-120us之间
  DQ=1; //将DQ拉高
  dat>>=1;//右移一位
    }
  delay(4);//这里延时1us以上
}
/********************************
  DS18B20读一个字节函数
********************************/
unint readchar()
{
 unchar i,dat=0;//这里要付初值
 for (i=8;i>0;i--)
 {
  DQ=1;  //DQ稍微拉高,这不可有可无
  delay(1);//延时小会,这里延时不严格
  DQ=0;  //按照时序图,将DQ拉低,先不延时,在下面delay(4)在一起延!
  dat>>=1;//右移一位
  DQ=1; //释放一下总线,等待检查DQ值!
  if(DQ)//当DQ为1是执行下面,如果DQ为0,值不变。你们想一下。。
    dat=dat|0x80;//把低位先放在高位,然后右移8次,高位的数据就移到了低位,因为我们是先写低位的!
    delay(4);//延时60-120us吧。。
     }
return(dat);//返回dat值
}
/********************************
 DS18B20读温度程序
********************************/
unint readtemperature()
{
 unint temperature;
 reset(); //初始化
 writechar(0xcc); //写SKIP  ROM(跳过检查ROM序列,因为我们一般只有一个DS18B20!)
 writechar(0x44); //写启动温度转换
 delay(125); //转换需要一点时间,延时大一点,应该大于500us吧
 reset(); //初始化
 writechar(0xcc); //写SKIP  ROM(跳过检查ROM序列,因为我们一般只有一个DS18B20!)
 writechar(0xbe); //读温度寄存器RAM(头两个值分别为温度的低位和高位)
 tempL=readchar(); //读出温度的低位LSB
 tempH=readchar(); //读出温度的高位MSB
 //温度转换,把高低位做相应的运算转化为实际温度
 temperature=((tempH*256)+tempL)*0.0625*10+0.5;//tempH*256的意思是tempH向左移8位
 delay(200);//两次间隔转换的间隔要延时一下
 return(temperature);
}
 
void display(void)
{
  unsigned char i=0;
 unsigned char A, B ,C;
 A= temple/100;
 B= temple%100/10;
 C= temple%10;
 
LedOut[0]= Disp_Tab[A];
LedOut[1]= Disp_Tab[B];
LedOut[2]= Disp_Tab[C];    

for(i=0;i<4;i++)
{
  P0 = LedOut[i] ;
             
  switch(i)      
         {       
   case 0:LS138A=0; LS138B=0; LS138C=0; break;        
            case 1:LS138A=1; LS138B=0; LS138C=0; break;              
            case 2:LS138A=0; LS138B=1; LS138C=0; break;
            case 3:LS138A=1; LS138B=1; LS138C=0; break;
         }
  
  delay2ms();
 }
 
  }
void main(void)
{
 while(1)
 {
  unsigned char i;
  i=0;
  temple=readtemperature() ;
 for(i=0;i<200;i++)
 {
  display();
 }
}}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多