第五部分 外设篇 - 基础实验 第1章CC2530温度传感器DS18B20

1 理论分析

1.1概述

DS18B20 是 DALLAS 最新单线数字温度传感器,新的”一线器件”体积更小、适用电压更宽、更经济。Dallas 半导体公司的数字化温度传感器 DS1820 是世界上第一片支持 “一线总线”接口的温度传感器。一线总线独特而且经济的特点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。DS18B20、 DS1822 “一线总线”数字化温度传感器同 DS1820 一样,DS18B20 也支持”一线总线”接口,测量温度范围为 -55°C~+125°C,在-10~+85°C 范围内,精度为±0.5°C。DS1822 的精度较差为± 2°C 。现场温度直接以”一线总线”的数字方式传输,大大提高了系统的抗干扰性。适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。与前一代产品不同,新的产品支持 3V~5.5V 的电压范围,使系统设计更灵活、方便。而且新一代产品更便宜,体积更小。 DS18B20、 DS1822 的特性 DS18B20 可以程序设定 9~12 位的分辨率,精度为±0.5°C。可选更小的封装方式,更宽的电压适用范围。分辨率设定,及用户设定的报警温度存储在 EEPROM 中,掉电后依然保存。DS18B20 的性能是新一代产品中最好的。性能价格比也非常出色。 DS1822 与 DS18B20 软件兼容,是 DS18B20的简化版本。省略了存储用户定义报警温度、分辨率参数的 EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。继”一线总线”的早期产品后,DS1820 开辟了温度传感器技术的新概念。DS18B20 和 DS1822 使电压、特性及封装有更多的选择,让我们可以构建适合自己的经济的测温系统。

1.2性能

(1) 可用数据线供电,电压范围:3.0~5.5V;
(2) 测温范围:-55~+125℃,在-10~+85℃时精度为±0.5℃;
(3) 可编程的分辨率为 9~12 位,对应的可分辨温度分别为 0.5℃、0.25℃、0.125℃和 0.0625℃;
(4) 12 位分辨率时最多在 750ms 内把温度值转换为数字;
(5) 负压特性:电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。

1.3外形和内部结构

DS18B20 内部结构主要由四部分组成:64 位光刻 ROM、温度传感器、非挥发的温度报警触发器 TH 和 TL、配置寄存器。DS18B20 的管脚排列如图所示。 ,内部结构图如下图所示。

这里写图片描述

图1 DS18B20 管脚图

这里写图片描述

图2 DS18B20 内部结构图

1.4 CC2530 读取 DS18B20 温度值

经过单线接口访问DS18B20的协议如下:
初始化;
ROM操作命令;
存储器操作命令;
处理/数据;

这里写图片描述

图3 CC2530 读取 DS18B20 温度值流程图

2 实验详解

2.1实验目的

Zigbee 很容易建立起无线传感网,低成本是我们研究zigbee 的目的。

2.2实验设备

硬件:PC 机一台 ;ZB2530(底板、核心板、仿真器、USB 线、OLCD) 一套 DS18B20 一个
软件:2000/XP/win7 系统,IAR 8.20 集成开发环境、串口助手

2.3实验相关电路图

这里写图片描述

图 4

2.4实验分析

实验中用到了串口和P0_7,相关寄存器如下:

表1 时钟控制命令

这里写图片描述
这里写图片描述
这里写图片描述

表2 时钟控制状态

这里写图片描述
这里写图片描述

表3 外设控制

这里写图片描述

表4端口2方向和端口0外设优先级模式


这里写图片描述
这里写图片描述

表5端口0功能选择


这里写图片描述

表6 USART 0控制和状态


这里写图片描述
这里写图片描述

表7 USART 0 UART控制


这里写图片描述
这里写图片描述

表8 USART 0通用控制


这里写图片描述

表9 USART 0接收/传送数据缓存

这里写图片描述

表10 USART 0 波特率控制

这里写图片描述

表11中断标志

这里写图片描述

表12 中断使能

这里写图片描述

表13 定时器1的控制和状态

这里写图片描述

表14 定时器1的状态

T1STAT(0xAF)-定时器1状态

