【CC2530开发基础篇】DS18B20温度传感器
1.1 开发背景
在本项目中,我们使用德州仪器(TI)的CC2530单片机搭建一个简单的温度检测系统,通过接入数字温度传感器DS18B20,实现实时环境温度的采集和监测。CC2530是一款高性能、低功耗的无线微控制器,特别适合物联网(IoT)和嵌入式系统的开发,其丰富的外设接口为传感器连接和数据传输提供了便利。
DS18B20是一种单总线数字温度传感器,具有高精度和易于使用的特点。它支持单线通信协议,仅需要一个数据线即可完成温度数据的采集和传输,从而简化了硬件设计。为了便于实验调试,本项目将DS18B20的信号引脚连接至CC2530的P0.7引脚,利用单片机的软件功能实现与传感器的通信和数据读取。
这是当前实验使用的CC2530板子的实物图:
二、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主要是由于以下原因:
-
官方支持 德州仪器推荐使用IAR开发CC2530,因为其ZigBee协议栈(如Z-Stack)是专门为IAR优化的,许多示例代码和参考项目直接在IAR环境中运行,减少了开发者的移植工作。
-
代码优化能力强 IAR的编译器提供了高效的代码优化功能,包括针对代码大小和运行速度的优化选项。对于资源受限的CC2530(如闪存128 KB和RAM 8 KB),IAR可以显著减小二进制文件大小,让更多复杂功能得以实现。
-
调试工具完善 IAR集成了强大的调试工具,支持CC2530的片上调试功能(On-Chip Debugging)。通过与TI的调试硬件(如CC Debugger)配合,开发者可以实时查看和控制程序运行状态,进行断点设置、变量监控和性能分析。
-
多功能集成 IAR提供了丰富的功能模块,如静态分析、运行时调试和内存分析工具。这些功能特别适合复杂协议栈(如ZigBee)的开发,帮助开发者迅速定位和解决问题。
IAR与Keil的区别
Keil也是一款非常流行的嵌入式开发工具,但在开发CC2530时,IAR相比Keil具有以下显著区别:
-
官方适配支持 TI官方的ZigBee协议栈和示例项目主要为IAR设计,Keil并没有直接支持这些协议栈。因此,使用Keil开发CC2530需要进行额外的移植工作,而IAR则可以开箱即用。
-
编译器优化效果 IAR的编译器在优化代码大小方面普遍优于Keil,这对于资源有限的CC2530尤为重要。在存储和性能受限的情况下,IAR可以更高效地利用芯片资源。
-
协议栈复杂度支持 ZigBee协议栈本身较为复杂,对编译器和开发环境的要求较高。IAR对复杂嵌入式协议的支持更为成熟,而Keil的侧重点更多在通用8051开发。
-
工具链兼容性 IAR与CC2530配套的调试工具(如CC Debugger)无缝集成,调试体验更流畅。Keil在支持TI调试硬件方面不够完善,可能需要第三方工具或插件进行适配。
IAR是CC2530开发的首选环境,其强大的优化能力、完善的调试功能和与ZigBee协议的高兼容性,使得开发者能够更加高效地完成项目。而Keil尽管也支持8051平台,但在CC2530开发中的表现和适配性稍逊一筹。
2.3 IAR新建工程的步骤
三、代码设计
代码的含义看中文注释
,这里不再单独写文字介绍代码含义。
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在嵌入式开发中的高效协作。
- 点赞
- 收藏
- 关注作者
评论(0)