Philips P89LPC917单片机对温度芯片DS1820的取温度笔记

原创 2006年06月19日 13:11:00

硬件环境:  P89LPC917, DS1820温度芯片, VDD=3.3V, 调试串口;
软件环境:  Keil uVision2, 串口通讯控制器(用来接收串口数据)

过程:
看了资料, 其有着许多C51单片机操作DS1820的实例,但是其晶振频率都是参照标准的51芯片的,为11.059MHz. 而P89LPC917的晶振是7372800Hz.由于单总线对时序十分的严谨,而且十分的短暂,所以其延时都是用的循环代码来延时的,这关键就是在7372800Hz晶振下的延时程序应该如何做?

看书了解了什么时钟周期,机器周期,指令周期以后打算算出一个精确的延时程序来,可是偶用C语言来写的,这实在是不好算. 最后,偶打算用示波器来测量延时的时间. 一番折腾后偶得到了下面的结论:

延时代码为:
// DELAY - with an 7.3728MHz crystal
// Calling the routine takes about 4μs, and then
// each count takes another 3.2μs
void delay( uint16 us )
{
    volatile uint16 s;
    for ( s = 0; s < us; s++ );
}
结论:
调用一次循环函数所用的时间  4us
没增加一次循环增加的时间    3.2us
一条赋值代码所需要的时间    280ns

之后参照其数据手册,严格按照其读写的时序来操作,最终正确取到了温度值(请注意,其温度是以0.5度为递增的,取道的值转换为十进制以后要除以2才是真正的温度值)

现把代码公布于下:
 /*
*********************************************************************************************************
*                                           ######有限公司
*                                             技术研发部
*
*                                  (c) Copyright 2005-2006, kmajian
*                                        All Rights Reserved
*
*                                  通过单总线协议从DS1820获取温度程序
*
* File : GETTMP.H
* By   : kmajian
* Date : 2006-5-15
*********************************************************************************************************
*/
#include "config.h"

sbit DQ = P0^1;

void GetTempInit( void )
{
    P0M1 = 0x00;                        // 将P0.1设置为准双向口
    P0M2 = 0x00;
}

// DELAY - with an 7.3728MHz crystal
// Calling the routine takes about 4μs, and then
// each count takes another 3.2μs
void delay( uint16 us )
{
    volatile uint16 s;
    for ( s = 0; s < us; s++ );
}
// 复位
uint8 ow_reset( void )
{
    unsigned char presence;
    DQ = 0;                               // pull DQ line low
    delay( 141 );                          // leave it low for 480μs
    DQ = 1;                               // allow line to return high
    delay( 14 );                           // wait for presence
    presence = DQ;                        // get presence signal
    delay( 110 );                          // wait for end of timeslot
    return( presence );                   // presence signal returned
}                                         // presence = 0, no part = 1

// 读位
uint8 read_bit( void )
{
    DQ = 0;                               // pull DQ low to start timeslot
    DQ = 0;                     
    DQ = 0;
    DQ = 0;
    DQ = 1;                               // then return high
    delay( 3 );                           // delay 15μs from start of timeslot
    return( DQ );                         // return value of DQ line
}

// 写位
void write_bit( int8 bitval )
{
    DQ = 0;                               // pull DQ low to start timeslot
    DQ = 0;                               // 至少保持1us
    DQ = 0;
    DQ = 0;
    if( bitval == 1 )
     DQ = 1;                             // return DQ high if write 1
    delay( 18 );                         // hold value for remainder of timeslot,60us
    DQ = 1;
}                                        

// 读字节
uint8 read_byte( void )
{
    uint8 i;
    uint8 value = 0;
    for ( i = 0; i < 8; i++ )
    {
        if( read_bit() )
      value |= 0x01<<i;                  // reads byte in, one byte at a time and then
                                         // shifts it left
        delay( 18 );                     // wait for rest of timeslot
    }
    return( value );
}

// 写字节
void write_byte( int8 val)
{
    uint8 i;
    uint8 temp;
    for (i = 0; i < 8; i++)             // writes byte, one bit at a time
    {
        temp = val>>i;                  // shifts val right ‘i’ spaces
        temp &= 0x01;                   // copy that bit to temp
        write_bit( temp );              // write bit in temp into
    }
    delay( 18 );
}

