机智宝 发表于 2016-9-8 18:23:37

【Gokit2&ZigBee&STM32】之无线工业粉尘监测仪

手机也可实时监控无线工业粉尘,还能实现太阳能供电!!!!
原创申明:如转载请注明来源:http://club.gizwits.com/thread-3242-1-1.html


· 作品说明及使用场景
远程无线工业粉尘监测仪采用高精度激光粉尘传感器对工厂内的空气粉尘浓度进行监测,特别适合应用于汽车轮毂厂、铝镁打磨厂、抛光车间、电镀车间、面粉厂等易发生粉尘爆Zha的地方。粉尘监测仪采用STM32控制粉尘传感器并将数据通过串口传输到ZigBee终端设备,ZigBee终端设备通过ZigBee网络传输到ZigBee协调器,ZigBee协调器通过串口传输到Gokit2,Gokit2连接到路由器最终通过以太网连接到云服务器。做为公司的管理层能够通过手机远程实时的对工厂粉尘浓度进行监管,同时工厂管理室放置的ZigBee协调器连接着语音报警系统,现场便能通知粉尘超标报警信息。除此之外,作品还扩展了对温湿度监测的功能、太阳能充电及供电系统。
· 作品展示

http://v.youku.com/v_show/id_XMTY4ODI5MDUzNg==.html
代码下载: http://club.gizwits.com/static/image/filetype/rar.gif 无线工业粉尘监测仪代码.rar (11.13 MB, 下载次数: 69)
请各位小伙伴们多多指教

更多详情代码,原理图,教程,请移步到原帖:http://club.gizwits.com/thread-3242-1-1.html
项目硬件设计
首先规划一下作品设计思路,下面便画张鱼骨图来展示一下作品的总体规划,如果1所示。



图1 无线工业粉尘监测仪鱼骨图


       有了鱼骨图就有了设计的方向,先从鱼尾开始做起吧!首当其冲便是采集传感器数据,攀藤G1粉尘传感器采用STM32驱动并用串口接收传感器采集的数据。


图2 攀藤G1激光粉尘传感器


      传感数据无线传输依赖于ZigBee无线传感网络,因此搭建ZigBee网络是项目的核心之一。ZigBee组成网状网络,使数据能够绕过障碍物进行无线传输,能够在复杂的工厂环境中畅通无阻的将数据传输到控制室。


图3 ZigBee三大金刚

          数据传输到ZigBee协调器之后我们的Gokit2终于亮相了。ZigBee协调器通过串口与Gokit2连接,将ZigBee网络内收集到的数据传递给Gokit2,Gokit2再将数据传输到机智云,这时候就可以通过手机以及电脑获取实时的粉尘浓度信息了。由于Gokit2的设计对于我这种强迫症来说使用起来有点麻烦,于是稍微改装了一下,如图4图5所示。


图4 Gokit2下载开关改装


图5 Gokit2串口跳线改装

      改装完之后将ZigBee协调器通过杜邦线与Gokit2以及语音合成模块连接,连接完成之后将它们一下用螺母锁在亚克力板上。如图6图7图8所示。


图6 ZigBee协调器


图7 连接语音合成模块


图8 连接Gokit2

       前端的传感数据采集发送是项目的重中之重,花了好长时间才搭好这个平台。内含粉尘传感器一枚(采集粉尘浓度)、STM32开发板一块(粉尘传感器数据处理)、ZigBee终端节点一块(数据无线传输)、太阳能电源系统(供电)。各种跳线实在凌乱T T,太阳能电池板电源接反烧了一块ZigBee开发板。。。用亚克力板做了个外壳,能把东西塞进去就行,外观神马的因为手残也就只能这样了。。。


图9 前端内景-1


图10 前端内景-2


图11 前端上表面


图12 前端下表面


图13 无线工业粉尘监测仪全家福

项目软件设计

      开发环境: IAR For 8051 8.10.1(ZigBee-CC2530开发使用)、Keil V4 For ARM(Gokit2及STM32使用)
      代码依旧流程图编写



