新闻| 论坛| 博客| 在线研讨会
Zigbee基础实验(6)—简单通信编程
luker| 2016-02-25 14:20:08 阅读:3220 发布文章

实验中两节点分别充当开关和电灯,通过在开关节点上的操作来控制电灯节点。

源代码:

#include
#include
#include
#include
#include
#include
#include "hal_mcu.h"
#include "hal_button.h"
#include "hal_rf.h"
#include "util_lcd.h"
#include "basic_rf.h"

#define RF_CHANNEL 25 // 信道选择。

// 定义各个参数的值
#define PAN_ID 0x2007 //网络ID
#define SWITCH_ADDR 0x2520 //开关节点的地址
#define LIGHT_ADDR 0xBEEF //电灯节点的地址
#define APP_PAYLOAD_LENGTH 1 //负载字节的长度,信息的长度。
#define LIGHT_TOGGLE_CMD 0 //被传送的开关命令。

//节点状态。0为空闲
#define IDLE 0
#define SEND_CMD 1

// 定义该节点所承担的任务(开关或电灯)
#define NONE 0
#define SWITCH 1
#define LIGHT 2
#define APP_MODES 2

static uint8 pTxData[APP_PAYLOAD_LENGTH]; //发送数组
static uint8 pRxData[APP_PAYLOAD_LENGTH]; //接收数组
static basicRfCfg_t basicRfConfig;

// 模式选择菜单
static menuItem_t pMenuItems[] =
{
"Switch", SWITCH,
"Light", LIGHT
};

static menu_t pMenu =
{
pMenuItems,
N_ITEMS(pMenuItems)
};


static void appLight(); //实现电灯功能
static void appSwitch(); //实现远程开关功能
static uint8 appSelectMode(void); //功能选择

static void appLight() //实现电灯功能
{
halLcdWriteLine(HAL_LCD_LINE_1, "Light");
halLcdWriteLine(HAL_LCD_LINE_2, "Ready");

// 初始化射频模块
basicRfConfig.myAddr = LIGHT_ADDR; //网络地址
if(basicRfInit(&basicRfConfig)==FAILED) {
HAL_ASSERT(FALSE); //初始化错误处理
}
basicRfReceiveOn(); //打开接收功能。

//死循环
while (TRUE) {
while(!basicRfPacketIsReady());
if(basicRfReceive(pRxData, APP_PAYLOAD_LENGTH, NULL)0) { //如果接收到数据
if(pRxData[0] == LIGHT_TOGGLE_CMD) {
halLedToggle(1); //开关改变状态
}
}
}
}

static void appSwitch() //实现远程开关
{
halLcdWriteLine(HAL_LCD_LINE_1, "Switch"); //屏幕输出
halLcdWriteLine(HAL_LCD_LINE_2, "Joystick Push");
halLcdWriteLine(HAL_LCD_LINE_3, "Send Command");

pTxData[0] = LIGHT_TOGGLE_CMD; //需要发送的数据

// 初始化
basicRfConfig.myAddr = SWITCH_ADDR;
if(basicRfInit(&basicRfConfig)==FAILED) {
HAL_ASSERT(FALSE); //出错处理
}
basicRfReceiveOff(); //关闭接收机

// 死循环
while (TRUE) {
if( halJoystickPushed() ) { //当按键按下时触发
basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH);//发送命令
}
}
}

void main(void)
{
uint8 appMode = NONE; //模式变量

// 设置网络ID和信道
basicRfConfig.panId = PAN_ID;
basicRfConfig.channel = RF_CHANNEL;
basicRfConfig.ackRequest = TRUE;

//初始化其他设备
halBoardInit();
halJoystickInit();

// 初始化射频模块
if(halRfInit()==FAILED) {
HAL_ASSERT(FALSE);
}

halLedSet(1); //LED1灯亮,提示节点已上电

utilPrintLogo("Light Switch");

// 等待用户按下S1进入菜单
while (halButtonPushed()!=HAL_BUTTON_1);
halMcuWaitMs(350); //延时
halLcdClear(); //清屏

// 设置该节点是开关还是电灯
appMode = appSelectMode();
halLcdClear();

// 模块开始工作
if(appMode == SWITCH) {
appSwitch();
}
else if(appMode == LIGHT) {
appLight();
}
//如果没有定义该节点的功能,则LED灯不断闪烁
HAL_ASSERT(FALSE);
}

static uint8 appSelectMode(void) //模式选择
{
halLcdWriteLine(1, "Device Mode: ");
return utilMenuSelect(&pMenu); //通过调用头文件实现功能选择
}

实验总结:
这个实验虽然功能非常简单,只是通过按下开关节点的按键来控制电灯节点LED的亮或灭,但是通过这个实验可以了解节点间通信的基本思路。
原代码中有许多可有可无的冗余代码,上面的代码经过代码中很多都是调用头文件,在这里就不在一一罗列,只在代码注释中注明该调用的功能。这些调用都是一些非常简单的操作,写入头文件调用是为了增加代码可读性。

baseRF通信基本流程
1.初始化网络地址,打开接收机或关闭接收机。
2.初始化basicRfConfig,确定网络ID、信道、是否需要应答、是否采用加密机制等。
3.初始化周边设备,如时钟、各个I/O口等。
4.事件的处理,如发送报文或接受报文后的数据处理等。

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客