// 读取温度
uint8 GetTmp( uint8 *sym )
{
    uint8 val1 = 0, val2 = 0;

    ow_reset();                        // 复位
    write_byte( 0xCC );                // 跳过 ROM 命令
    write_byte( 0x44 );                // Convert T 命令
    TDelay( 100 );                     // 延时一秒, 转换需要足够的时间
    ow_reset();                        // 复位
    write_byte( 0xCC );                // 跳过 ROM 命令
    write_byte( 0xBE );                // 发送读取命令
    val1 = read_byte();                // 读取低字节
    val2 = read_byte();                // 读取高字节
    if( val2 > 0 )                     // 温度为负值则做处理
    {
        *sym = 1;                      // 标示为负数
        val1 = ~val1 + 1;              // 取其补码
    }
    else
    {
        *sym = 0;
    }

    return val1;
}

/*                                                
**********************************************************************************************************
*                                             END 
*********************************************************************************************************
*/

温度和芯片供电电压影响芯片的速度和性能

除了工艺对芯片性能有影响外,外界环境条件如温度和芯片供电电压也会影响芯片的速度和性能。 1)、温度对数字IC芯片阈值电压Vt是有影响的,温度升高引起Vt下降。阈值电压Vt下降使芯片速度加快,但通常温...
  • xavi_siege
  • xavi_siege
  • 2013年04月11日 09:15
  • 2353

STM32芯片内部温度传感器

1、STM32的内部温度传感器 STM32内部温度传感器与ADC的通道16相连,与ADC配合使用实现温度测量。测量范围–40~125℃,精度 ± 1.5℃ 操作流程: 1)、设置ADC相关参数 AD...
  • baoke485800
  • baoke485800
  • 2015年08月13日 20:06
  • 2127

单片机利用串口通信传送温度

/********该程序主要是利用DS18B20采集温度,然后通过数码管显示温度*************/ /*当程序收到上位机发送的命令之后,该程序会将当时的温度值通过串口发送给上位机*/ #...
  • u011314012
  • u011314012
  • 2015年12月22日 14:22
  • 1643

【单片机】时钟及温度的显示

回头看我所写的文章,基本都是软件方面的,是个典型的“欺软怕硬”的人。然而,在最开始的时候,我学习的是硬件。在前面文章《我的2013–一起从心开始》一文中写道,我在大一暑假的时候开始了单片机的学习,在大...
  • tengweitw
  • tengweitw
  • 2015年05月21日 20:25
  • 3612

DS1820温度测量程序

 #include #include #include #include #define uchar unsigned char#define uint unsigned int sbit P3_5=...
  • zhangxinchunleo
  • zhangxinchunleo
  • 2008年09月07日 18:55
  • 573

STM32芯片温度的测量

转自:http://blog.ednchina.com/cairang45/252356/message.aspx ================================= ADC ===...
  • u011717322
  • u011717322
  • 2013年08月23日 10:10
  • 1253

IC之常见的表示温度级别的后缀举例

一般常见的IC温度级别用C(商业级)和I(工业级)来表示,通常在IC的后缀中给出。下面以美信的MAX696CWE为例说明(不同的厂牌和不同类型的芯片表示的方法也不一样,在此只做参考): MAX696...
  • kingjin88
  • kingjin88
  • 2013年05月15日 13:57
  • 1505

STC单片机测8路NTC测温度

1.    单片机型号:STC15F2K32S2,NTC电阻,内部自带ADC检测ADC, 2.    怎么样把ADC值转为温度是最容易让大家不知从何下手,有查表等思路,但是我自己分析的是不是查表,查表...
  • liurenfu2017
  • liurenfu2017
  • 2017年05月02日 23:57
  • 1198

基于stc15芯片的温度传感器DS18B20的使用

基于stc15芯片的温度传感器DS18B20的使用
  • qq_24282081
  • qq_24282081
  • 2017年11月01日 09:16
  • 249

CC2538之TinyOS例程实验:5-Adc_Temp片内温度读取实验 TinyOS如何直接使用C文件

使用过CC2530的朋友肯定对TI的片内温度不陌生;下面带来2538的片内温度读取;先看实验结果: 代码部分:选择使用TinyOS来实现 此处的实验是向大家展示如何TinyOS如何直接使用C(...
  • mc158185
  • mc158185
  • 2015年12月30日 09:59
  • 1410
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Philips P89LPC917单片机对温度芯片DS1820的取温度笔记
举报原因:
原因补充:

(最多只允许输入30个字)