franksunny的个人技术空间
获得人生中的成功需要的专注与坚持不懈多过天才与机会。 ——C.W. Wendte

 

DS18B20驱动

——第一次写驱动函数

由于项目中需要用MSP430F1232访问DS18B20单总线温度传感器,在网上搜集了些资料,几乎全都是代码而且都说100%能用的,但是我实际用起来感觉头痛,怎么用都不行,没办法只好回过头来看dataSheet,不过写得不够详细,或许是我第一次写这种东西的缘故吧,连个时序、时钟周期、机器周期和指令周期都没清楚的情况下,苦苦折腾了四天,下面就是我的成果了。

由于个人的亲身经历,觉得给出代码真的没什么意思,所以先写出三个驱动函数的思路。接着给出了三个程序文件,仅供大家参考,如果有高人看到我的驱动函数思路,有什么总结的不对的地方话还望指点,程序代码就不用看了,我已经执行过可以用。()

 

//////////////////////////////////////////////////////////////////////////

//---------------------------驱动函数思路-------------------------------

//其中的DQ就是MCUDS18B20TDQ脚的I/O

//DQ拉低即该I/O口置0,反之拉高就是置1

//////////////////////////////////////////////////////////////////////////

//初始化函数

{

       //DQ转为输出

       //DQ拉低

       //延时480900us

       //DQ拉高

       //延时90120us(如果延时低于90us将不能正常工作,如果延时大于120us下面读到的位很可能为高,但是不影响正常工作)

       //DQ转为输入

       //DQ

       //判断是否初始化成功(如果读到低电平则成功)

       //如果成功则将DQ拉高

}

 

//读字节函数

{

       for()//循环八次

       {

              //字节右移一位

              //DQ转为输出

              //DQ拉低

              //延时1us 如果下面DQ转为输入指令已经可以花去1us以上则不用延时

              //DQ输入

 

              if()//DQ位为高

                     //字节最高位置1

              else

                     //字节最高位置0

             

              //延时10us(如果单个位读操作已经花去60us那么不用延时,如果没有超过必须加延时使得下一步读操作在此次读操作的60us以后)

       }

}

 

//写字节函数

{

       //DQ输出

       for()//循环八次

       {

              //DQ拉低

 

              if()//如果当前要写的字节为1

                     //DQ拉高

              else

                     //DQ拉低

 

              //字节移位

              //延时60us(如果以上操作能确保使得高低电平已经保持60us以上,则不用延时)

              //DQ拉高(这里是为下一步操作准备的)

       }

}

 

 

//////////////////////////////////////////////////////////////////////////

//--------------------------头文件---------------------------------------

//////////////////////////////////////////////////////////////////////////

#ifndef     __DS18B20_H

#define     __DS18B20_H

//本人使用中,DS18B20TDQ脚接单片机的P3.0

#define DQ1 P3OUT |= BIT0

#define DQ0 P3OUT &=~ BIT0

#define DQIN P3DIR &= ~BIT0

#define DQOUT P3DIR |= BIT0

 

void delay(long i);

unsigned char Init_DS18B20(void);

unsigned char ReadOneChar(void);

void WriteOneChar(unsigned char dat);

float ReadTemperature(void);

 

 

 

#endif      /*  __DS18B20_H */

//////////////////////////////////////////////////////////////////////////

//-------------------------实现文件--------------------------------------

//////////////////////////////////////////////////////////////////////////

#include"ds18b20.h"

#include<io430x12x2.h>

#include<in430.h>

 

float Temper=0.0;

unsigned int temperature = 0;

 

//直接延时(本人采用内部DCO1M晶振作为MCLK

//输入:延时比例:i,总延时为:5.7 * i + 23us

//返回:

void delay(long i)

{

              for(;i >= 0; i--)

              {

                            _NOP();

              }

}

 

//ds18b20初始化函数

//输入:

//返回:0表示初始化失败,1表示初始化成功

unsigned char Init_DS18B20(void)