/*STM32main函数代码*/
#include "stm32f10x.h"
#include "usart1.h"
#include "Time_test.h"
#include "LCD12864.h"
volatile u32 time,time_LCD; // ms 计时变量
u8 PM_save;

/*
* 函数名:main
* 描述:主函数
* 输入:无
* 输出:无
*/

int main(void)
{      
      /* USART1 config 115200 8-N-1 */
      u8 i,LCD_PM1={"PM1.0:"},LCD_PM25={"PM2.5:"},LCD_PM10={"PM10:"};
      u8 LCD_PM1_DATA,LCD_PM25_DATA,LCD_PM10_DATA;
      u16 LCD_PM1_SAVE,LCD_PM25_SAVE,LCD_PM10_SAVE;
      SystemInit();
      TIM2_NVIC_Configuration();
          TIM2_Configuration();

      USART1_Config();//串口初始化
      lcdinit();//12864初始化
      NVIC_Configuration();
      
      write_com(0x03);
          delay(50);
      
      write_com(0x81);
      lcd_display(LCD_PM1);
      
      write_com(0x91);
      lcd_display(LCD_PM25);
      
      write_com(0x89);
      lcd_display(LCD_PM10);
      
      delay(50);
      write_com(0x01);//清屏
      START_TIME;//启动定时器
      while(1)
      {
                /* 每1000MS更新一次数据 */
                if(time_LCD > 1000)
                {
                        LCD_PM1_SAVE = PM_save*256 + PM_save;
                        LCD_PM1_DATA = LCD_PM1_SAVE/1000+'0';
                        LCD_PM1_DATA = LCD_PM1_SAVE/100%10+'0';
                        LCD_PM1_DATA = LCD_PM1_SAVE%100/10+'0';
                        LCD_PM1_DATA = LCD_PM1_SAVE%10+'0';
                        LCD_PM1_DATA = 0;
                        
                        LCD_PM25_SAVE = PM_save*256 + PM_save;
                        LCD_PM25_DATA = LCD_PM25_SAVE/1000+'0';
                        LCD_PM25_DATA = LCD_PM25_SAVE/100%10+'0';
                        LCD_PM25_DATA = LCD_PM25_SAVE%100/10+'0';
                        LCD_PM25_DATA = LCD_PM25_SAVE%10+'0';
                        LCD_PM25_DATA = 0;
                        
                        LCD_PM10_SAVE = PM_save*256 + PM_save;
                        LCD_PM10_DATA = LCD_PM10_SAVE/1000+'0';
                        LCD_PM10_DATA = LCD_PM10_SAVE/100%10+'0';
                        LCD_PM10_DATA = LCD_PM10_SAVE%100/10+'0';
                        LCD_PM10_DATA = LCD_PM10_SAVE%10+'0';
                        LCD_PM25_DATA = 0;
                        

                        write_com(0x84);
                        lcd_display(LCD_PM1_DATA);
                        write_com(0x94);
                        lcd_display(LCD_PM25_DATA);
                        write_com(0x8c);
                        lcd_display(LCD_PM10_DATA);
                        time_LCD =0;
                }

                /* 每5000MS将数据通过串口传输到ZigBee终端节点 */
                if(time>5000)
                {               
                        for(i=0;i<11;i++)
                                        {
                                                USART_SendData(USART2,PM_save);//发送数据
                                                while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);      
                                        }
                        time = 0;
                }

               
      }
}

/*ZigBee用户函数代码*/
#include "OSAL.h"
#include "ZGlobals.h"
#include "AF.h"
#include "aps_groups.h"
#include "ZDApp.h"

#include "SampleApp.h"
#include "SampleAppHw.h"

#include "OnBoard.h"

/* HAL */
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "MT_UART.h"
#include "MT.h"//消息命令ID定义头文件
#include "string.h"
#include "hal_voice.h"

const cId_t SampleApp_ClusterList =
{
SAMPLEAPP_PERIODIC_CLUSTERID,//广播簇ID
SAMPLEAPP_FLASH_CLUSTERID
};