名称 复位 R/W 描述
7:6 - 0 R0 保留
5 OVFIF 0 R/W0 定时器1计数器溢出中断标志。当计数器在自由运行或按模计数模式下达到最终计数值时设置,当在正/倒计数模式下达到零时倒计数。写1没有影响。
4 CH4IF 0 R/W0 定时器1通道4中断标志,当通道4中断条件发生时设置,写1没有影响。
3 CH3IF 0 R/W0 定时器1通道3中断标志,当通道3中断条件发生时设置,写1没有影响。
2 CH2IF 0 R/W0 定时器1通道2中断标志,当通道2中断条件发生时设置,写1没有影响。
1 CH1IF 0 R/W0 定时器1通道1中断标志,当通道1中断条件发生时设置,写1没有影响。
0 CH0IF 0 R/W0 定时器1通道0中断标志,当通道0中断条件发生时设置,写1没有影响。

表15 定时器中断标志

这里写图片描述

表16 串口寄存器

U0DBUF USART 0接收/发送数据缓存

2.5参考源码 (部分代码)

/**Includes*********************************************************************/
#include <iocc2530.h>
#include <stdio.h>
#include <string.h>
#include "ds18b20.h"  
#include "LCD.h"

/**宏定义***********************************************************************/
//定义数据类型
typedef unsigned char uchar;
typedef unsigned int  uint;
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr)[0])
#define FLOAT_TEMP      1          //输出更高精度时打开此注释

/**函数声明*********************************************************************/
void InitCLK();
void InitUart();
void UartSendString(char *Data, int len);

/**全局变量*********************************************************************/
extern void Delay_ms(unsigned int k);//外部函数ms的声明


/**
  * @brief     主函数
  * @param     None
  * @retval    None
  */
void main()
{  
  char str[9]="DS18B20:"; 
  char strTemp[30];
  float fTemp;

  InitCLK();                      //设置系统时钟源
  InitUart();                     //串口初始化
  P0SEL &= 0x7f;                  //DS18B20的io口初始化

  LCD_Init();                 //oled 初始化  
  LCD_CLS();                  //屏全亮 
  LCD_welcome();

  while(1)
  {        
    memset(strTemp, 0, ARRAY_SIZE(strTemp)); 

    //厂家提供的程序温度值不带小数,Ds18B20本身是支持1位小数位的,修改后使其支持,精度更高        
#if defined(FLOAT_TEMP)                 
    fTemp = floatReadDs18B20();       //温度读取函数 带1位小数位
    sprintf(strTemp, "%s%.01f", str, fTemp); //将浮点数转成字符串  

    UartSendString(strTemp, strlen(strTemp));       //通过串口发送温度值到电脑显示
#else       
    ucTemp = ReadDs18B20();           //温度读取函数
    //strTemp[0] = ucTemp/10+48;        //取出十位数
    //strTemp[1] = ucTemp%10+48;        //取出个位数

    sprintf(strTemp, "%s%d%d", str, ucTemp/10, ucTemp%10);   
    UartSendString(strTemp, strlen(strTemp));       //通过串口发送温度值到电脑显示
#endif 

    LCD_P8x16Str(0, 5, (unsigned char*)strTemp);
    UartSendString("\r\n", 2);          // 回车换行     
    Delay_ms(1000);                   //延时函数使用定时器方式  
  }
}

/**
  * @brief     设置系统时钟源
  * @param     None
  * @retval    None
  */
void InitCLK()
{
  CLKCONCMD &= ~0x40;             //设置系统时钟源为32MHZ晶振 
  while(CLKCONSTA & 0x40);        //等待晶振稳定为32M
  CLKCONCMD &= ~0x47;             //设置系统主时钟频率为32MHZ   
}

/**
  * @brief     串口初始化函数
  * @param     None
  * @retval    None
  */
void InitUart()
{
  PERCFG = 0x00;                  //位置1 P0口
  P0SEL = 0x0c;                   //P0用作串口
  P2DIR &= ~0xc0;                 //P0优先作为UART0 
  U0CSR |= 0x80;                  //串口设置为UART方式
  U0GCR |= 11;
  U0BAUD |= 216;                  //波特率设为115200
  U0CSR |= 0x40;                  //UART接收器使能
  UTX0IF = 0;                     //UART0 TX中断标志初始置位0
}

/**
  * @brief     串口发送函数
  * @param     Data:发送缓冲区   
               len:发送长度
  * @retval    None
  */
void UartSendString(char *Data, int len)
{
  uint i;

  for(i=0; i<len; i++)
  {    
    U0DBUF = *Data++;

    while(UTX0IF == 0);
    UTX0IF = 0;
  }
}

2.6实验现象

串口显示的温度如下图,用手摸着18B20 发现温度明显在变化。

这里写图片描述

图5

本章参考代码

点击进入

猜你喜欢

转载自blog.csdn.net/u013162035/article/details/80992933