【CC2530开发基础篇】DS18B20温度传感器

举报
DS小龙哥 发表于 2024/11/26 11:42:50 2024/11/26
【摘要】 通过本项目,我们成功实现了基于CC2530和DS18B20温度传感器的环境温度检测系统。CC2530作为主控芯片,凭借其强大的处理能力和丰富的外设接口,出色地完成了与传感器的通信以及数据的采集与传输任务。而DS18B20以其高精度、简易的单总线通信方式,以及灵活的供电模式,为系统提供了可靠的温度测量解决方案。

一、前言

1.1 开发背景

在本项目中,我们使用德州仪器(TI)的CC2530单片机搭建一个简单的温度检测系统,通过接入数字温度传感器DS18B20,实现实时环境温度的采集和监测。CC2530是一款高性能、低功耗的无线微控制器,特别适合物联网(IoT)和嵌入式系统的开发,其丰富的外设接口为传感器连接和数据传输提供了便利。

DS18B20是一种单总线数字温度传感器,具有高精度和易于使用的特点。它支持单线通信协议,仅需要一个数据线即可完成温度数据的采集和传输,从而简化了硬件设计。为了便于实验调试,本项目将DS18B20的信号引脚连接至CC2530的P0.7引脚,利用单片机的软件功能实现与传感器的通信和数据读取。

此外,本项目将采集到的温度数据通过CC2530的串口0发送到PC端串口调试助手进行实时显示。通过串口调试助手,可以直观地观察环境温度的变化,为调试和验证提供了方便。本设计的简单架构和高可扩展性不仅适合初学者学习,还为后续的无线传输或其他传感器扩展提供了良好的基础。


这是当前实验使用的CC2530板子的实物图:

cke_5113.png


1.2 DS1820温度传感器介绍

DS18B20是一款广泛使用的数字温度传感器,因其高精度、易用性和低成本,广泛应用于温度监测和控制系统中。它采用单总线(1-Wire)协议进行通信,通过单根数据线即可实现与微控制器的连接,适合资源有限的嵌入式系统。

DS18B20支持的温度测量范围为-55°C至+125°C,精度在-10°C至+85°C范围内可达到±0.5°C。其分辨率可配置为9位至12位,默认分辨率为12位,能提供精确到0.0625°C的测量值。由于其内置非易失性存储器(EEPROM),用户可以设置并保存分辨率等参数,即使掉电也不会丢失。

该传感器具有唯一的64位序列号,每个DS18B20都独立可寻址,这使得多传感器连接在同一总线上成为可能。用户通过序列号可以轻松管理和读取多个传感器的数据,适合复杂场景中的多点温度采集。

DS18B20的供电方式非常灵活,可以使用外部电源供电(VDD = 3.0V~5.5V),也可以采用寄生电源模式,仅通过数据线供电,进一步减少了外部连线的需求。

DS18B20的使用非常简单,数据通信只需要一个GPIO口配合单线协议进行数据传输。单线协议的特点是通过特定的时序发送和接收信号,完成数据读取和控制指令的交互。常见操作包括读取温度值、启动温度转换、配置寄存器等。

DS18B20以其高精度、低功耗和简洁的通信接口成为温度传感器领域的经典选择。无论是简单的单点测量还是复杂的多点网络采集,DS18B20都能胜任,是嵌入式温度监测系统的理想选择。



二、CC2530基础知识科普

2.1 CC2530 与 ZigBee 的含义

CC2530是什么

CC2530是一款由德州仪器(Texas Instruments,TI)推出的无线微控制器芯片,专为低功耗和无线通信应用设计。它基于8051内核,具有丰富的片上资源,包括128 KB的闪存、8 KB的RAM、多个UART和SPI接口、ADC模块等。此外,CC2530支持IEEE 802.15.4标准,这是ZigBee协议栈的基础。CC2530的低功耗特性和高集成度使其特别适用于智能家居、物联网(IoT)设备和工业自动化等应用场景。

ZigBee是什么

