1. 功能介绍
设计题目名称:
一共使用3个CC2530 ZigBee代号分别为开发板ABC。
光感传感器连接在上面,ESP8266WIFI模块。通过ESP8266与手机APP之间通信,ESP8266创建热点,配置为TCP服务器模式; 手机APP连接上ESP8266热点后,连接ESP8266创建服务器,完成通信。 手机APP按钮可以控制上面B,C开发板上LED灯的开关。
-
自动照明模式: 根据A开发板上的光感模块,采集光照强度,控制B、C开发板上的LED灯开关。
-
手动模式: 手机APP 可选择单独控制B、C开发板上的LED灯开关。
-
支持光感阀值的设置: 在手机APP光感传感器阀值(即控制灯亮灭的阀值)可设置在A开发板上。
-
支持设置亮度,也可以自动根据环境光控制亮度
B开发板作为从机节点: B板载用于开发板LED模拟家庭卧室的照明设备,演示控制效果。
C开发板作为从机节点: C板载用于开发板LED模拟家庭客厅的照明设备,演示控制效果。
https://download.csdn.net/download/xiaolong1126626497/75317115
2. 硬件介绍
2.1 ESP8266 wifi
采用的ESP8266系列无线模块性价比高WIFI SOC该系列模块支持标准模块IEEE802.11b/g/n协议,内置完整TCP/IP协议堆栈。用户可以使用该系列模块为现有设备添加网络功能或构建独立的网络控制器。
CC2530开发板本身就有ESP插入8266专用接口。
ES8266 WIFI 模块接在 串口1 上面(P0.4/P0.5口) ,波特率为 115200 。
CC2530串口0作为常规调试串口(P0_2和P0_3端口),可以收集AD将数据打印到串口。 您还可以打印其他调试信息。
2.2 光敏传感器
3. 项目代码
3.1 串口代码
#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(char *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; ///清除发送标志,准备下次发送 } }
3.2 按键代码
#include "key.h" /* 函数功能:按键IO口初始化 硬件连接:KEY1-->P0_1 KEY2-->P2_0 */ void KEY_Init(void) { P0SEL&=~(0x1<<1); //配置P0_1处于通用GPIO口模式 P0DIR&=~(0x1<<1); //配置P0_1为输入模式 P0INP|= 0x1<<1; //上拉 P2SEL&=~(0x1<<0); //配置P2_0处于通用GPIO口模式 P2DIR&=~(0x1<<0); //配置P2_0为输入模式 P2INP|= 0x1<<0; //上拉 } /* 函数功能:按键扫描 返 回 值:按键值 */ unsigned char Key_Scan(void) { static unsigned char stat=1; if((KEY1==0||KEY2==0)&&stat) { stat=0; delay10ms(); if(KEY1==0)return 1; if(KEY2==0)return 2; } else { if(KEY1&&KEY2)stat=1; } return 0; }
3.3 延时函数
#include "delay.h" /*延时200毫秒*/ void delay200ms(void) //误差 -0.125us { unsigned char a,b,c; for(c=95;c>0;c--) for(b=181;b>0;b--) for(a=14;a>0;a--); } void delay10ms(void) //误差 0us { unsigned char a,b,c; for(c=193;c>0;c--) for(b=118;b>0;b--) &bsp; for(a=2;a>0;a--);
}
/******************************************
* 函数描述:32M系统时钟下的毫秒延时函数
******************************************/
void DelayMs(unsigned int ms)
{
unsigned int i,j;
for(i = 0; i < ms; i++)
{
for(j = 0;j < 1774; j++);
}
}
void Onboard_wait( int timeout )
{
while (timeout--)
{
asm("NOP");
asm("NOP");
asm("NOP");
}
}
//延时函数
void DelayUs(int us) //1 us延时
{
Onboard_wait(us);
}
3.4 A开发板(协调器)主函数代码
/*主函数*/
void main(void)
{
u8 time_cnt=0;
unsigned char key;
u8 switch_val=150; //开关阀值
u8 mode=1; //0 表示手动模式 1表示自动模式
//延时等待系统稳定
DelayMs(1000);
DelayMs(1000);
init_clk(); //配置时钟
LED_Init(); //初始化LED灯控制IO口
KEY_Init(); //按键初始化
Init_Uart0(); //初始化串口0
RF_Init(); //RF初始化
Init_Uart1(); //初始化串口1--连接WIFI
SetWifi(); //复位WIFI
SetESP8266_AP_TCP_Server(); //初始化WIFI
adc_Init();
clearBuffU1(); //清空BUFF
//运行正常提示
USART0_Printf("当前运行的是A开发板程序,一切正常.\r\n");
while(1)
{
//按键检测
key=Key_Scan();
if(key)
{
LED2 = !LED2;
}
/* 服务器发出的数据
value:100 //阀值
led1_on //卧室LED开
led1_off //卧室LED关
led2_on //客厅LED开
led2_off //客厅LED关
yes_auto_mode //自动模式
no_auto_mode //手动模式
*/
//判断是否收到了WIFI的数据
if(lenU1>=13)
{
RecdataU1[lenU1]='\0';
//串口打印数据
USART0_Printf("WIFI收到的数据:%s\n",(u8*)RecdataU1);
//卧室LED开
if(strstr((char*)RecdataU1,"led1_on"))
{
USART0_Printf("卧室LED开.\n");
u8 buff[100]="B:1---";
//发送数据
tx_data(buff,strlen((char*)buff));
//运行状态灯
LED1 = !LED1;
}
//卧室LED关
else if(strstr((char*)RecdataU1,"led1_off"))
{
USART0_Printf("卧室LED关.\n");
u8 buff[100]="B:0---";
//发送数据
tx_data(buff,strlen((char*)buff));
//运行状态灯
LED1 = !LED1;
}
//客厅LED开
else if(strstr((char*)RecdataU1,"led2_on"))
{
USART0_Printf("客厅LED开.\n");
u8 buff[100]="C:1---";
//发送数据
tx_data(buff,strlen((char*)buff));
//运行状态灯
LED1 = !LED1;
}
//自动模式
else if(strstr((char*)RecdataU1,"yes_auto_mode"))
{
USART0_Printf("设置为自动模式.\n");
mode=1;
}
//手动模式
else if(strstr((char*)RecdataU1,"no_auto_mode"))
{
USART0_Printf("设置为手动模式.\n");
mode=0;
}
//阀值
else if(strstr((char*)RecdataU1,"value:"))
{
//运行状态灯
LED1 = !LED1;
char *p=strstr((char*)RecdataU1,"value:");
if(p)
{
int a=atoi(p+6);
if(a>0)
{
switch_val=a; //得到新的阀值
}
}
USART0_Printf("设置新的阀值:%d.\n",switch_val);
}
clearBuffU1(); //清理缓存
}
time_cnt++;
DelayMs(10);
//1秒钟时间到达
if(time_cnt>100)
{
time_cnt=0;
//读取ADC值--也就是光照传感器的值
GasData = ReadGasData();
//发送光照传感器的值到上位机
USART0_Printf("光照度:%d,模式:%d\n",GasData,mode);
//如果是自动模式
if(mode)
{
//根据阀值判断是否开启关闭卧室,客厅的LED灯
if(GasData > switch_val )
{
//开灯
u8 buff1[10]="B:1---";
//发送数据
tx_data(buff1,strlen((char*)buff1));
//开灯
u8 buff2[10]="C:1---";
//发送数据
tx_data(buff2,strlen((char*)buff2));
}
else
{
//关灯
u8 buff1[10]="B:0---";
//发送数据
tx_data(buff1,strlen((char*)buff1));
//关灯
u8 buff2[10]="C:0---";
//发送数据
tx_data(buff2,strlen((char*)buff2));
}
}
}
}
}