当前位置: > 华清远见教育科技集团 > 嵌入式学习 > 讲师博文 > AT86RF231zigbee的使用一
AT86RF231zigbee的使用一
时间:2016-12-14作者:华清远见

电路如图所示:

其中控制芯片使用SAM3S4B,通过SPI格式(单一的SAM3S4B为主端,AT86RE231为从端)与AT86RF231进行通讯,AT86RF231是一款工业级,低电压供电,超低功耗,方便操作,遵循IEEE802.15.4-2006 硬件标准。AT86RF231将控制信号转换为zigbee模式的差分对信号,通过2.45Ghz的谐波滤波器2450FB15L0001滤波后接入天线与其余zigbee端点进行通讯,2450FB15L0001主要是对接受到得zigbee信号进行滤波。

Zigbee框架下编译程序,需要进行些简单的设置,

因为处与zigbee协议栈框架中,部分源码被atmel,封装起来,在man函数中,SYS_sysinit();系统初始化给出.h文件,而没有具体的C代码。这意味ZIGBEE的具体结构核心部分不是开源的。实际中SYS_sysinit()在libBc_All_At91sam3s4c_Rf231_Iar.a中,该文件被封装起来。

其中,对bitcloud编译生成的是libHAL_Sam3sEkRf2xx_At91sam3s4c_64Mhz_Iar.a。 这里面即便被封住,我们可以进入bitcloud源码内,解读代码,如WTD操作,HAL_InstallInterruptVector(),TimeTick_Configure()还是可以进行代码解读的。那对zigbee格式下的函数应该怎样跟踪解析代码:例如pio.h中,PIO_Configure();无法看到C代码的实现过程。可以鼠标右击pio.h文件(见下图1),open containing folder,打开文件夹,找到include中的pio.h文件,可以推测出点C文件如果有,应该存在于source中。进行代码解读。


图1

在下面历程中,给出协调器和节点的实现。

协调器部分程序:

int main(void)
        {
                //初始化,相关系统配置
                SYS_SysInit();
                ..
                ..
                for(;;)
                {
                        //数据处理
                        ..
                        ..
                        SYS_RunTask();
                }
        }

SYS_SysInit();函数是系统的函数,用来初始化系统的硬件;

SYS_RunTask();是调用zigbee的入口函数,会调用BitCloud协议栈中的用户应用程序,即APL_TaskHandler();

voidAPL_TaskHandler(void)
        {
                switch (appState)
                {
                        case APP_INITIAL_STATE:
                        initHardware();
                        initNetwork();
                        break;
                        case APP_JOINING_STATE:
                        startNetwork();
                        break;
                        case APP_JOINED_STATE:
                        break;
                        default:
                        break;
                }
        }

APL_TaskHandler();这个函数类似个有限状态机,是zigbee所处状态的处理,程序在初始化时static AppState_tappState = APP_INITIAL_STATE;

如果没有添加入网络,或者从网络中断掉,在主程序每次循环的时候,会添加入网络,如果是已将处于zigbee网络中,则处于APP_JOINED_STATE状态,直接退出APL_TaskHandler()函数。

我们可以看下具体状态下的子函数;

硬件初始化只是配置个LED,当zigbee网络正常工作时,led1常亮状态,否认闪亮。

static void initHardware(void)
        {
                LED_Configure(APP_LED_0);
                LED_Configure(APP_LED_1);
        }

而对协调器的配置是zigbee配置的关键部分,下面一段代码将本身配置为协调器,并在网络中定义两个节点。

static void initNetwork(void)
        {
                DeviceType_tdeviceType = DEVICE_TYPE_COORDINATOR; //配置成协调器
                CS_WriteParameter(CS_DEVICE_TYPE_ID, &deviceType);
                boolpredefPANID = true;
                uint16_tnwkPANID = 0x1000;
                CS_WriteParameter(CS_NWK_PREDEFINED_PANID_ID, &predefPANID);
                CS_WriteParameter(CS_NWK_PANID_ID, &nwkPANID);//add by jacky

                // 定义数据节点0
                apsDataReq.dstAddrMode = APS_SHORT_ADDRESS;
                apsDataReq.dstAddress.shortAddress = 0;
                apsDataReq.profileId = APP_PROFILE_ID;
                apsDataReq.dstEndpoint = APP_DATA_ENDPOINT;//0X20
                apsDataReq.clusterId = APP_CLUSTER_ID;
                apsDataReq.srcEndpoint = APP_DATA_ENDPOINT;//0X20
                apsDataReq.asdu = (uint8_t *)sensor_buf;
                apsDataReq.asduLength = sizeof(execute_buf);//传输数据
                apsDataReq.txOptions.acknowledgedTransmission = 0;
                apsDataReq.radius = 0;
                apsDataReq.APS_DataConf = apsDataReqConf;

                // 定义数据节点1
                apsDataReq1.dstAddrMode = APS_SHORT_ADDRESS;
                apsDataReq1.dstAddress.shortAddress = 0;
                apsDataReq1.profileId = APP_PROFILE_ID;
                apsDataReq1.dstEndpoint = 0x40;
                apsDataReq1.clusterId = APP_CLUSTER_ID;
                apsDataReq1.srcEndpoint = 0x40;
                apsDataReq1.asdu = (uint8_t *)execute_buf;
                apsDataReq1.asduLength = sizeof(execute_buf);//传输数据
                apsDataReq1.txOptions.acknowledgedTransmission = 0;
                apsDataReq1.radius = 0;
                apsDataReq1.APS_DataConf = apsDataReqConf1;

                appState = APP_JOINING_STATE;
                SYS_PostTask(APL_TASK_ID);
        }