ZigBee是一种基于IEEE 802.15.4标准的无线通信协议,专为低功耗、低数据速率和短距离应用场景设计。它的主要特点是功耗低、组网灵活、支持大规模网络节点(如星型、网状和树形拓扑),并且具有较强的抗干扰能力。ZigBee常用于智能家居(如智能灯控、温湿度传感器)、工业物联网、医疗设备和农业监控等领域。与Wi-Fi和蓝牙相比,ZigBee适合需要低功耗、低数据速率和高网络节点容量的应用。

CC2530与ZigBee的联系

CC2530是支持ZigBee协议的硬件平台之一。CC2530的硬件架构和无线射频模块完全符合IEEE 802.15.4标准,而ZigBee协议栈则是运行在该标准之上的通信协议。通过在CC2530芯片上加载ZigBee协议栈(如TI提供的Z-Stack),用户可以构建完整的ZigBee无线通信系统。

CC2530作为ZigBee设备的实现平台,可以配置为不同类型的ZigBee节点,包括协调器(Coordinator)、路由器(Router)和终端设备(End Device)。协调器负责整个ZigBee网络的建立和管理,路由器用于中继信号扩展网络范围,终端设备通常是低功耗的传感器或执行器。

CC2530是支持ZigBee协议的硬件芯片,而ZigBee是运行在像CC2530这样的硬件平台上的通信协议。CC2530为ZigBee提供硬件支持,ZigBee则为CC2530提供实现复杂网络功能的能力。这种软硬结合使得CC2530成为ZigBee应用中的主流选择之一。


2.2 CC2530的开发环境

CC2530官方推荐的开发环境是 IAR Embedded Workbench(IAR EW8051)

CC2530的开发环境:IAR Embedded Workbench

IAR Embedded Workbench(简称IAR)是开发CC2530的主要集成开发环境(IDE)。它是一款专业的嵌入式软件开发工具,提供了编辑、编译、调试和优化等功能,广泛支持各种嵌入式微控制器平台,包括基于8051内核的CC2530。IAR针对低功耗和无线设备开发进行了深度优化,特别适合CC2530这类资源有限的嵌入式芯片。

IAR支持德州仪器的ZigBee协议栈(如Z-Stack),并提供了配套的调试工具和编译器,使开发者能够轻松集成ZigBee协议、编写应用代码和调试固件。此外,IAR具有良好的代码优化能力,能有效减少CC2530有限内存的占用,提高程序运行效率。


为什么使用IAR开发CC2530

使用IAR开发CC2530主要是由于以下原因:

  1. 官方支持 德州仪器推荐使用IAR开发CC2530,因为其ZigBee协议栈(如Z-Stack)是专门为IAR优化的,许多示例代码和参考项目直接在IAR环境中运行,减少了开发者的移植工作。

  2. 代码优化能力强 IAR的编译器提供了高效的代码优化功能,包括针对代码大小和运行速度的优化选项。对于资源受限的CC2530(如闪存128 KB和RAM 8 KB),IAR可以显著减小二进制文件大小,让更多复杂功能得以实现。

  3. 调试工具完善 IAR集成了强大的调试工具,支持CC2530的片上调试功能(On-Chip Debugging)。通过与TI的调试硬件(如CC Debugger)配合,开发者可以实时查看和控制程序运行状态,进行断点设置、变量监控和性能分析。

  4. 多功能集成 IAR提供了丰富的功能模块,如静态分析、运行时调试和内存分析工具。这些功能特别适合复杂协议栈(如ZigBee)的开发,帮助开发者迅速定位和解决问题。


IAR与Keil的区别

Keil也是一款非常流行的嵌入式开发工具,但在开发CC2530时,IAR相比Keil具有以下显著区别:

  1. 官方适配支持 TI官方的ZigBee协议栈和示例项目主要为IAR设计,Keil并没有直接支持这些协议栈。因此,使用Keil开发CC2530需要进行额外的移植工作,而IAR则可以开箱即用。

  2. 编译器优化效果 IAR的编译器在优化代码大小方面普遍优于Keil,这对于资源有限的CC2530尤为重要。在存储和性能受限的情况下,IAR可以更高效地利用芯片资源。

  3. 协议栈复杂度支持 ZigBee协议栈本身较为复杂,对编译器和开发环境的要求较高。IAR对复杂嵌入式协议的支持更为成熟,而Keil的侧重点更多在通用8051开发。

  4. 工具链兼容性 IAR与CC2530配套的调试工具(如CC Debugger)无缝集成,调试体验更流畅。Keil在支持TI调试硬件方面不够完善,可能需要第三方工具或插件进行适配。


