silvanesw 发表于 2009-2-8 16:06:25

记号贴:89C52+1602+DS18B20实现的实时温度显示系统。带C和PROTEUS仿真。 【恢复】

此贴为转载。但是内容是经过验证的。51+18B20实时测温通过。以下为作者的笔记。仿真在PROTEUS7.2版通过了。

(不过此程序只能正确显示0~99度之内的温度。支持最高精度的显示。高于100和小于0度的温度会出错。注释很详细,如果需要很自行更改。)

调试笔记:



1、DS18B20重新启动单总线,然后使用0xbe读取转换的温度值,不能写入0x44(启动转换)命令之后延时750ms接着就读取scratchpad,这样是没有意义的,参见DS18b20 Datasheet中的访问流程图;



 



2、用单片机模拟单总线需要精确的微秒级延时,因此,延时程序的编制太重要不过了;本例程编制中参考了网络原创贴:51单片机 Keil C 延时程序的简单研究(by: InfiniteSpace Studio),具体如下:



/*延时计算式:2 × x+5;Step:2us;*/

extern void Delay_Xus(int8u x)  //x取值1~255;

{ while(--x); }





3、Read time slot中必须对DQ写1后再读,否则,读出来的温度转换值将是不预期的垃圾;





DNS文件+说明+Keil文件ourdev_614607.rar(文件大小:339K) (原文件名:DS18B20.rar) 

silvanesw 发表于 2009-2-8 16:14:59

以下为作者的One-Wire.C 中的代码。单总线的所有控制驱动。



/******************************************************************************/

/**

/** 模 块 名: -------------------One-Wire.C----------------------------------

/**            -----------------DS18B20单总线模块----------------------------*/

/** 功能描述: 

/**

/** 创 建 人: huangtiexiong           日期:2006-11-28   */

/** 修 改 人:                         日期:2006-11-28   */ 

/** 其他说明: 

/******************************************************************************/



#include "Includes.h"                        //文件包含



/*************************************************

    模块级变量申明                 

*************************************************/

static void         OneWire_Rst(void);

static void         OneWire_Init(void);

static void         OneWire_WriteByte(int8u cmd);

static int8u         OneWire_ReadByte(void);

static void         OneWire_Idle(void);





/*************************************************

    子函数定义                  

*************************************************/



/*******************************************************************************

*** 函 数 名: static void OneWire_Init(void)

*** 功能描述: 

*** 全局变量: 

*** 输                入: NO !

*** 输                出: NO !

*** 创 建 人:huangtiexiong                          日期:2006-11-28

*** 修 改 人:                                                                                 日期:2006-11-28

*** 函数说明: 单总线数据传输初始化;

/******************************************************************************/

static void OneWire_Init(void)

{

        DQ = 1;

        NOP();

        DQ = 0;                                                //拉低数据线,准备Reset OneWire Bus;

        Delay_Xus(125);                //延时510us,Reset One-Wire Bus.

        Delay_Xus(125);

        

        DQ = 1;                                                //提升数据线;

        Delay_Xus(15);                //延时35us;

        

        while(DQ)                                        //等待Slave 器件Ack 信号;

        {

                NOP();

                }

        Delay_Xus(60);                //延时125us;        

        DQ = 1;                                                //提升数据线,准备数据传输;

        }

/*******************************************************************************

*** 函 数 名: static void OneWire_Rst(void)

*** 功能描述: 

*** 全局变量: No !

*** 输                入: NO !

*** 输                出: NO !

*** 创 建 人:huangtiexiong                          日期:2006-11-28

*** 修 改 人:                                                                                 日期:2006-11-28

*** 函数说明: 单总线Reset pulse;

/******************************************************************************/

static void OneWire_Rst(void)

{

        DQ = 0;                                                //拉低数据线,准备Reset OneWire Bus;

        Delay_Xus(125);                //延时511us,Reset One-Wire Bus.

        DQ = 0;

        Delay_Xus(125);

        }

/*******************************************************************************

*** 函 数 名: static void OneWire_WriteByte(int8u cmd)

*** 功能描述: 写一个字节;

*** 全局变量: NO !

*** 输                入: cmd:8bit;

*** 输                出: NO !

*** 创 建 人:huangtiexiong                          日期:2006-11-28

*** 修 改 人:                                                                                 日期:2006-11-28

*** 函数说明: cmd主要有Rom操作指令和E2Ram操作指令两种;

/******************************************************************************/

static void OneWire_WriteByte(int8u cmd)

{

        int8u i;

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

        {

                if(cmd & 0x01)                //低位在前;

                        {

                                DQ = 0;                                //结束Recovery time;

                                NOP();

                                NOP();

                                NOP();

                                DQ = 1;                                //发送数据;

                                }

                else

                        {

                                DQ = 0;                                //结束Rec time;

                                NOP();

                                NOP();

                                NOP();                

                                //DQ = 0;                        //发送数据;

                                }

                Delay_Xus(30);                //等待Slave Device采样;

                DQ = 1;                                                //Recovery;

                NOP();                                                //Recovery Time Start;

                cmd>>= 1;

                }

        }

/*******************************************************************************

*** 函 数 名: static int8u OneWire_ReadByte(void)

*** 功能描述: 读取一个字节;

*** 全局变量: NO !

*** 输                入: NO !

*** 输                出: 8bit data;

*** 创 建 人:huangtiexiong                          日期:2006-11-28

*** 修 改 人:                                                                                 日期:2006-11-28

*** 函数说明: 读之前必须首先写1;

/******************************************************************************/

static int8u OneWire_ReadByte(void)