const SimpleDescriptionFormat_t SampleApp_SimpleDesc =
{
SAMPLEAPP_ENDPOINT,            //int Endpoint;
SAMPLEAPP_PROFID,                //uint16 AppProfId;
SAMPLEAPP_DEVICEID,            //uint16 AppDeviceId;
SAMPLEAPP_DEVICE_VERSION,      //int   AppDevVer:4;
SAMPLEAPP_FLAGS,               //int   AppFlags:4;
SAMPLEAPP_MAX_CLUSTERS,          //uint8AppNumInClusters;
(cId_t *)SampleApp_ClusterList,//uint8 *pAppInClusterList;
SAMPLEAPP_MAX_CLUSTERS,          //uint8AppNumInClusters;
(cId_t *)SampleApp_ClusterList   //uint8 *pAppInClusterList;
};

endPointDesc_t SampleApp_epDesc;


uint8 SampleApp_TaskID;   // Task ID for internal task/event processing
// This variable will be received when
// SampleApp_Init() is called.
devStates_t SampleApp_NwkState;

uint8 SampleApp_TransID;// This is the unique message ID (counter)

afAddrType_t SampleApp_Periodic_DstAddr;//广播afAddrType_t类型数据
afAddrType_t SampleApp_Flash_DstAddr;
afAddrType_t Point_To_Point_DstAddr;

aps_Group_t SampleApp_Group;

uint8 SampleAppPeriodicCounter = 0;
uint8 SampleAppFlashCounter = 0;

/**********************************************
* LOCAL FUNCTIONS
*/
void SampleApp_HandleKeys( uint8 shift, uint8 keys );
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
void SampleApp_SendPointToPointMessage( uint8 *dat ) ;//点对点传播
void SampleApp_SerialCMD(mtOSALSerialData_t *cmdMsg);//数据接收处理
/**********************************************
* NETWORK LAYER CALLBACKS
*/

/**********************************************
* PUBLIC FUNCTIONS
*/

/**********************************************
* @fn      SampleApp_Init
*
* @brief   Initialization function for the Generic App Task.
*          This is called during initialization and should contain
*          any application specific initialization (ie. hardware
*          initialization/setup, table initialization, power up
*          notificaiton ... ).
*
* @param   task_id - the ID assigned by OSAL.This ID should be
*                  used to send messages and set timers.
*
* @returnnone
*/
void SampleApp_Init( uint8 task_id )
{
SampleApp_TaskID = task_id;
SampleApp_NwkState = DEV_INIT;
SampleApp_TransID = 0;

/********串口初始化************/
MT_UartInit();
MT_UartRegisterTaskID(SampleApp_TaskID);
HalUARTWrite(0,"uart init success\n" ,18);
/**************************/

//uint8 vol={0xfd,0x00,0x08,0x01,0x01,0x5b,0x76,0x30,0x31,0x5d,0x84};
//HalUARTWrite(1,vol,11);//减小音量


#if defined ( BUILD_ALL_DEVICES )
// The "Demo" target is setup to have BUILD_ALL_DEVICES and HOLD_AUTO_START
// We are looking at a jumper (defined in SampleAppHw.c) to be jumpered
// together - if they are - we will start up a coordinator. Otherwise,
// the device will start as a router.
if ( readCoordinatorJumper() )
    zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;
else
    zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;
#endif // BUILD_ALL_DEVICES

#if defined ( HOLD_AUTO_START )
// HOLD_AUTO_START is a compile option that will surpress ZDApp
//from starting the device and wait for the application to
//start the device.
ZDOInitDevice(0);
#endif


//Setup for the Point To Point destination address
Point_To_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//点对点短地址
Point_To_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
Point_To_Point_DstAddr.addr.shortAddr = 0x0000; //协调器地址

// Fill out the endpoint description.
SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_epDesc.task_id = &SampleApp_TaskID;
SampleApp_epDesc.simpleDesc
    = (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;
SampleApp_epDesc.latencyReq = noLatencyReqs;

// Register the endpoint description with the AF
afRegister( &SampleApp_epDesc );


uint8 test[]={"欢迎使用无线工业粉尘监测仪"},len=0;
len = sizeof(test);
voice_input(test,len);
}

/**********************************************
* @fn      SampleApp_ProcessEvent
*
* @brief   Generic Application Task event processor.This function
*          is called to process all events for the task.Events
*          include timers, messages and any other user defined events.
*
* @param   task_id- The OSAL assigned task ID.
* @param   events - events to process.This is a bit map and can
*                   contain more than one event.
*
* @returnnone
*/
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
{
afIncomingMSGPacket_t *MSGpkt;
(void)task_id;// Intentionally unreferenced parameter

if ( events & SYS_EVENT_MSG )
{
    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );
    while ( MSGpkt )
    {
      switch ( MSGpkt->hdr.event )
      {
      case CMD_SERIAL_MSG: //串口收到数据后由 MT_UART 层传递过来的
      SampleApp_SerialCMD((mtOSALSerialData_t *)MSGpkt);
      break;

      case AF_INCOMING_MSG_CMD:
      SampleApp_MessageMSGCB( MSGpkt );
      break;
      
      // Received whenever the device changes state in the network
      case ZDO_STATE_CHANGE:
      SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
      break;
      
      default:
      break;
      }
      
      // Release the memory
      osal_msg_deallocate( (uint8 *)MSGpkt );
      
      // Next - if one is available
      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );
    }
   
    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
}

