基于CC2530(ZigBee)设计的自动照明系统

描述

 1. 功能介绍

设计题目的名称: 基于ZigBee的自动照明系统设计

一共使用3个CC2530 ZigBee开发板,代号分别为ABC。

A开发板当做主机: 上面连接了光感传感器,ESP8266WIFI模块。通过ESP8266与手机APP之间通信,ESP8266创建热点,配置为TCP服务器模式; 手机APP连接上ESP8266的热点之后,再连接ESP8266创建的服务器,完成通信。 手机APP上通过按钮可以控制B,C开发板上LED灯的开关。

手机APP上可以设置自动照明的模式:

自动照明模式: 根据A开发板上的光感模块,采集光照强度,控制B、C开发板上的LED灯开关。

手动模式: 手机APP 上可以选择单独控制B、C开发板上的LED灯开关。

支持设置光感阀值: 在手机APP上可以设置A开发板的光感传感器阀值(也就是控制灯亮灭的阀值)。

支持设置亮度,也可以自动根据环境光控制亮度

B开发板当做从机节点: B开发板上使用板载的LED灯,模拟家里卧室的照明设备,实现控制效果演示。

C开发板当做从机节点: C开发板上使用板载的LED灯,模拟家里客厅的照明设备,实现控制效果演示。

CC2530

 

CC2530

 

CC2530

 

 

2. 硬件介绍

2.1 ESP8266 wifi

采用的ESP8266系列无线模块是高性价比WIFI SOC模组,该系列模块支持标准的IEEE802.11b/g/n协议,内置完整的TCP/IP协议栈。用户可以使用该系列模块为现有的设备添加联网功能,也可以构建独立的网络控制器。

CC2530开发板上本身就有一个ESP8266专用的接口,插上去就行了。

ES8266 WIFI 模块接在 串口1 上面(P0.4/P0.5口) ,波特率为 115200 。

CC2530的串口0作为常规调试串口(P0_2和P0_3端口),可以把采集的AD数据打印到串口。 也可以自己打印其他一些调试信息。

CC2530

 

CC2530

 

CC2530

 

2.2 光敏传感器

CC2530CC2530

​编辑

CC2530

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--)
            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);   
}
CC2530

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));    
               }
          }
       }
    }
}
CC2530


 

​  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
评论(0)
发评论
jf_46267315 2023-04-27
0 回复 举报
请问大佬是采用什么软件开发平台做的上位机软件呀? 收起回复

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分