标签:
要做到目视千里,耳听八方是人类长久的梦想,现代卫星技术的出现虽然使人们离这目标又进了一步,但卫星高高在上,洞察全局在行,明察细微就不管用了。这个时候,本文的主角—无线传感器网络就排上用场了。将大量的传感器节点遍撒指定区域,数据通过无线电波传回监控中心,监控区域内的所有信息就会尽收观察者的眼中了。
闲话不说,直接进入正题。想让传感数据回来,总得有一套可以“采集传感器数据,打包发送数据给上层”的系统,这里就程序简单说明一下该系统的实现。
主开发程序在/ZStack-CC2530-2.3.0-1.4.0/Projects/zstack/Samples目录下,开发环境是IAR,开发语言C。
该系统具备的功能:
程序基本思路如下:
1、初始化操作
由于节点需要用到UART callback,所以串口需要重新配置,在init()函数中,重新以下部分:
/********************************************************************* * @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. * * @return none */ void SampleApp_Init( uint8 task_id ) { // look out ************************************************************************* halUARTCfg_t uartConfig; SampleApp_TaskID = task_id; SampleApp_NwkState = DEV_INIT; SampleApp_TransID = 0; //初始化io P0SEL &= 0xBF; P0DIR |= 0x40; // // MT_UartInit(); //串口初始化 uartConfig.configured = TRUE; // 2x30 don‘t care - see uart driver. uartConfig.baudRate = SAMPLE_APP_BAUD; uartConfig.flowControl = FALSE; uartConfig.flowControlThreshold = SAMPLE_APP_THRESH; // 2x30 don‘t care - see uart driver. uartConfig.rx.maxBufSize = SAMPLE_APP_RX_SZ; // 2x30 don‘t care - see uart driver. uartConfig.tx.maxBufSize = SAMPLE_APP_TX_SZ; // 2x30 don‘t care - see uart driver. uartConfig.idleTimeout = SAMPLE_APP_IDLE; // 2x30 don‘t care - see uart driver. uartConfig.intEnable = TRUE; // 2x30 don‘t care - see uart driver. uartConfig.callBackFunc = SampleApp_CallBack; HalUARTOpen (SAMPLE_APP_PORT, &uartConfig); MT_UartRegisterTaskID(task_id); //注册串口任务 HalUARTWrite(0,"UartInit OK\n", sizeof("UartInit OK\n"));//提示信息 osal_pwrmgr_task_state(task_id,PWRMGR_CONSERVE); //休眠功能初始化 // look out ************************************************************************* // Device hardware initialization can be added here or in main() (Zmain.c). // If the hardware is application specific - add it here. // If the hardware is other parts of the device add it in main(). #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 periodic message‘s destination address // Broadcast to everyone SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF; // Setup for the flash command‘s destination address - Group 1 SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP; // 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 ); // Register for all key events - This app will handle all key events RegisterForKeys( SampleApp_TaskID ); // By default, all devices start out in Group 1 SampleApp_Group.ID = 0x0001; osal_memcpy( SampleApp_Group.name, "Group 1", 7 ); aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); #if defined ( LCD_SUPPORTED ) HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 ); #endif }
2、接收节点调用协议栈的无线数据接收函数
/********************************************************************* * @fn SampleApp_MessageMSGCB * * @brief Data message processor callback. This function processes * any incoming data - probably from other devices. So, based * on cluster ID, perform the intended action. * * @param none * * @return none */ void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) //接收数据 { uint16 flashTime; switch ( pkt->clusterId ) { case SAMPLEAPP_PERIODIC_CLUSTERID: //HalUARTWrite(0, "Rx:", 3); //prompt message HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); //send the message to GPRS //HalUARTWrite(0, "\n", 1); break; case SAMPLEAPP_FLASH_CLUSTERID: flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] ); HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) ); break; } }
3、终端跟传感器相互通信的时候一定注意延时的重要性!
/********************************************************************* * @fn SampleApp_SendPeriodicMessage * * @brief Send the periodic message. * * @param none * * @return none */ void SampleApp_SendPeriodicMessage( void ) { osal_pwrmgr_device(PWRMGR_ALWAYS_ON); //唤醒 Delay_s(1); P0_6 = 0; Delay_ms(1); P0_6 = 1; Delay_ms(1); P0_6 = 0; Delay_ms(1); Delay_s(6); ifSendData = false; // // 发送唤醒指令。。。。 HalUARTWrite(0, Let_On_Cmd, 5); HalUARTPoll(); // 唤醒LED2 HalLedSet(HAL_LED_1, HAL_LED_MODE_TOGGLE); // 等待,等待发送数据 Delay_s(5); // 监测是否有UART数据,如果有,发送UART数据;如果没有,发送data中封装的数据 //发送心跳 if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 26, packagedata, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { HalLedSet(HAL_LED_3, HAL_LED_MODE_TOGGLE); } // 发送休眠指令。。。。 HalUARTWrite(0, Let_Off_Cmd, 5); // HalUARTPoll(); // 关闭LED2 Delay_s(10); osal_pwrmgr_device(PWRMGR_BATTERY); //休眠 } /********************************************************************* * @fn SampleApp_CallBack * * @brief Send data OTA. * * @param port - UART port. * @param event - the UART port event flag. * * @return none */ static void SampleApp_CallBack(uint8 port, uint8 event) { (void)port; if ((event & (HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT)) && #if SAMPLE_APP_LOOPBACK (SampleApp_TxLen < SAMPLE_APP_TX_MAX)) #else !SampleApp_TxLen) #endif { SampleApp_Send(); } } /********************************************************************* * @fn SampleApp_Send * * @brief Send data OTA. * * @param none * * @return none */ static void SampleApp_Send(void) { #if SAMPLE_APP_LOOPBACK if (SampleApp_TxLen < SAMPLE_APP_TX_MAX) { SampleApp_TxLen += HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf+SampleApp_TxLen+1, SAMPLE_APP_TX_MAX-SampleApp_TxLen); } if (SampleApp_TxLen) { (void)SampleApp_TxAddr; if (HalUARTWrite(SAMPLE_APP_PORT, SampleApp_TxBuf+1, SampleApp_TxLen)) { SampleApp_TxLen = 0; } else { osal_set_event(SampleApp_TaskID, SAMPLEAPP_SEND_EVT); } } #else if (!SampleApp_TxLen && (SampleApp_TxLen = HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf+1, SAMPLE_APP_TX_MAX))) { // Pre-pend sequence number to the Tx message. //SampleApp_TxBuf[0] = ++SampleApp_TxSeq; pocessdata(SampleApp_TxBuf, SampleApp_TxLen); } if (SampleApp_TxLen) { if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, (endPointDesc_t *)&SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 26, finaldata,/**/ &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { HalLedSet (HAL_LED_2, HAL_LED_MODE_TOGGLE); //设置灯状态 Delay_ms(2); SampleApp_TxLen = 0; Delay_ms(2); ifSendData = true; Delay_ms(2); int clear; for(clear=0; clear<25; clear++){ finaldata[clear] = 0; } } else { // SampleApp_TxBuf[0] = 0; osal_set_event(SampleApp_TaskID, SAMPLEAPP_SEND_EVT); } } #endif }
4、打包数据校验策略
uint8 errorflag(uint8 *data, int length) { int i; uint8 crc; jiaoyan=(*(data + 2)) ^ (*(data + 3)); for(i = 4; i <= 22; i++) crc = crc ^ (*(data + i)); if(crc == (*(data + length))) return 1; //奇偶校验是正确的 else return 0; }
详细请参考:https://github.com/zlcxbb/ZStack-CC2530-2.3.0-1.4.0
标签:
原文地址:http://www.cnblogs.com/zlcxbb/p/4637459.html