写点什么

基于 CC2530(ZigBee 设计) 的温度报警器

作者:DS小龙哥
  • 2022 年 2 月 22 日
  • 本文字数:4443 字

    阅读完需:约 15 分钟

1. 功能介绍

这是基于 CC2530 设计的远程温度报警器,通过 CC2530 终端检测环境温度上传给手机 APP 实时显示。


一共有两块 CC2530 开发板,这里就分别称为 A 板(当做协调器)、B 板(当做温度节点),A 板上接了 ESP8266 WIF 模块,用于与手机 APP 之间通信。B 板上接了 DS18B20 温度传感器模块,用于给 A 板传递检测的温度,A 板收到 DS18B20 的温度之后,发送给手机 APP 显示。APP 上位机采用 Qt 框架设计,支持跨平台,Android、windows、IOS、Linux 都可以编译运行安装。




完整项目代码下载地址: https://download.csdn.net/download/xiaolong1126626497/75315395


资料包里包含:


2. 硬件接线介绍

2.1 DS18B20 温度传感器

作为 B 节点的 CC2530 开发板上接了 DS18B20 温度传感器,采集温度传递给 A 节点。



这是 B 节点的程序,在主函数 1 秒采集一次 DS18B20 温度数据,然后传递给 A 节点。


2.2 ESP8266 WIFI 模块

作为 A 节点协调器的 CC2530 开发板用到了 2 个串口:


(1)串口 0—作为常规调试串口,可以向串口调试助手打印调试信息。


(2)串口 1—连接 ESP8266 WIFI,进行通信。 P0.4,P0.5 用作串口





上面这张图是代码的截图,设置 ESP8266 的 AP 热点名称和密码。把 ESP8266 接线接好之后,在把程序下载进去。正常情况下,ESP8266 就会创建一个名称为**” wbyq_Cortex_M3”** 的热点,连接密码为**”12345678”**, 这是打开手机 APP 搜索这个 WIFI 名称,然后连接即可,连接上了,打开专用的手机 APP,点击连接服务器,然后就可以收到 ESP8266 发送过来的温度数据了。


下面这个是代码主函数里,1 秒的频率向 APP 上传 DS18B20 的温度。


3. 案例代码

3.1 QT 设计的上位机


3.2 B 节点 DS18B20 代码

#define Ds18b20IO P0_6       //温度传感器引脚
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--; }}
//时钟频率为32Mvoid Ds18b20Delay(unsigned int k){ unsigned int i,j; for(i=0;i<k;i++) for(j=0;j<2;j++);}
void Ds18b20InputInitial(void)//设置端口为输入{ P0DIR &= (1<<6); //P0.7到P0.0的I/O方向 0输入 1输出}
void Ds18b20OutputInitial(void)//设置端口为输出{ P0DIR |= (1<<6);}
//ds18b20初始化 初始化成功返回0x00,失败返回0x01unsigned char Ds18b20Initial(void){ unsigned char Status = 0x00; unsigned int CONT_1 = 0; unsigned char Flag_1 = 1; Ds18b20OutputInitial(); Ds18b20IO = 1; //DQ复位 Ds18b20Delay(260); //稍做延时 Ds18b20IO = 0; //单片机将DQ拉低 Ds18b20Delay(750); //精确延时 大于 480us 小于960us Ds18b20IO = 1; //拉高总线 Ds18b20InputInitial();//设置IO输入 while((Ds18b20IO != 0)&&(Flag_1 == 1))//等待ds18b20响应,具有防止超时功能 { //等待约60ms左右 CONT_1++; Ds18b20Delay(10); if(CONT_1 > 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;}


//温度读取函数 带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;}
复制代码

3.3 协调器-ESP8266 代码

#include "esp8266.h"
uint lenU1 = 0;uchar tempRXU1;uchar RecdataU1[MAXCHAR];//AP+服务器模式char *ESP8266_AP_Server[]={ "AT\r\n", "ATE0\r\n", "AT+CWMODE=2\r\n", "AT+RST\r\n", "ATE0\r\n", "AT+CWSAP=\"wbyq_Cortex_M3\",\"12345678\",1,4\r\n", "AT+CIPMUX=1\r\n", "AT+CIPSERVER=1,8089\r\n", "AT+CIFSR\r\n" };

//"AT+CIPSEND=0,10\r\n" //长度10//返回">" 之后就可以正常发送数据了//发送成功返回 "SEND OK"

//发送数据void ESP8266_SendData(char *p,int len){ char buff[50]; sprintf(buff,"AT+CIPSEND=0,%d\r\n",len); clearBuffU1(); Uart1_Send_String(buff); DelayMs(1000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); //发送数据 Uart1_Send_String(p); //等待发送完成 DelayMs(1000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1();}

/***************************************************************************** 名 称: SetWifi()* 功 能: 设置LED灯相应的IO口* 入口参数: 无* 出口参数: 无****************************************************************************/void SetWifi(void){ P0DIR |= 0x40; //P0.6定义为输出 IGT = 0; //高电平复位 DelayMs(500); IGT = 1; //低电平工作}
/*设置WIFI为AP模式+TCP服务器*/void SetESP8266_AP_TCP_Server(){ clearBuffU1(); Uart1_Send_String("AT\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("ATE0\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+CWMODE=2\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+RST\r\n"); DelayMs(2000); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("ATE0\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+CWSAP=\"wifi_cc2530\",\"12345678\",1,4\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+CIPMUX=1\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+CIPSERVER=1,8080\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1); clearBuffU1(); Uart1_Send_String("AT+CIFSR\r\n"); DelayMs(2000); RecdataU1[lenU1]='\0'; UR0SendString(RecdataU1);}

unsigned char dataRecv;unsigned char Flag = 0;/*===================UR1初始化函数====================*/void Init_Uart1(){ PERCFG = 0x00; //位置1 P0.4/P0.5口 P0SEL |= 0x30; //P0.4,P0.5用作串口(外部设备功能) U1CSR |= 0x80; //设置为UART方式 U1GCR |= 11; //BAUD_E U1BAUD |= 216; //BAUD_M 波特率设为115200 UTX1IF = 0; //UART1 TX中断标志初始置位0 U1CSR |= 0X40; //允许接收 IEN0 |= 0x88; // 开总中断,UART1接收中断 }

void clearBuffU1(void){ int j; for(j=0;j<MAXCHAR;j++) { RecdataU1[j]=0x00; } lenU1=0;}
/*******************************************************************************串口1发送一个字节函数 *******************************************************************************/void Uart1_Send_Char(char Data){ U1CSR &= ~0x40; //禁止接收 U1DBUF = Data; while(UTX1IF == 0); UTX1IF = 0; U1CSR |= 0x40; //允许接收}
/*******************************************************************************串口1发送字符串函数 *******************************************************************************/void Uart1_Send_String(char *Data){ while(*Data!='\0') { Uart1_Send_Char(*Data); Data++; }}

/**************************************************************** 串口接收一个字符: 一旦有数据从串口传至CC2530, 则进入中断,将接收到的数据赋值给变量temp. ****************************************************************/ #pragma vector = URX1_VECTOR __interrupt void UART1_ISR(void) { if(lenU1<81) { tempRXU1 = U1DBUF; RecdataU1[lenU1]=tempRXU1; URX1IF = 0; // 清中断标志 lenU1++; }}
复制代码


发布于: 刚刚阅读数: 2
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
基于CC2530(ZigBee设计)的温度报警器