return 0;
}


/*对接收到的串口数据进行处理*/
void SampleApp_SerialCMD(mtOSALSerialData_t *cmdMsg)
{
uint8 *str=NULL; //len 有用数据长度
str=cmdMsg->msg; //指向数据开头
if( (*(str+1) ==0x42) && (*(str+2) ==0x4D) )
    SampleApp_SendPointToPointMessage(str);//将数据通过广播发送
}

void SampleApp_HandleKeys( uint8 shift, uint8 keys )
{

}


/*协调器对接收到的数据进行处理*/
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
uint8 PM,WS;
switch ( pkt->clusterId )
{
case SAMPLEAPP_POINT_TO_POINT_CLUSTERID:
    if(pkt->cmd.Data == 0X42 && pkt->cmd.Data == 0X4d)//判断粉尘数据是否符合协议
    {
      /*协调器接收到终端节点的数据后对数据进行剪切*/
      uint16 PM1_0,PM2_5,PM10;
      PM = pkt->cmd.Data;
      PM = pkt->cmd.Data;
      PM = pkt->cmd.Data;
      PM = pkt->cmd.Data;
      PM = pkt->cmd.Data;
      PM = pkt->cmd.Data;
      PM = pkt->cmd.Data;
      PM = pkt->cmd.Data;
      PM = 0xdd;
      PM = 0xff;
      
      PM1_0 = (PM*256) + PM;
      PM2_5 = (PM*256) + PM;
      PM10 =(PM*256) + PM;
      if( (PM1_0 < PM2_5 < PM10) && (PM1_0<2000) &&(PM2_5<2000) && (PM10<2000))//判断粉尘浓度是否超过设定阈值
      {
      HalUARTWrite(0,PM,10);
      
      if(( PM1_0>1000) | (PM2_5>1000)| (PM10>1000) )
      {
          uint8 test[]={"警告警告粉尘浓度超标"},len=0;//发送报警信息到语音合成模块
          len = sizeof(test);
          voice_input(test,len);
      }
      }
      
    }
   
    if(pkt->cmd.Data == 0xaa && pkt->cmd.Data == 0xbb)//判断温湿度数据是否符合协议
    {
      WS = pkt->cmd.Data;
      WS = pkt->cmd.Data;
      WS = pkt->cmd.Data;
      WS = pkt->cmd.Data;
      WS = pkt->cmd.Data;
      WS = pkt->cmd.Data;
      WS = pkt->cmd.Data;
      WS = pkt->cmd.Data;
      WS = 0xdd;
      WS = 0xff;
      HalUARTWrite(0,WS,10);
      
      if(WS>0x30 )//判断温度是否超过设定阈值
      {
      uint8 test[]={"警告警告温度过高"},len=0;//发送报警信息到语音合成模块
      len = sizeof(test);
      voice_input(test,len);
      }
      if(WS>0x40 )////判断湿度浓度是否超过设定阈值
      {
      uint8 test[]={"警告警告湿度过高"},len=0;//发送报警信息到语音合成模块
      len = sizeof(test);
      voice_input(test,len);
      }
      break;
    }
}
}