{

        int8u i;

        int8u tmp = 0;

        DQ = 1;                                                        //准备读;

        NOP();

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

        {

                tmp>>= 1;                                //低位先发;

                DQ = 0;                                                //Read init;

                _nop_();                                        //2ms;

                DQ = 1;                                                //必须写1,否则读出来的将是不预期的数据;

                Delay_Xus(2);                        //延时9us;

                _nop_();

                if(DQ)                                                //在12us处读取数据;

                        tmp |= 0x80;

                Delay_Xus(30);                //延时55us;

                DQ = 1;                                                //恢复One Wire Bus;

                NOP();

                }

        return tmp;        

        }

/*******************************************************************************

*** 函 数 名: static void OneWire_Idle(void)

*** 功能描述: 总线空闲模式;

*** 全局变量: NO !

*** 输                入: NO !

*** 输                出: NO !

*** 创 建 人:huangtiexiong                          日期:2006-11-28

*** 修 改 人:                                                                                 日期:2006-11-28

*** 函数说明: 

/******************************************************************************/

static void OneWire_Idle(void)

{

        DQ = 1;

        NOP();

        }

/*******************************************************************************

*** 函 数 名: extern void DS18B20_Init(void)

*** 功能描述: 器件DS18B20初始化;

*** 全局变量: NO !

*** 输                入: NO !

*** 输                出: NO !

*** 创 建 人:huangtiexiong                          日期:2006-11-28

*** 修 改 人:                                                                                 日期:2006-11-28

*** 函数说明: 

/******************************************************************************/

extern void DS18B20_Init(void)

{

        OneWire_Init();

        }

/*******************************************************************************

*** 函 数 名: extern void DS18B20_RomCmd(int8u romCmd)

*** 功能描述: DS18B20Rom操作命令写;

*** 全局变量: NO !

*** 输                入: romCmd;

*** 输                出: NO !

*** 创 建 人:huangtiexiong                          日期:2006-11-28

*** 修 改 人:                                                                                 日期:2006-11-28

*** 函数说明: 0x33:Read Rom; 0x55:Match Rom; 0xcc:Skip rom; 0xf0: Search rom;

                                                        0xec:Alarm Search.

/******************************************************************************/

extern void DS18B20_RomCmd(int8u romCmd)                //仅写了SkipRom例程;

{

        switch(romCmd)

        {

                case 0xcc:                        //Skip Rom command;

                        OneWire_WriteByte(0xcc);

                        break;

                

                default:

                        break;        

                }

        }

/*******************************************************************************

*** 函 数 名: extern void DS18B20_MemCmd(int8u memCmd)

*** 功能描述: DS18B20Memory 操作命令;

*** 全局变量: NO !

*** 输                入: NO !

*** 输                出: NO !

*** 创 建 人:huangtiexiong                          日期:2006-11-28

*** 修 改 人:                                                                                 日期:2006-11-28

*** 函数说明: 仅写了ConvertT(0x44) 和0xBE命令;

                                                        0x44:Convert T; 0xbe:Read Scratch-pad;

/******************************************************************************/

extern void DS18B20_MemCmd(int8u memCmd)                

{

        switch(memCmd)

        {

                case 0x44:                //Start to Convert temperature;

                        OneWire_WriteByte(0x44);

                        NOP();

                        DS18B20_Busy();

                        Delay_Xms(250);                //延时750ms;

                        Delay_Xms(250);

                        Delay_Xms(250);

                        break;

                

                case 0xbe:                //Read scratchpad;

                        OneWire_WriteByte(0xbe);

                        break;

                                

                default:

                        break;        

                }

        }

/*******************************************************************************

*** 函 数 名: extern void DS18B20_ReadDat(int8u len,int8u *buf)

*** 功能描述: 读取DS18B20内部的Scratchpad内容;

*** 全局变量: NO !

*** 输                入: len:将要读取的数据长度;

*** 输                出: buf:数据缓存;

*** 创 建 人:huangtiexiong                          日期:2006-11-28

*** 修 改 人:                                                                                 日期:2006-11-28

*** 函数说明: 

/******************************************************************************/

extern void DS18B20_ReadDat(int8u len,int8u *buf)

{

        int8u i;

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

        {

                buf = OneWire_ReadByte();

                }

        OneWire_Rst();

        OneWire_Idle();        

        }

/*******************************************************************************

*** 函 数 名: extern void DS18B20_Busy(void)

*** 功能描述: 内部模数转换中,忙

*** 全局变量: NO !

*** 输                入: NO !

*** 输                出: NO !

*** 创 建 人:huangtiexiong                          日期:2006-11-28

*** 修 改 人:                                                                                 日期:2006-11-28

*** 函数说明: 

/******************************************************************************/

extern void DS18B20_Busy(void)

{

        OneWire_Idle();

        }





/*******************************************************************************

****                              End Of File

*******************************************************************************/

haoyangwoaini 发表于 2010-2-6 18:06:47

借鉴中

chenli_365 发表于 2010-11-29 16:35:07

学习了,这个对我很重要,感谢楼主了

chenli_365 发表于 2010-11-29 16:44:09

程序写的非常好!赞

flotox 发表于 2013-5-5 15:53:56

MARKMARKMARK

洛乐 发表于 2013-5-6 02:36:04

神人的程序   很好

aidianzio 发表于 2013-5-11 09:43:21

{:victory:}神人的程序啊、、、

1066950103 发表于 2013-6-20 20:11:37

程序写的太好了 , C语言超级好 。 学习了。
页: [1]
查看完整版本: 记号贴:89C52+1602+DS18B20实现的实时温度显示系统。带C和PROTEUS仿真。 【恢复】