IAR是CC2530开发的首选环境,其强大的优化能力、完善的调试功能和与ZigBee协议的高兼容性,使得开发者能够更加高效地完成项目。而Keil尽管也支持8051平台,但在CC2530开发中的表现和适配性稍逊一筹。



2.3 IAR新建工程的步骤

cke_7563.png

cke_9122.png

cke_11192.png

cke_13353.png

cke_15573.png

cke_17867.png

cke_20226.png

cke_22692.png

cke_25210.png

cke_27807.png

cke_30467.png

cke_33238.png

cke_36070.png


cke_38994.png


cke_41952.png


cke_45011.png


cke_48139.png

cke_51345.png


cke_54408.png

cke_57795.png



cke_61236.png

cke_64772.png

cke_68405.png



三、代码设计

代码的含义看中文注释,这里不再单独写文字介绍代码含义。

3.1 main.c

/****************************************************************************
* 描    述: 设置串口调试助手波特率:115200bps 8N1
*           DS18B20采集的温度通过串口传给电脑显示
****************************************************************************/
#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          //输出更高精度时打开此注释
​
extern void Delay_ms(unsigned int k);//外部函数ms的声明
​
/****************************************************************************
* 名    称: InitCLK()
* 功    能: 设置系统时钟源
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitCLK()
{
    CLKCONCMD &= ~0x40;             //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);        //等待晶振稳定为32M
    CLKCONCMD &= ~0x47;             //设置系统主时钟频率为32MHZ   
}
​
/****************************************************************************
* 名    称: InitUart()
* 功    能: 串口初始化函数
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitUart()
{
    PERCFG = 0x00;                  //位置1 P0口
    P0SEL = 0x0c;                   //P0用作串口
    P2DIR &= ~0xc0;                 //P0优先作为UART0 
    U0CSR |= 0x80;                  //串口设置为UART方式
    U0GCR |= 8;
    U0BAUD |= 59;                  //波特率设为115200
    U0CSR |= 0x40;                  //UART接收器使能
    UTX0IF = 0;                     //UART0 TX中断标志初始置位0
}
​
/****************************************************************************
* 名    称: UartSendString()
* 功    能: 串口发送函数
* 入口参数: Data:发送缓冲区   len:发送长度
* 出口参数: 无
****************************************************************************/
void UartSendString(char *Data, int len)
{
    uint i;
    
    for(i=0; i<len; i++)
    {
        U0DBUF = *Data++;
        while(UTX0IF == 0);
        UTX0IF = 0;
    }
}
​
/****************************************************************************
* 程序入口函数
****************************************************************************/
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);                   //延时函数使用定时器方式
    }
}


3.2 DS18B2.c

