一、环境介绍
编译集成开发环境: IAR
MCU: CC2530(ZigBee)
编程语言: C 语言
手机 APP: 采用 QT 设计,程序支持跨平台编译运行(Android、IOS、Windows、Linux 都可以编译运行,对应平台上 QT 的环境搭建,之前博客已经发了文章讲解)
硬件包含: 3 套 CC2530 开发板(1 个协调器、2 个节点)、1 个 ESP8266 串口 WIFI、1 个 DHT11 温湿度传感器、1 个 RGB 多彩灯、1 个 BH1750 光强度检测传感器.
资料包里包含了: CC2530 协调器源码、2 个节点源码、手机 APP 源码、Windows 上位机源码、手机 APP 可执行文件、IAR 下载器驱动、IAR 资料等等。
二、功能介绍
这是基于 CC2530 设计的景观照明控制系统,一共包含了 3 个 CC2530 节点(就是 3 块 CC2530 开发板)。
下面将这个 3 个 CC2530 开发板称为 A、B、C 节点。
A 节点: 当做协调器、可以接收 BC 节点上传的数据;A 模块配了一个 ESP8266 WIFI 模块,可以连接手机 APP,将 BC 节点上传温湿度数据再上传给手机 APP 显示。如果 A 节点在一定时间内没有收到 B、C 节点的数据,就会通知手机 APP,告诉用户,B、C 节点已经掉线。
B 节点: 作为 RGB 多彩灯+温湿度检测节点,会根据当前温湿度调整当前 RGB 灯的颜色,用于告诉景区的游客,当前景区的温湿度情况,采集的温湿度也会通过 CC2530 传递给 A 节点。
C 节点: 光照强度检测+LED 灯节点。 这里的 LED 灯就是模拟景区的路灯,手机 APP 可以控制 LED 灯的开关,如果是白天的时候,LED 灯会自动关掉,天气变暗,自动打开。也可以设计时间,定时关灯。
三、相关的硬件介绍
3.1 DTH11 温湿度传感器
DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个 DHT11 传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在 OTP 内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用中,在苛刻应用场合的最佳选择。产品为 4 针单排引脚封装,连接方便。
3.2 ESP8266 WIFI
ESP8266 系列无线模块是高性价比 WIFI SOC 模组,该系列模块支持标准的 IEEE802.11b/g/n 协议,内置完整的 TCP/IP 协议栈。用户可以使用该系列模块为现有的设备添加联网功能,也可以构建独立的网络控制器。
能卓越
ESP8266EX 芯片内置超低功耗 Tensilica L106 32 位 RISC 处理器,CPU 时钟速度最⾼可达 160 MHz,⽀持实时操作系统 (RTOS) 和 Wi-Fi 协议栈,可将⾼达 80% 的处理能⼒应用于编程和开发。
高度集成
ESP8266 芯片高度集成天线开关、射频巴伦、功率放大器、低噪声接收放大器、滤波器等射频模块。模组尺寸小巧,尤其适用于空间受限的产品设计。
认证齐全
RF 认证:SRRC、FCC、CE-RED、KCC、TELEC/MIC、IC 和 NCC 认证;
环保认证:RoHS、REACH;
可靠性认证:HTOL、HTSL、μHAST、TCT、ESD。
丰富的产品应用
ESP8266 模组既可以通过 ESP-AT 指令固件,为外部主机 MCU 提供 Wi-Fi 连接功能;也可以作为独立 Wi-Fi MCU 运行,用户通过基于 RTOS 的 SDK 开发带 Wi-Fi 连接功能的产品。用户可以轻松实现开箱即用的云连接、低功耗运行模式,以及包括 WPA3 在内的 Wi-Fi 安全支持等功能。
3.3 CC2530
CC2530 是用于 2.4-GHz IEEE 802.15.4、ZigBee 和 RF4CE 应用的一个真正的片上系统(SoC)解决方案。它能够以非常低的总的材料成本建立强大的网络节点。
CC2530 结合了领先的 RF 收发器的优良性能,业界标准的增强型 8051 CPU,系统内可编程闪存,8-KB RAM 和许多其它强大的功能。CC2530 有四种不同的闪存版本:CC2530F32/64/128/256,分别具有 32/64/128/256KB 的闪存。CC2530 具有不同的运行模式,使得它尤其适应超低功耗要求的系统。运行模式之间的转换时间短进一步确保了低能源消耗。
CC2530F256 结合了德州仪器的业界领先的黄金单元 ZigBee 协议栈(Z-Stack™),提供了一个强大和完整的 ZigBee 解决方案。
CC2530F64 结合了德州仪器的黄金单元 RemoTI,更好地提供了一个强大和完整的 ZigBee RF4CE 远程控制解决方案。
3.4 RGB 多彩灯
颜色:全彩 红绿蓝三基色
亮度:高亮
电压:5V
输入:数字电平
三基色原理显示多重颜色
通过 PWM 端口控制实现全彩显示
3.5 BH1750
** bh1750 是 16 位数字输出型,环境光强度传感器。**
四、节点硬件+手机 APP 介绍
4.1 C 节点: 光敏传感器+LED 灯控制
4.2 B 节点: 多彩灯+温湿度
4.3 A 节点: WIFI + APP
4.4 手机 APP 界面效果
五、手机 APP 上位机源码
六、CC2530 节点源码
节点源码较多,下面就贴一些关键代码。
6.1 uart.c
#include "uart.h"
/*
函数功能:串口0初始化
*/
void Init_Uart0(void)
{
PERCFG&=~(1<<0); //串口0的引脚映射到位置1,即P0_2和P0_3
P0SEL|=0x3<<2; //将P0_2和P0_3端口设置成外设功能
U0BAUD = 216; //32MHz的系统时钟产生115200BPS的波特率
U0GCR&=~(0x1F<<0);//清空波特率指数
U0GCR|=11<<0; //32MHz的系统时钟产生115200BPS的波特率
U0UCR |= 0x80; //禁止流控,8位数据,清除缓冲器
U0CSR |= 0x3<<6; //选择UART模式,使能接收器
}
/*
函数功能:UART0发送字符串函数
*/
void UR0SendString(u8 *str)
{
while(*str!='\0')
{
U0DBUF = *str; //将要发送的1字节数据写入U0DBUF
while(UTX0IF == 0);//等待数据发送完成
UTX0IF = 0; //清除发送完成标志,准备下一次发送
str++;
}
}
/*
函数功能: 模仿printf风格的格式化打印功能
*/
char USART0_PRINT_BUFF[200]; //格式化数据缓存数据
void USART0_Printf(const char *format,...)
{
char *str=NULL;
/*1. 格式化转换*/
va_list ap; // va_list---->char *
va_start(ap,format); //初始化参数列表
vsprintf(USART0_PRINT_BUFF,
format,
ap); //格式化打印
va_end(ap); //结束参数获取
/*2. 串口打印*/
str=USART0_PRINT_BUFF;//指针赋值
while(*str!='\0')
{
U0DBUF=*str; //发送一个字节的数据
str++; //指针自增,指向下一个数据
while(UTX0IF == 0);//等待数据发送完成
UTX0IF = 0; //清除发送完成标志,准备下一次发送
}
}
复制代码
6.2 DHT11.c
#include "dht11.h"
#include "delay.h"
#define DATA_PIN P0_7
//温湿度定义
uchar ucharFLAG,uchartemp;
uchar shidu_shi,shidu_ge,wendu_shi,wendu_ge=4;
uchar ucharT_data_H,ucharT_data_L,ucharRH_data_H,ucharRH_data_L,ucharcheckdata;
uchar ucharT_data_H_temp,ucharT_data_L_temp,ucharRH_data_H_temp,ucharRH_data_L_temp,ucharcheckdata_temp;
uchar ucharcomdata;
//延时函数
void Delay_us() //1 us延时
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
void Delay_10us() //10 us延时
{
#if 0
Delay_us();
Delay_us();
Delay_us();
Delay_us();
Delay_us();
Delay_us();
Delay_us();
Delay_us();
Delay_us();
Delay_us();
#else
int i = 10;
while(i--);
#endif
}
void Delay_ms(unsigned int Time)//n ms延时
{
unsigned char i;
while(Time--)
{
for(i=0;i<100;i++)
Delay_10us();
}
}
//温湿度传感
void COM(void) // 温湿写入
{
uchar i;
for(i=0;i<8;i++)
{
ucharFLAG=2;
while((!DATA_PIN)&&ucharFLAG++);
Delay_10us();
Delay_10us();
Delay_10us();
uchartemp=0;
if(DATA_PIN)uchartemp=1;
ucharFLAG=2;
while((DATA_PIN)&&ucharFLAG++);
if(ucharFLAG==1)break;
ucharcomdata<<=1;
ucharcomdata|=uchartemp;
}
}
void DHT11(void) //温湿传感启动
{
DATA_PIN=0;
Delay_ms(19); //>18MS
DATA_PIN=1;
P0DIR &= ~0x80; //重新配置IO口方向
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
if(!DATA_PIN)
{
ucharFLAG=2;
while((!DATA_PIN)&&ucharFLAG++);
ucharFLAG=2;
while((DATA_PIN)&&ucharFLAG++);
COM();
ucharRH_data_H_temp=ucharcomdata;
COM();
ucharRH_data_L_temp=ucharcomdata;
COM();
ucharT_data_H_temp=ucharcomdata;
COM();
ucharT_data_L_temp=ucharcomdata;
COM();
ucharcheckdata_temp=ucharcomdata;
DATA_PIN=1;
uchartemp=(ucharT_data_H_temp+ucharT_data_L_temp+ucharRH_data_H_temp+ucharRH_data_L_temp);
if(uchartemp==ucharcheckdata_temp)
{
ucharRH_data_H=ucharRH_data_H_temp;
ucharRH_data_L=ucharRH_data_L_temp;
ucharT_data_H=ucharT_data_H_temp;
ucharT_data_L=ucharT_data_L_temp;
ucharcheckdata=ucharcheckdata_temp;
}
wendu_shi=ucharT_data_H/10;
wendu_ge=ucharT_data_H%10;
shidu_shi=ucharRH_data_H/10;
shidu_ge=ucharRH_data_H%10;
}
else //没用成功读取,返回0
{
wendu_shi=0;
wendu_ge=0;
shidu_shi=0;
shidu_ge=0;
}
P0DIR |= 0x80; //IO口需要重新配置
}
复制代码
6.3 BH1750.c
#include "bh1750.h"
u8 Read_BH1750_Data()
{
unsigned char t0;
unsigned char t1;
unsigned char t;
u8 r_s=0;
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:1\r\n");
IIC_WriteOneByteData(0x01);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:2\r\n");
IIC_Stop(); //停止信号
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:3\r\n");
IIC_WriteOneByteData(0x01);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:4\r\n");
IIC_Stop(); //停止信号
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:5\r\n");
IIC_WriteOneByteData(0x10);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:6\r\n");
IIC_Stop(); //停止信号
DelayMs(300); //等待
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(0x47);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:7\r\n");
t0=IIC_ReadOneByteData(); //接收数据
IIC_SendACK(0); //发送应答信号
t1=IIC_ReadOneByteData(); //接收数据
IIC_SendACK(1); //发送非应答信号
IIC_Stop(); //停止信号
t=(((t0<<8)|t1)/1.2);
return t;
}
复制代码
评论