完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
第一个实验是这样的,终端给协调器发送 D1 ,协调器接收到以后LED1闪烁并给终端发送 D1使终端LED1也闪烁。下面是sampleApp.c的代码。我有几个不懂的地方:
1.所有用户任务程序都是写在sampleApp.c里,终端和协调运行程序时处理事件顺序是怎么规定的。 2.以下程序怎么实现终端先给协调器发D1,然后协调器给终端再发D1。 3.程序中有写组播方式,和广播方式 ,最后为什么又是广播发送的。 void SampleApp_Init( uint8 task_id ) { SampleApp_TaskID = task_id; //osal分配的任务ID随着用户添加任务的增多而改变 SampleApp_NwkState = DEV_INIT;//设备状态设定为ZDO层中定义的初始化状态 SampleApp_TransID = 0; //消息发送ID(多消息时有顺序之分) // 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 //该段的意思是,如果设置了HOLD_AUTO_START宏定义,将会在启动芯片的时候会暂停启动 //流程,只有外部触发以后才会启动芯片。其实就是需要一个按钮触发它的启动流程。 #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;//组号0x0001 // Fill out the endpoint description. 定义本设备用来通信的APS层端点描述符 SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT; //指定端点号 SampleApp_epDesc.task_id = &SampleApp_TaskID; //SampleApp 描述符的任务ID SampleApp_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;//SampleApp简单描述符 SampleApp_epDesc.latencyReq = noLatencyReqs; //延时策略 // Register the endpoint description with the AF afRegister( &SampleApp_epDesc ); //向AF层登记描述符 // 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 );//把该组登记添加到APS中 #if defined ( LCD_SUPPORTED ) HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 ); //如果支持LCD,显示提示信息 #endif } /********************************************************************* * @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. * * @return none */ //用户应用任务的事件处理函数 uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; (void)task_id; // Intentionally unreferenced parameter if ( events & SYS_EVENT_MSG ) //接收系统消息再进行判断 { //接收属于本应用任务SampleApp的消息,以SampleApp_TaskID标记 MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); while ( MSGpkt ) { switch ( MSGpkt->hdr.event ) { // Received when a key is pressed case KEY_CHANGE://按键事件 SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; // Received when a messages is received (OTA) for this endpoint case AF_INCOMING_MSG_CMD://接收数据事件,调用函数AF_DataRequest()接收数据 SampleApp_MessageMSGCB( MSGpkt );//调用回调函数对收到的数据进行处理 break; // Received whenever the device changes state in the network case ZDO_STATE_CHANGE: //只要网络状态发生改变,就通过ZDO_STATE_CHANGE事件通知所有的任务。 //同时完成对协调器,路由器,终端的设置 SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status); //if ( (SampleApp_NwkState == DEV_ZB_COORD)//实验中协调器只接收数据所以取消发送事件 if ( (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE) ) { // Start sending the periodic message in a regular interval. //这个定时器只是为发送周期信息开启的,设备启动初始化后从这里开始 //触发第一个周期信息的发送,然后周而复始下去 osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT ); } else { // Device is no longer in the network } break; default: break; } // Release the memory 事件处理完了,释放消息占用的内存 osal_msg_deallocate( (uint8 *)MSGpkt ); // Next - if one is available 指针指向下一个放在缓冲区的待处理的事件, //返回while ( MSGpkt )重新处理事件,直到缓冲区没有等待处理事件为止 MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); } // return unprocessed events 返回未处理的事件 return (events ^ SYS_EVENT_MSG); } // Send a message out - This event is generated by a timer // (setup in SampleApp_Init()). if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) { // Send the periodic message 处理周期性事件, //利用SampleApp_SendPeriodicMessage()处理完当前的周期性事件,然后启动定时器 //开启下一个周期性事情,这样一种循环下去,也即是上面说的周期性事件了, //可以做为传感器定时采集、上传任务 SampleApp_SendPeriodicMessage(); // Setup to send message again in normal period (+ a little jitter) osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) ); // return unprocessed events 返回未处理的事件 return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT); } // Discard unknown events return 0; } /********************************************************************* * Event Generation Functions */ /********************************************************************* * @fn SampleApp_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. Valid entries: * HAL_KEY_SW_2 * HAL_KEY_SW_1 * * @return none */ void SampleApp_HandleKeys( uint8 shift, uint8 keys ) //此实验没有用到,后面再分析 { (void)shift; // Intentionally unreferenced parameter if ( keys & HAL_KEY_SW_1 ) { /* This key sends the Flash Command is sent to Group 1. * This device will not receive the Flash Command from this * device (even if it belongs to group 1). */ SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION ); } if ( keys & HAL_KEY_SW_2 ) { /* The Flashr Command is sent to Group 1. * This key toggles this device in and out of group 1. * If this device doesn't belong to group 1, this application * will not receive the Flash command sent to group 1. */ aps_Group_t *grp; grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); if ( grp ) { // Remove from the group aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); } else { // Add to the flash group aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); } } } /********************************************************************* * LOCAL FUNCTIONS */ /********************************************************************* * @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; byte buf[3]; switch ( pkt->clusterId ) //判断簇ID { case SAMPLEAPP_PERIODIC_CLUSTERID: //收到广播数据 osal_memset(buf, 0 , 3); osal_memcpy(buf, pkt->cmd.Data, 2); //复制数据到缓冲区中 if(buf[0]=='D' && buf[1]=='1') //判断收到的数据是否为"D1" { HalLedBlink(HAL_LED_1, 0, 50, 500);//如果是则Led1间隔500ms闪烁 #if defined(ZDO_COORDINATOR) //协调器收到"D1"后,返回"D1"给终端,让终端Led1也闪烁 SampleApp_SendPeriodicMessage(); #endif } else { HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); } 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; } } /********************************************************************* * @fn SampleApp_SendPeriodicMessage * * @brief Send the periodic message. * * @param none * * @return none */ //分析发送周期信息 void SampleApp_SendPeriodicMessage( void ) { byte SendData[3]="D1"; // 调用AF_DataRequest将数据无线广播出去 if( AF_DataRequest( &SampleApp_Periodic_DstAddr,//发送目的地址+端点地址和传送模式 &SampleApp_epDesc,//源(答复或确认)终端的描述(比如操作系统中任务ID等)源EP SAMPLEAPP_PERIODIC_CLUSTERID, //被Profile指定的有效的集群号 2, // 发送数据长度 SendData,// 发送数据缓冲区 &SampleApp_TransID, // 任务ID号 AF_DISCV_ROUTE, // 有效位掩码的发送选项 AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) //传送跳数,通常设置为AF_DEFAULT_RADIUS { } else { HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); // Error occurred in request to send. } } /********************************************************************* * @fn SampleApp_SendFlashMessage * * @brief Send the flash message to group 1. * * @param flashTime - in milliseconds * * @return none */ void SampleApp_SendFlashMessage( uint16 flashTime ) //此实验没有用到,后面再分析 { uint8 buffer[3]; buffer[0] = (uint8)(SampleAppFlashCounter++); buffer[1] = LO_UINT16( flashTime ); buffer[2] = HI_UINT16( flashTime ); if ( AF_DataRequest( &SampleApp_Flash_DstAddr, &SampleApp_epDesc, SAMPLEAPP_FLASH_CLUSTERID, 3, buffer, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { } else { // Error occurred in request to send. } } |
|
相关推荐
4个回答
|
|
来人啊 来人啊
|
|
|
|
不知道你现在搞懂没有,其实我早就看到你帖子,但是你的问题,我需要敲个长篇大论啊,所以一直没回,你要是还没解决,那我今天有时间的时候,给你回复把,就当练习打字了
|
|
|
|
我的想法是不用讲理论的 因为资料上都有,我现在的想法是可不可以直接告诉我这个板子上哪些部分属于端口,这样我再结合 资料看看
|
|
|
|
你有资料不去看,来这里问...我当初就没你这魄力,端口的话是指?endpoint?那看看这个帖子:http://blog.sina.com.cn/s/blog_7ca994b80100tsg5.html
|
|
|
|
只有小组成员才能发言,加入小组>>
如何使用STM32+nrf24l01架构把有线USB设备无线化?
2571 浏览 7 评论
请问能利用51单片机和nRF24L01模块实现实时语音无线传输吗?
2366 浏览 5 评论
3212 浏览 3 评论
2839 浏览 8 评论
为什么ucosii上移植lwip后系统进入了HardFault_Handler?
2791 浏览 4 评论
请教各位大咖:有没有接收频率32M左右的芯片推荐的?先感谢啦!
669浏览 1评论
906浏览 0评论
1027浏览 0评论
672浏览 0评论
500浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 22:10 , Processed in 1.231181 second(s), Total 84, Slave 68 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号