{

       unsigned char x=0;

       DQOUT;

       DQ0;

       delay(100);//延时500us

       DQ1;

       delay(13);//延时90us

       DQIN;

       x = P3IN & BIT0;

       if(x)

       {

                     return 0;

       }

       else

       {

                     DQ1;

                     return 1;

       }

}

 

//读一个字节

//输入:

//返回:根据一线制器件协议获得的一个字节

unsigned char ReadOneChar(void)

{

              unsigned char i = 0;

              unsigned char temp =0;

              for(i=0;i<8;i++)

              {

                            temp=temp >> 1;

                            DQOUT;                     

                            DQ0;

                            DQIN;

                            if((P3IN&BIT0)==0)

                            {

                                          temp=temp&0x7F;

                            }

                            else

                            {

                                          temp=temp|0x80;

                            }                         

                            delay(500);//延时40us                       

              }

              return temp;

}

 

//写一个字节

//输入:需要发送的一个字节:dat

//返回:

void WriteOneChar(unsigned char dat)

{

              unsigned char i = 0;

              DQOUT;

              for(i=0;i<8;i++)

              {

                            DQ0;

                            if((dat&0X01)==0X01)

                            {

                                          DQ1;                                               

                            }

                            else

                            {

                                          DQ0;                                        

                            }

                            dat=dat>>1;

                            delay(7);

                            DQ1;

              }

}

 

//读取温度,0.0625的分辨率进行的转换,如果温度的两个字节为则FF返回100.0,如出错返回-100.0

//输入:

//返回:温度的浮点数

float ReadTemperature(void)

{

       unsigned char temp_low = 0;

       unsigned char temp_high = 0;      

      

       if(Init_DS18B20())

       {

                     WriteOneChar(0xcc);//单片跳过rom编码

                     WriteOneChar(0x44);//开启温度变换

                    

                     delay(180000);//延时1S以上,供温度转换,其它位数转换时间少,具体看datasheet

                    

                     Init_DS18B20();

                     WriteOneChar(0xcc);//单片跳过rom编码

                     WriteOneChar(0xBE);//读暂存存储器 

                     temp_low = ReadOneChar(); //读低位

                     temp_high = ReadOneChar(); //读高位

                    

                     if((temp_high == 0xFF) && (temp_low == 0xFF))

                     {

                                   return(100.0);

                     }

                     else

                     {

                                   temperature = (temp_high & 0x0F);

                                   temperature <<= 8;

                                   temperature |= temp_low;

                                   Temper = temperature * 0.0625;

                                   return(Temper);

                     }

       }

       else

       {

                     return(-100.0);

       }

}

 

 

//////////////////////////////////////////////////////////////////////////

//-------------------------驱动实现文件----------------------------------

//////////////////////////////////////////////////////////////////////////

#include "io430.h"

#include<io430x12x2.h>

#include "ds18b20.h"

 

float temp;

 

int main( void )

{

       // Stop watchdog timer to prevent time out reset

       WDTCTL = WDTPW + WDTHOLD;

       DCOCTL=DCO0+DCO1+DCO2;

       BCSCTL1=RSEL2;

       BCSCTL2 = DIVS_0 + DIVM_0;

       while(1)

       {

              //由于没有接任何显示设备,所以用户只能中断查看当前采得温度是否正确

              temp = ReadTemperature();

       }

  return 0;

}

 

posted on 2007-06-07 20:55 frank.sunny 阅读(1488) 评论(1)  编辑 收藏 引用 所属分类: 硬件实践小结

FeedBack:
# re: DS18B20驱动
2007-08-18 12:07 | 熊一霖
DQOUT;
DQ0;
顺序应倒过来;
否则 PxOUTx 中不确定的内容将在执行DQOUT时就已经送到引脚上;
改为:
DQ0;
DQOUT;
后;
PxOUTx 中确定“0”将在执行DQOUT时送到引脚上;  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航:   博客园   博客园最新博文   博问   管理



常用链接

留言簿(13)

随笔分类

个人其它博客

基础知识链接

最新评论

阅读排行榜

评论排行榜