初始化结束后会改变appState的状态,appState = APP_JOINING_STATE; 进行网络的加入操作,使用SYS_PostTask(APL_TASK_ID);来投递任务,让系统再次调用APL_TaskHandler() 去执行case APP_JOINING_STATE进而去执行startNetwork()函数。

startNetwork()创建一个定时器用来控制led的亮灭来表示网络的连接状态,在注册一个网络连接确认的回调函数。

static void startNetwork(void)
        {
                blinkTimer.interval = BLINK_TIMER_INTERVAL;
                blinkTimer.mode = TIMER_REPEAT_MODE;
                blinkTimer.callback = blinkTimerFired;
                HAL_StartAppTimer(&blinkTimer);
                startNetworkReq.ZDO_StartNetworkConf = ZDO_StartNetworkConf;//回调函数
                ZDO_StartNetworkReq(&startNetworkReq);
        }

回调函数中,主要是判断zigbee网络连接,连接成功,关闭定时器和注册网络节点。

static void ZDO_StartNetworkConf(ZDO_StartNetworkConf_t* conf)
        {
                HAL_StopAppTimer(&blinkTimer); //add by lht
                if (ZDO_SUCCESS_STATUS == conf->status)
                {
                        appState = APP_JOINED_STATE;
                        // 注册网络节点0
                        registerDataEndpointReq.simpleDescriptor = &dataEndpoint;
                        registerDataEndpointReq.APS_DataInd = APS_DataIndData;
                        APS_RegisterEndpointReq(&registerDataEndpointReq);

                        // 注册网络节点1
                        registerDataEndpointReq1.simpleDescriptor = &dataEndpoint1;
                        registerDataEndpointReq1.APS_DataInd = APS_DataIndData1;
                        APS_RegisterEndpointReq(&registerDataEndpointReq1);

                }
                else
                {
                        appState = APP_JOINING_STATE;
                }
                SYS_PostTask(APL_TASK_ID);
        }

zigbee数据发送函数:

static void sendDataBlock(unsigned char channel)
        {
                switch(channel)
                {
                        case Sensor:
                        APS_DataReq(&apsDataReq);
                        break;
                        case Execute:
                        APS_DataReq(&apsDataReq1);
                        break;
                        default:
                        break;
                }
        }

zigbee数据接受函数:

static void APS_DataIndData(APS_DataInd_t *ind) //data come from sensor module
        {
                zigbee_in_flag = 1;
                memcpy(&sensor_data[1],ind->asdu, 18);
                sensor_from_address = ind->srcAddress.shortAddress;
        }
        static void APS_DataIndData1(APS_DataInd_t *ind) //data come from excute module
        {
                memcpy(init_data,ind->asdu, 30);
                to_excute_address = ind->srcAddress.shortAddress;
                if(init_data[0] == 0xaa)
                {
                        enable_count = 1;
                        excute_open = 1;
                }
        }

在zigbee的节点函数APL_TaskHandler(),与协调器程序中多的状态是:离开zigbee网络,定义的宏是APP_LEAVE_STATE。

voidAPL_TaskHandler(void)
        {
                switch (appState)
                {
                        case APP_INITIAL_STATE:
                    &nbnbsp;   initHardware();
                        initNetwork();
                        break;
                        case APP_JOINING_STATE:
                        startNetwork();
                        break;
                        case APP_JOINED_STATE:
                        break;
                        case APP_LEAVE_STATE:
   &nbsnbsp;                    leaveNetwork();
                        break;
                        case APP_LEAVING_STATE:
                        break;
                        default:
                        break;
                }
        }

发表评论
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)