#include "ds18b20.h" 
​
#define Ds18b20IO P0_7       //温度传感器引脚
​
void Delay_us(unsigned int k)//us延时函数
{
    T1CC0L = 0x06; 
    T1CC0H = 0x00; 
    T1CTL = 0x02; 
    while(k)
    { 
        while(!(T1CNTL >= 0x04));
        k--;
    }
    T1CTL = 0x00;  //关闭定时器
}
​
void Delay_ms(unsigned int k)
{
    T1CC0L = 0xe8;
    T1CC0H = 0x03;
    T1CTL = 0x0a; //模模式 32分频
    while(k)
    {
        while(!((T1CNTL >= 0xe8)&&(T1CNTH >= 0x03)));
        k--;
    }
    T1CTL = 0x00; //关闭定时器
}
​
void Delay_s(unsigned int k)
{
    while(k)
    {
        Delay_ms(1000);
        k--;
    }
}
​
//时钟频率为32M
void Ds18b20Delay(unsigned int k)
{
    unsigned int i,j;
    for(i=0;i 8000)Flag_1 = 0;
        Status = Ds18b20IO;
    }
    Ds18b20OutputInitial();
    Ds18b20IO = 1;
    Ds18b20Delay(100);
    return Status;       //返回初始化状态
}
​
void Ds18b20Write(unsigned char infor)
{
    unsigned int i;
    Ds18b20OutputInitial();
    for(i=0;i<8;i++)
    {
        if((infor & 0x01))
        {
            Ds18b20IO = 0;
            Ds18b20Delay(6);
            Ds18b20IO = 1;
            Ds18b20Delay(50);
        }
        else
        {
            Ds18b20IO = 0;
            Ds18b20Delay(50);
            Ds18b20IO = 1;
            Ds18b20Delay(6);
        }
        infor >>= 1;
    }
}
​
unsigned char Ds18b20Read(void)
{
    unsigned char Value = 0x00;
    unsigned int i;
    Ds18b20OutputInitial();
    Ds18b20IO = 1;
    Ds18b20Delay(10);
    for(i=0;i<8;i++)
    {
        Value >>= 1; 
        Ds18b20OutputInitial();
        Ds18b20IO = 0;// 给脉冲信号
        Ds18b20Delay(3);
        Ds18b20IO = 1;// 给脉冲信号
        Ds18b20Delay(3);
        Ds18b20InputInitial();
        if(Ds18b20IO == 1) Value |= 0x80;
        Ds18b20Delay(15);
    } 
    return Value;
}
​
//温度读取函数
unsigned char ReadDs18B20(void) 
{
    unsigned char V1,V2;   //定义高低8位 缓冲
    unsigned char temp;    //定义温度缓冲寄存器
    
    Ds18b20Initial();
    Ds18b20Write(0xcc);    // 跳过读序号列号的操作
    Ds18b20Write(0x44);    // 启动温度转换
    
    Ds18b20Initial();
    Ds18b20Write(0xcc);    //跳过读序号列号的操作 
    Ds18b20Write(0xbe);    //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
    
    V1 = Ds18b20Read();    //低位
    V2 = Ds18b20Read();    //高位
    temp = ((V1 >> 4)+((V2 & 0x07)*16)); //转换数据 
​
    return temp;
}
​
//温度读取函数 带1位小数位
float floatReadDs18B20(void) 
{
    unsigned char V1,V2;   //定义高低8位 缓冲
    unsigned int temp;     //定义温度缓冲寄存器
    float fValue;
    Ds18b20Initial();
    Ds18b20Write(0xcc);    // 跳过读序号列号的操作
    Ds18b20Write(0x44);    // 启动温度转换
    
    Ds18b20Initial();
    Ds18b20Write(0xcc);    //跳过读序号列号的操作 
    Ds18b20Write(0xbe);    //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
    
    V1 = Ds18b20Read();    //低位
    V2 = Ds18b20Read();    //高位
    //temp = ((V1 >> 4)+((V2 & 0x07)*16)); //转换数据 
    temp=V2*0xFF+V1;
    fValue = temp*0.0625;
    
    return fValue;
}


四、总结


通过本项目,我们成功实现了基于CC2530和DS18B20温度传感器的环境温度检测系统。CC2530作为主控芯片,凭借其强大的处理能力和丰富的外设接口,出色地完成了与传感器的通信以及数据的采集与传输任务。而DS18B20以其高精度、简易的单总线通信方式,以及灵活的供电模式,为系统提供了可靠的温度测量解决方案。

将采集到的温度数据通过串口发送至调试助手,使系统的运行情况得到了直观的反馈。这种实时的数据展示方式,既方便调试,也为系统的功能验证提供了保障。通过实际应用验证,整个系统硬件连接简单、软件逻辑清晰,充分体现了CC2530与DS18B20在嵌入式开发中的高效协作。

本项目为温度监测系统的开发提供了一种简洁有效的设计方法。未来,系统还可以进一步扩展,例如结合CC2530的无线通信能力,将采集到的温度数据通过ZigBee协议传输到远程终端,实现更复杂的物联网场景。这样的设计不仅提升了系统的实用性,也为物联网开发奠定了坚实的基础。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。