zigbee

总体方向:

单片机的部分就不需要学习了,主要学习zigbee和主控部分前端部分会基本的改就行。

一、了解zigbee在物联网通信协议中的位置

在这里插入图片描述

云端协议:

在这里插入图片描述

网关协议:

在这里插入图片描述

现在长距离一般都使用wifi而这些一般都是有插电的比如冰箱洗衣机等,而短距离就用蓝牙因为省电。我们项目使用zigbee目的是为了便于学习。

二、zigbee是如何建立网络的(只需了解,不需要我们实现)

协调器如何加入网络:

在这里插入图片描述

节点如何加入网络:

在这里插入图片描述

三、如何使用zigbee(首先要安装zigbee协议用IAR软件打开并编写)

在这里插入图片描述

分析zigbee系统:

在这里插入图片描述

总:
main
	->osal_init_system();//初始化操作系统
	->osal_start_system(); // No Return from here// 执行操作系统,进去后不会返回
初始化:
osal_init_system
	->osalInitTasks();//初始化系统任务
		->ZDApp_Init( taskID++ );//ZDApp_Init(4) ,用户需考虑(不太重要)
		->GenericApp_Init( taskID ); //用户自定义初始化(节点,协调器,路由器各有定义)重要

协调器初始化:

GenericApp_Init
	...
	GenericApp_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;//协调器对应AddrBroadcast
  	GenericApp_DstAddr.endPoint = GENERICAPP_ENDPOINT;//都一样
  	GenericApp_DstAddr.addr.shortAddr = 0xFFFF;//地址自己定,不与其他一样就行
  	...
  	//协调器需要串口与Linux通信,初始化串口
    halUARTCfg_t uartConfig; 
    uartConfig.configured = TRUE; 
    uartConfig.baudRate = HAL_UART_BR_115200; 
    uartConfig.flowControl = FALSE; 
    uartConfig.flowControlThreshold = 1; 
    uartConfig.rx.maxBufSize = 255; 
    uartConfig.tx.maxBufSize = 255; 
    uartConfig.idleTimeout = 1; 
    uartConfig.intEnable = TRUE; 
    uartConfig.callBackFunc = rxCB; 
    HalUARTOpen (HAL_UART_PORT_0, &uartConfig);
  	//初始化lcd
  	HalLcdInit();
  	clear_lcd();

节点初始化:

GenericApp_Init:
	...
	GenericApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//节点对应Addr16Bit
	GenericApp_DstAddr.endPoint = GENERICAPP_ENDPOINT;
	GenericApp_DstAddr.addr.shortAddr = 0x0000;
	...
	//硬件初始化
	InitBeep();
	InitLed();
	InitRelay();
    	    
	Init_infrare();
	HalLcdInit();
	clear_lcd()
开始任务:
osal_start_system
	->osal_run_system
		->events = (tasksArr[idx])( idx, events );//通过指针调用任务处理函数,关键,执行taskarr中的函数
const pTaskEventHandlerFn tasksArr[] = {
      macEventLoop,
      nwk_event_loop,
      Hal_ProcessEvent,
    #if defined( MT_TASK )
      MT_ProcessEvent,
    #endif
      APS_event_loop,
    #if defined ( ZIGBEE_FRAGMENTATION )
      APSF_ProcessEvent,
    #endif
      ZDApp_event_loop,
    #if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
      ZDNwkMgr_event_[]loop,
    #endif
      GenericApp_ProcessEvent//只有它不是三者共用的,用于事件发生时的处理函数
};

协调器:

串口接收到中断,发送命令给节点:

static void rxCB(uint8 port,uint8 event)
	....
	if(AF_DataRequest( &GenericApp_DstAddr, &GenericApp_epDesc,
		GENERICAPP_CLUSTERID,//字节的节点id
		1,//发送字节数
        &cmd,//发送消息
        &GenericApp_TransID,  //0
        AF_DISCV_ROUTE, AF_DEFAULT_RADIUS )==afStatus_SUCCESS)
	{
	}
	....

接收节点消息,串口发送给Linux