/*点对点传输函数,终端节点用来发送点对点消息到协调器*/
void SampleApp_SendPointToPointMessage( uint8 *dat )
{
if ( AF_DataRequest( &Point_To_Point_DstAddr,
                      &SampleApp_epDesc,
                      SAMPLEAPP_POINT_TO_POINT_CLUSTERID,
                      *dat,//(byte)osal_strlen(dat),
                      dat,
                      &SampleApp_TransID,
                      AF_DISCV_ROUTE,
                      AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
    // Error occurred in request to send.
}
}
/**********************************************

**********************************************/
/*Gokit2代码*/
#include "gokit.h"

/*Global Variable*/
uint32_t ReportTimeCount = 0;
uint8_t gaterSensorFlag = 0;
uint8_t Set_LedStatus = 0;
uint8_t NetConfigureFlag = 0;
uint8_t curTem = 0, curHum = 0;
uint8_t lastTem = 0,lastHum = 0;

extern RingBuffer u_ring_buff;
uint8_t p0Flag = 0;

WirteTypeDef_t      WirteTypeDef;
ReadTypeDef_t      ReadTypeDef;
uint8_t Rx_sensor={0};//´«¸ÐÆ÷Êý¾Ý
extern uint8_t zb_count;
uint8_t Switch_LEDStatus = 0,Switch_WaterStatus = 0,Switch_AirStatus = 0,Switch_WaringStatus = 0;
/**
* @briefMain program.
* @paramNone
* @retval None
*/
int main(void)
{
      uint8_t p0_control_buf;
      
      SystemInit();      
      HW_Init();
      SW_Init();               
      while(1)
      {
                KEY_Handle();
                GizWits_MessageHandle(p0_control_buf, sizeof(WirteTypeDef_t));

               
    if(gaterSensorFlag != 0)
    {
      gaterSensorFlag = 0;
                  Zigbee_sensorData();//获取ZigBee串口传输的数据
                        GizWits_DevStatusUpgrade((uint8_t *)&ReadTypeDef, 10*60*1000, 1);//上传数据到机智云服务器
    }

      }
}
/** @addtogroup GizWits_HW_Init
* @{
*/
void HW_Init(void)
{
      Delay_Init(72);      
      UARTx_Init();
RGB_KEY_GPIO_Init();
      RGB_LED_Init();      
      LED_GPIO_Init();      
      KEY_GPIO_Init();
      TIM3_Int_Init(7199,9);   //ms interrupt      
      Motor_Init();      
      DHT11_Init();      
      IR_Init();      
}
/** @addtogroup GizWits_SW_Init
* @{
*/
void SW_Init()
{

      ReadTypeDef.PM1_0_H =0;
      ReadTypeDef.PM1_0_L =0;
      ReadTypeDef.PM2_5_H = 0;
      ReadTypeDef.PM2_5_L = 0;
      ReadTypeDef.PM10_H = 0;
      ReadTypeDef.PM10_L = 0;
      GizWits_init(sizeof(ReadTypeDef_t));
      printf("hello world\r\n");
      printf("Gokit Init Ok ...\r\n");
}
/** @addtogroup Printf_SystemRccClocks
* @{
*/
void Printf_SystemRccClocks(void)
{
      uint8_t SYSCLKSource;

      RCC_ClocksTypeDefSystemRCC_Clocks;
      printf("System start...\r\n");
      SYSCLKSource = RCC_GetSYSCLKSource();
      if(SYSCLKSource==0x04)
                printf("SYSCLKSource is HSE\r\n");
      else if(SYSCLKSource==0x00)
                printf("SYSCLKSource is HSI\r\n");
      else if(SYSCLKSource==0x08)
                printf("SYSCLKSource is PL!\r\n");
      
      RCC_GetClocksFreq(&SystemRCC_Clocks);
      printf("SYS clock =%dMHz \r\n",(uint32_t)SystemRCC_Clocks.SYSCLK_Frequency/1000000);
      printf("HCLK clock =%dMHz \r\n",(uint32_t)SystemRCC_Clocks.HCLK_Frequency/1000000);
      printf("PCLK1 clock =%dMHz \r\n",(uint32_t)SystemRCC_Clocks.PCLK1_Frequency/1000000);
      printf("PCLK2_clock =%dMHz \r\n",(uint32_t)SystemRCC_Clocks.PCLK2_Frequency/1000000);      
      printf("SADCCLK_Frequencyclock =%dMHz \r\n",(uint32_t)SystemRCC_Clocks.ADCCLK_Frequency/1000000);

}

/*Gokit2获取到ZigBee协调器传输的数据进行处理*/
void Zigbee_sensorData(void)
{
      uint8_t i;
      if( (Rx_sensor == 0x42) && (Rx_sensor == 0xFF) )//判断数据是否符合协议
      {
                ReadTypeDef.PM1_0_H = Rx_sensor;//保存数据到结构体中
                ReadTypeDef.PM1_0_L = Rx_sensor;//保存数据到结构体中
                ReadTypeDef.PM2_5_H = Rx_sensor;//保存数据到结构体中
                ReadTypeDef.PM2_5_L = Rx_sensor;//保存数据到结构体中
                ReadTypeDef.PM10_H = Rx_sensor;//保存数据到结构体中
                ReadTypeDef.PM10_L = Rx_sensor;//保存数据到结构体中
                printf("%s",Rx_sensor);//打印数据,方便调试
               

                for(i=0;i<10;i++)
                        {
                              Rx_sensor = 0;//清除数组为下一次数据保存
                        }
               zb_count =0;
      }
}
/*****************************************************
* Function Name: KEY_Handle
* Description    : Key processing function
* Input          : None
* Output         : None
* Return         : None
* Attention                        : None
*****************************************************/
void KEY_Handle(void)
{
      uint8_t Key_return =0;      
      Key_return = ReadKeyValue();      
      if(Key_return & KEY_UP)
      {
                if(Key_return & PRESS_KEY1)
                {
#ifdef PROTOCOL_DEBUG
                                  printf("KEY1 PRESS\r\n");
#endif               
                }
                if(Key_return & PRESS_KEY2)
                {
#ifdef PROTOCOL_DEBUG
                        printf("KEY2 PRESS ,Soft AP mode\r\n");
#endif      
                        //Soft AP mode, RGB red
                        LED_RGB_Control(255, 0, 0);
                        GizWits_D2WConfigCmd(SoftAp_Mode);
                        NetConfigureFlag = 1;
                }                              
      }

      if(Key_return & KEY_LONG)
      {
                if(Key_return & PRESS_KEY1)
                {
#ifdef PROTOCOL_DEBUG
                              printf("KEY1 PRESS LONG ,Wifi Reset\r\n");
#endif                        
                        GizWits_D2WResetCmd();
                }
                if(Key_return & PRESS_KEY2)
                {
                        //AirLink mode, RGB Green
#ifdef PROTOCOL_DEBUG
                              printf("KEY2 PRESS LONG ,AirLink mode\r\n");
#endif      
                        LED_RGB_Control(0, 128, 0);
                        GizWits_D2WConfigCmd(AirLink_Mode);
                        NetConfigureFlag = 1;
                }
      }
}
/*****************************************************
* Function Name: GizWits_WiFiStatueHandle
* Description    : Callback function , Judge Wifi statue
* Input          : None
* Output         : None
* Return         : Bit , Attr_Flags
* Attention               :
*****************************************************/
void GizWits_WiFiStatueHandle(uint16_t wifiStatue)
{      
      if(((wifiStatue & Wifi_ConnClouds) == Wifi_ConnClouds) && (NetConfigureFlag == 1))
      {
                printf("W2M->Wifi_ConnClouds\r\n");
                NetConfigureFlag = 0;
                LED_RGB_Control(0,0,0);
      }
}
/************* (C) COPYRIGHT 2011 STMicroelectronics ****END OF FILE***/

页: [1]
查看完整版本: 【Gokit2&ZigBee&STM32】之无线工业粉尘监测仪