GenericApp_ProcessEvent//协调器只需要接收节点消息并提供串口发送给linux就行
	......
	if ( events & SYS_EVENT_MSG ){//有SYS_EVENT_MSG事件发生
		....
		MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );//接收发送过来的消息
		switch ( MSGpkt->hdr.event ){//判断具体是什么事件
			....
			case AF_INCOMING_MSG_CMD://接收数据事件,调用函数 AF_DataRequest()接收数据
          		GenericApp_MessageMSGCB( MSGpkt );//根据节点发过来的命令将数据发给linux
          	break;
          	....
		}
	}
GenericApp_MessageMSGCB
	....
		switch ( pkt->clusterId )
	{
	 	case GENERICAPP_CLUSTERID1: 
	 	case GENERICAPP_CLUSTERID2:
	 	case GENERICAPP_CLUSTERID3:
	 	case GENERICAPP_CLUSTERID4:			
			HalUARTWrite(0, pkt->cmd.Data,24);//串口发送数据pkt->cmd.Data
			break;
	}
	....

节点:

GenericApp_ProcessEvent //以节点为例,节点需要定时发送数据给协调器,也需要接收来自协调器的信息
    ......
	if ( events & SYS_EVENT_MSG ){//有SYS_EVENT_MSG事件发生
		....
		MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );//接收发送过来的消息
		switch ( MSGpkt->hdr.event ){//判断具体是什么事件
			....
			case AF_INCOMING_MSG_CMD://接收数据事件,调用函数 AF_DataRequest()接收数据
          		GenericApp_MessageMSGCB( MSGpkt );//根据协调器发过来的命令进行相应的处理
          	break;
          	....
          	
          	case ZDO_STATE_CHANGE://如果是任何状态改变事件,比如开启时
          	....
            	osal_start_timerEx( GenericApp_TaskID,
                                 	GENERICAPP_SEND_MSG_EVT,//定时器到期标志
                                	GENERICAPP_SEND_MSG_TIMEOUT );//设置定时器时间
				show_title();
			....
		}
	}
	if ( events & GENERICAPP_SEND_MSG_EVT )//定时器到期
	{ //定时器,每隔5秒发送一次传感器数据信息
		SyncData(ENDDEVICE_ID);//获取硬件信息,并存入EnvMsg结构体中,并且先在自己的lcd上显示出信息
			
		memcpy(sendbuf, &EnvMsg, 24);	
		AF_DataRequest( &GenericApp_DstAddr, &GenericApp_epDesc,
		           GENERICAPP_CLUSTERID1,//协调器1
		           24, //数据字节数
		           (uchar *)&EnvMsg,//消息
		           &GenericApp_TransID, 
		           AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );//zigbee发送函数


		// Setup to send message again
		osal_start_timerEx( GenericApp_TaskID,
		            GENERICAPP_SEND_MSG_EVT,
		            ENDDEVICE_SEND_MSG_TIMEOUT );//重新设置定时器
		....
	}
	......

接收协调器消息,解析命令做出改变:

static void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
	uint8_t cmd = 0;
	char buf[10];
	switch ( pkt->clusterId )
	{
		case GENERICAPP_CLUSTERID: //协调器发来数据

           cmd = *(pkt->cmd.Data);//获取消息
			//显示到lcd屏幕
		
			if((cmd & STO_MASK) == (ENDDEVICE_ID << 6)) // 仓库号正确
			{
				sprintf(buf,"cmd:%x",cmd);
				
				HalUARTWrite(0, buf,strlen(buf));	
				HalLcdWriteString(buf,HAL_LCD_LINE_4);	
				switch(cmd & DEV_MASK) // 判断设备号
				{
					case RELY: // 排风扇命令字
							// 风扇命令处理函数
						RelyCtrl(cmd & CMD_MASK);
						//HalLcdWriteString("rely",HAL_LCD_LINE_5);
						break;
					case BEEP: // 蜂鸣器命令字
							// 蜂鸣器命令处理函数
						BeepCtrl(cmd & CMD_MASK);
						break;
					case LED: // 照明灯命令字
						// 照明灯命令处理函数
						LedCtrl(cmd & CMD_MASK);
						break;
					default :
						break;
				}
			}
			break;
	}
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值