版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Zigbee無線傳感網(wǎng)技術(shù)與應(yīng)用智能家居傳感網(wǎng)0601了解ZigbeeOSAL運(yùn)行原理03掌握Zigbee網(wǎng)絡(luò)串口編程方法04了解Zigbee無線傳感網(wǎng)傳輸方式02了解Zigbee協(xié)議棧原理學(xué)習(xí)目標(biāo)Learningobjectives任務(wù)一:基于OSAL系統(tǒng)下溫度監(jiān)控任務(wù)要求要求讀者了解在單片機(jī)操作系統(tǒng)OSAL,使用OSAL系統(tǒng)改寫項(xiàng)目四獲取溫濕度傳感器代碼,并將獲取到的數(shù)據(jù)發(fā)送給電腦顯示。任務(wù)目標(biāo)Missionobjectives01了解什么是操作系統(tǒng)03掌握使用OSAL系統(tǒng)基本使用方法02了解OSAL基本概念儲(chǔ)備知識(shí)什么是操作系統(tǒng),即把傳統(tǒng)單片機(jī)編程的單任務(wù)系統(tǒng)變?yōu)槎嗳蝿?wù)系統(tǒng),操作系統(tǒng)使單片機(jī)更有效地完成更加復(fù)雜的任務(wù)。但這就需要犧牲單片機(jī)更大的存儲(chǔ)空間用于系統(tǒng)程序和用戶程序。早期沒有操作系統(tǒng)的單片機(jī)也出現(xiàn)了一些多任務(wù)的底層COS,單實(shí)際上還是要和底層打交道,當(dāng)更加復(fù)雜昂貴的單片機(jī)出現(xiàn)后就有條件使應(yīng)用開發(fā)完全與底層及其版本無關(guān),這就是借助操作系統(tǒng)。1.單片機(jī)也有操作系統(tǒng)圖:?jiǎn)稳蝿?wù)與多任務(wù)儲(chǔ)備知識(shí)2.OSAL是何方神圣OSAL為OperatingSystemAbstractionLayer,OSAL為操作系統(tǒng)抽象層,支持多任務(wù)運(yùn)行,但是它并不是一個(gè)傳統(tǒng)意義上的操作系統(tǒng),但又實(shí)現(xiàn)了部分類似操作系統(tǒng)的功能。OSAL概念是由TI公司在Zigbee協(xié)議棧引入,他的意思是“模擬操作系統(tǒng)”,OSAL并非一個(gè)真正的OS,而是模擬OS的一些方法為廣大編程者提供一種寫MCU程序的方法.當(dāng)有一個(gè)事件發(fā)生的時(shí)候,OSAL負(fù)責(zé)將此事件分配給能夠處理此事件的任務(wù),然后此任務(wù)判斷事件的類型,調(diào)用相應(yīng)的事件處理程序進(jìn)行處理?,F(xiàn)有的嵌入式操作系統(tǒng)可以分為兩類,即通用的多任務(wù)操作系統(tǒng)(General—purposeMulti-taskingOS)和事件驅(qū)動(dòng)的操作系統(tǒng)(Event-drivenOS)。前者能夠很好地支持多任務(wù)或者多線程,但是會(huì)隨著內(nèi)部任務(wù)切換頻率的增加而產(chǎn)生很大的開銷。OSAL概述儲(chǔ)備知識(shí)2.OSAL是何方神圣后者支持?jǐn)?shù)據(jù)流的高效并發(fā),并且考慮了系統(tǒng)的低功耗要求,在功耗、運(yùn)行開銷等方面具有優(yōu)勢(shì)。典型的代表如TinyOSl291。目前TinyOS操作系統(tǒng)支持的平臺(tái)有ATMEL公司的AVR系列、TI公司的MSP430系列。由于TinyOS操作系統(tǒng)還沒有對(duì)Chipcon公司(才知道TI把它收購(gòu)了)提供CC2430開發(fā)平臺(tái)提供支持,因此,要在CC2430開發(fā)平臺(tái)上使用TinyOS系統(tǒng)來開發(fā)Zigbee協(xié)議棧軟件,就必須首先對(duì)TinyOS進(jìn)行移植。OSAL主要提供了:任務(wù)注冊(cè)、任務(wù)間同步互斥、中斷處理、存儲(chǔ)器分配和管理、提供定時(shí)器功能。圖:OSAL工作框圖儲(chǔ)備知識(shí)2.OSAL是何方神圣OSAL軟件功能是由任務(wù)事件來實(shí)現(xiàn)的,其創(chuàng)建流程如下所示:任務(wù)初始化osalInitTasks();在注冊(cè)事件數(shù)組寫入事件處理函數(shù)tasksArr[];事件函數(shù)處理事件Event();OSAL事件事件是驅(qū)動(dòng)任務(wù)去執(zhí)行某些操作的條件,當(dāng)系統(tǒng)產(chǎn)生了一個(gè)事件,將這個(gè)觸發(fā)傳遞給相應(yīng)的任務(wù)后,任務(wù)才能執(zhí)行一個(gè)相應(yīng)的操作。OSAL通過一個(gè)16位寬度的數(shù)組來管理事件,意味著OSAL最多可以支持16個(gè)事件,其中最高位(0x08000,SYS_EVENT_MSG)系統(tǒng)保留,用戶可以使用的事件有15個(gè)。儲(chǔ)備知識(shí)2.OSAL是何方神圣事件使用流程如下:需要找個(gè)地方定義事件的ID,實(shí)際上是指定該事件占用事件數(shù)組的哪個(gè)位。如#defineMY_EVENT0x02,占用bit1。在需要觸發(fā)事件的地方調(diào)用osal_set_event(task_id,event_flag),這個(gè)函數(shù)有兩個(gè)參數(shù),一個(gè)是接收事件任務(wù)的ID,另一個(gè)參數(shù)指定事件ID。在相應(yīng)任務(wù)的處理函數(shù),檢查該事件執(zhí)行相應(yīng)代碼即可。清除事件標(biāo)識(shí)。3.OSAL簡(jiǎn)單使用本任務(wù)所需硬件:下載器、1塊ZigBee開發(fā)板、溫濕度傳感器、5V電源適配器、USB下載線。環(huán)境準(zhǔn)備任務(wù)實(shí)施任務(wù)實(shí)施3.OSAL簡(jiǎn)單使用圖:打開工程文件與工程目錄代碼小貼士:TI公司為的Z-Stack工程文件已編好絕大部分代碼,我們僅僅需要在其基礎(chǔ)上作出基本的修改即可使用。任務(wù)實(shí)施步驟2:打開工程后,暫時(shí)不必立刻開始編寫代碼,先嘗試編譯原有工程點(diǎn)擊“RebuildAll”按鈕,是否可以被正常編譯,如圖所示。(Z-Stack工程文件比較大,編譯過程有比較久,需要耐心等待編譯成功)。3.OSAL簡(jiǎn)單使用圖:編譯成功任務(wù)實(shí)施步驟3:屏蔽Coordinator.c與Coordinator.h文件,使用OSAL系統(tǒng)暫時(shí)不需要該文件。3.OSAL簡(jiǎn)單使用圖:屏蔽文件任務(wù)實(shí)施步驟4:在“Source”目錄下新建test.c與test.h文件并在App目錄下添加,如圖所示。Source目錄為用戶編寫程序目錄。3.OSAL簡(jiǎn)單使用圖:添加文件任務(wù)實(shí)施步驟5:在test.c文件中編寫引用頭文件,這里僅需要引用最基本的幾個(gè)頭文件即可,代碼如下所示。3.OSAL簡(jiǎn)單使用#include"ZComDef.h"http://宏定義uint8uint16等#include"iocc2530.h"http://必備頭文件#include"OSAL.h"http://需要調(diào)用一些OSAL函數(shù)#include"OSAL_Timers.h"http://需要調(diào)用一些OSAL函數(shù)#include"test.h"代碼小貼士:代碼:#include"ZComDef.h"說明:后續(xù)代碼會(huì)大量用到變量簡(jiǎn)單申明方式如uint8、uint16等聲明方式故需要提前申明。任務(wù)實(shí)施步驟6:在test.c代碼中編寫任務(wù)初始化函數(shù)test_Init(),代碼如右所示。3.OSAL簡(jiǎn)單使用代碼小貼士:代碼:#include"OSAL_Timers.h"#include"OSAL.h"說明:主要用到osal系統(tǒng)中的函數(shù),故需要引用其頭文件。#include"ZComDef.h"http://宏定義uint8uint16等#include"iocc2530.h"http://必備頭文件#include"OSAL.h"http://需要調(diào)用一些OSAL函數(shù)#include"OSAL_Timers.h"http://需要調(diào)用一些OSAL函數(shù)#include"test.h"uint8test_taskid=0;voidtest_Init(uint8task_id){test_taskid=task_id;//注冊(cè)事件,開啟事件事件為id為0x0001oasl_set_event(test_taskid,0x0001);}任務(wù)實(shí)施步驟6:在test.c代碼中編寫任務(wù)事件處理函數(shù)test_Event(),并編寫事件判斷處理代碼,代碼如下所示。3.OSAL簡(jiǎn)單使用代碼小貼士:代碼:oasl_set_event(test_taskid,0x0001);說明:注冊(cè)一個(gè)事件,并通過事件調(diào)用event函數(shù)。參數(shù)1:任務(wù)id,為初始化時(shí)傳入的參數(shù)參數(shù)2:事件id,可自行數(shù)據(jù),注意不要重復(fù)任務(wù)實(shí)施3.OSAL簡(jiǎn)單使用#include"ZComDef.h"http://宏定義uint8uint16等#include"iocc2530.h"http://必備頭文件#include"OSAL.h"http://需要調(diào)用一些OSAL函數(shù)#include"OSAL_Timers.h"http://需要調(diào)用一些OSAL函數(shù)#include"test.h"uint8test_taskid=0;voidtest_Init(uint8task_id){P1DIR|=0x01;test_taskid=task_id;//注冊(cè)事件,開啟事件事件為id為0x0001oasl_set_event(test_taskid,0x0001);}uint16test_Event(uint8task_id,uint16events){if(events&0x0001){ }}任務(wù)實(shí)施3.OSAL簡(jiǎn)單使用代碼小貼士:代碼:uint16test_Event(uint8task_id,uint16events)說明:為事件函數(shù),如果有事件發(fā)送,該函數(shù)都會(huì)被調(diào)用。參數(shù)1:任務(wù)ID參數(shù)2:事件ID代碼:if(events&0x0001){}說明:使用events與上0x0001,如果events的第一位為1則數(shù)據(jù)必然大于1,表示事件為用戶定義的事件,如果是則執(zhí)行括號(hào)內(nèi)的代碼。任務(wù)實(shí)施步驟7:編寫事件執(zhí)行代碼,將LED燈取反顯示,并且調(diào)用osal定時(shí)函數(shù)在1秒后重新產(chǎn)生0x0001事件。代碼如下所示。3.OSAL簡(jiǎn)單使用uint16test_Event(uint8task_id,uint16events){
if(events&0x0001){P1_0=!P1_0;//定時(shí)1秒后產(chǎn)生0x0001事件osal_start_timerEx(test_TaskID,0x0001,1000);//返回?cái)?shù)據(jù)表示
事件執(zhí)行成功
return(events^0x0001);}}任務(wù)實(shí)施3.OSAL簡(jiǎn)單使用代碼小貼士:代碼:osal_start_timerEx(test_TaskID,0x0001,1000);說明:OSAL本身有一個(gè)定時(shí)器,定時(shí)器會(huì)計(jì)時(shí),當(dāng)時(shí)間過1000ms之后,會(huì)再一次觸發(fā)0x0001事件,并調(diào)用事件處理函數(shù)。參數(shù)1:任務(wù)ID參數(shù)2:觸發(fā)事件ID參數(shù)3:延遲時(shí)間,單位為毫秒級(jí)別代碼:return(events^0x0001);說明:返回?cái)?shù)據(jù)表示成功執(zhí)行,必須返回?cái)?shù)據(jù)否則系統(tǒng)將認(rèn)為時(shí)間未執(zhí)行成功將不斷判斷。任務(wù)實(shí)施步驟8:編寫test.h頭文件,把初始化函數(shù)、事件處理函數(shù)設(shè)為外部可調(diào)用函數(shù),代碼如下所示。3.OSAL簡(jiǎn)單使用#ifndefTEST_H#defineTEST_H#include"comdef.h"extern
voidtest_Init(uint8task_id);externuint16test_Event(uint8task_id,uint16events);#endif任務(wù)實(shí)施3.OSAL簡(jiǎn)單使用代碼小貼士:代碼:#ifndefTEST_H#defineTEST_H…#endif說明:宏定義預(yù)編譯指令,表示如果沒有定義TEST_H宏定義則定義該TEST_H主要作用是防止重復(fù)添加頭文件而使用。代碼:externvoidtest_Init(uint8task_id);externuint16test_Event(uint8task_id,uint16events);說明:函數(shù)中加入extern關(guān)鍵字表示,可被外部調(diào)用的函數(shù)。任務(wù)實(shí)施步驟9:在App目錄下找到OSAL_SampleApp.c文件如圖所示,在OSAL_SampleApp.c中osalInitTask函數(shù)中刪除之前任務(wù)代碼,添加新任務(wù)初始化函數(shù)test_init()并傳入任務(wù)id號(hào),代碼如下所示。3.OSAL簡(jiǎn)單使用圖:任務(wù)文件任務(wù)實(shí)施3.OSAL簡(jiǎn)單使用voidosalInitTasks(void){uint8taskID=0;tasksEvents=(uint16*)osal_mem_alloc(sizeof(uint16)*tasksCnt);osal_memset(tasksEvents,0,(sizeof(uint16)*tasksCnt));macTaskInit(taskID++);nwk_init(taskID++);Hal_Init(taskID++);#ifdefined(MT_TASK)MT_TaskInit(taskID++);#endifAPS_Init(taskID++);#ifdefined(ZIGBEE_FRAGMENTATION)APSF_Init(taskID++);#endifZDApp_Init(taskID++);#ifdefined(ZIGBEE_FREQ_AGILITY)||defined(ZIGBEE_PANID_CONFLICT)ZDNwkMgr_Init(taskID++);#endif/*添加的新初始化函數(shù)*/test_Init(taskID);/********************/}任務(wù)實(shí)施步驟10:在OSAL_SampleApp.c文件tasksArr[]數(shù)組最后,添加編寫的事件函數(shù)名test_Event,并刪除SampleApp_ProcessEvent事件,代碼如右所示。3.OSAL簡(jiǎn)單使用//TheorderinthistablemustbeidenticaltothetaskinitializationcallsbelowinosalInitTask.constpTaskEventHandlerFntasksArr[]={macEventLoop,nwk_event_loop,Hal_ProcessEvent,#ifdefined(MT_TASK)MT_ProcessEvent,#endifAPS_event_loop,#ifdefined(ZIGBEE_FRAGMENTATION)APSF_ProcessEvent,#endifZDApp_event_loop,#ifdefined(ZIGBEE_FREQ_AGILITY)||defined(ZIGBEE_PANID_CONFLICT)ZDNwkMgr_event_loop,#endif/*添加的事件*/test_Event/************/};任務(wù)實(shí)施步驟11:自此最簡(jiǎn)單的OSAL使用編寫代碼已經(jīng)完成,編譯代碼在test.c處設(shè)置斷點(diǎn),查看事件函數(shù)是否被正常執(zhí)行。3.OSAL簡(jiǎn)單使用圖:斷點(diǎn)調(diào)試任務(wù)實(shí)施步驟12:全速執(zhí)行代碼,查看LED效果每秒亮滅,如圖?所示。OSAL的編寫看似步驟是否繁瑣,但使用熟練之后開發(fā)一些大型綜合類程序有其獨(dú)到之處。3.OSAL簡(jiǎn)單使用圖:查看效果任務(wù)實(shí)施一、在原有基礎(chǔ)代碼上添加一個(gè)新的0x0002事件,事件始另外的LED以0.5秒頻率閃爍。二、添加有一個(gè)新的任務(wù),該任務(wù)為按鈕任務(wù),按下按鈕停止所有燈的閃爍。技能拓展3.OSAL簡(jiǎn)單使用4.OSAL溫度監(jiān)控本任務(wù)所需硬件:下載器、1塊ZigBee開發(fā)板、溫濕度傳感器、5V電源適配器、USB下載線。環(huán)境準(zhǔn)備任務(wù)實(shí)施任務(wù)實(shí)施
新建兩個(gè)事件,在事件1中每秒獲取溫濕度數(shù)據(jù);
在事件2中將溫濕度數(shù)據(jù)發(fā)送至電腦顯示,間隔周期2s。任務(wù)要求編寫代碼步驟1:復(fù)制“工程1”文件夾,命名為“工程2”,復(fù)制項(xiàng)目四中SHT11.c、hal_defs.h、hal_types.h到“工程2\source”目錄下,如圖所示。4.OSAL溫度監(jiān)控圖:復(fù)制文件任務(wù)實(shí)施步驟2:在test.c文件下,test_Init函數(shù)中添加多個(gè)事件函數(shù),代碼如下所示。4.OSAL溫度監(jiān)控voidtest_Init(uint8task_id){P1DIR|=0x01;P1_0=0;UartInit();test_TaskID=task_id;
//啟動(dòng)事件osal_set_event(test_TaskID,0x0001);//LED亮滅事件osal_set_event(test_TaskID,0x0002);//獲取溫度事件osal_set_event(test_TaskID,0x0004);//發(fā)送串口事件}任務(wù)實(shí)施代碼小貼士:代碼:osal_set_event(test_TaskID,0x0002);osal_set_event(test_TaskID,0x0004);說明:0x0002為獲取溫度事件,在事件中負(fù)責(zé)每一秒獲取溫度信息。0x0004為發(fā)送串口事件,在事件中負(fù)責(zé)將溫度信息發(fā)送給電腦每2秒發(fā)送一次。4.OSAL溫度監(jiān)控步驟3:在test.c文件下,編寫串口使能函數(shù),代碼如右所示。(注意:Z-Stack的頻率為32MHZ串口的波特率)voidUartInit(void){halUARTCfg_tuartConfig;//申明一個(gè)串口結(jié)構(gòu)體uartConfig.configured=TRUE;//是否被配置,固定為TrueuartConfig.baudRate=HAL_UART_BR_57600;//波特率為57600uartConfig.flowControl=FALSE;//流控制不啟動(dòng)uartConfig.callBackFunc=NULL;//沒有回調(diào)函數(shù)HalUARTOpen(0,&uartConfig);//啟動(dòng)串口配置}任務(wù)實(shí)施步驟4:在test.h頭文件中編寫,函數(shù)信息代碼如下所示。(注意:Z-Stack每編寫一個(gè)函數(shù),則必須在頭文件下進(jìn)行聲明否則編譯無法通過)4.OSAL溫度監(jiān)控#ifndefTEST_H#defineTEST_H#include"comdef.h"extern
voidtest_Init(uint8task_id);externuint16test_Event(uint8task_id,uint16events);voidUartInit(void);#endif代碼小貼士:代碼:voidUartInit(void);說明:void表示為空,參數(shù)如果為空,必須添加void否則無法編譯。任務(wù)實(shí)施步驟5:在test.c文件下,編寫發(fā)送串口字符串函數(shù)、串口發(fā)送單字符函數(shù),代碼如下所示。4.OSAL溫度監(jiān)控voidsend(unsigned
chars){U0DBUF=s;//發(fā)送a
while(!UTX0IF);UTX0IF=0;}voidsendstr(unsigned
char*s,unsigned
charlen){
intcount=0;
while(len--){send(*(s+count));count++;}}任務(wù)實(shí)施步驟6:在test.h頭文件中編寫,函數(shù)信息代碼如下所示。(注意:Z-Stack每編寫一個(gè)函數(shù),則必須在頭文件下進(jìn)行聲明否則編譯無法通過)4.OSAL溫度監(jiān)控#ifndefTEST_H#defineTEST_H#include"comdef.h"extern
voidtest_Init(uint8task_id);externuint16test_Event(uint8task_id,uint16events);externvoidUartInit(void);externvoidsend(unsigned
chars);externvoidsendstr(unsigned
char*s,unsigned
charlen);#endif任務(wù)實(shí)施步驟7:添加SHT11.h頭文件,代碼如下所示。4.OSAL溫度監(jiān)控#include"SHT11.h"步驟8:在test.c文件下,test_Event函數(shù)中添加兩個(gè)事件處理判斷,在一個(gè)事件中調(diào)用獲取溫濕度函數(shù),另一個(gè)事件中調(diào)用發(fā)送串口函數(shù),代碼如下所示。uint16test_Event(uint8task_id,uint16events){
if(events&0x0001){P1_0=!P1_0;osal_start_timerEx(test_TaskID,0x0001,1000);
return(events^0x0001);}
if(events&0x0002)任務(wù)實(shí)施4.OSAL溫度監(jiān)控{call_sht11(&temp,&hum);osal_start_timerEx(test_TaskID,0x0002,1000);
return(events^0x0002);}
if(events&0x0004){sendstr("溫度:",5);send((temp/100)+'0');send((temp/10%10)+'0');send('.');send((temp%10)+'0');sendstr("℃",2);send('\n');osal_start_timerEx(test_TaskID,0x0004,2000);
return(events^0x0004);}
return
0;}任務(wù)實(shí)施步驟9:下載代碼,在發(fā)送串口數(shù)據(jù)位置設(shè)置斷點(diǎn),查看是否獲取到溫度信息,并發(fā)送至電腦。4.OSAL溫度監(jiān)控圖:斷點(diǎn)接收溫度任務(wù)實(shí)施步驟10:全速執(zhí)行查看,打開串口調(diào)試助手波特率設(shè)置為9600。每個(gè)事件是否為固定事件內(nèi)執(zhí)行。4.OSAL溫度監(jiān)控圖:溫度接收任務(wù)實(shí)施一、添加一個(gè)新事件,在溫度接收的基礎(chǔ)上,在新事件下將濕度信息發(fā)送至電腦。技能拓展4.OSAL溫度監(jiān)控Zigbee無線傳感網(wǎng)技術(shù)與應(yīng)用智能家居傳感網(wǎng)0601了解ZigbeeOSAL運(yùn)行原理03掌握Zigbee網(wǎng)絡(luò)串口編程方法04了解Zigbee無線傳感網(wǎng)傳輸方式02了解Zigbee協(xié)議棧原理學(xué)習(xí)目標(biāo)Learningobjectives任務(wù)二:無線智能窗簾控制系統(tǒng)任務(wù)要求要求讀者掌握使用Z-Stack組網(wǎng)程序,一個(gè)節(jié)點(diǎn)設(shè)備使用光照傳感器接收光照數(shù)值實(shí)時(shí)發(fā)送數(shù)據(jù)至協(xié)調(diào)器,協(xié)調(diào)器接收數(shù)據(jù)發(fā)送數(shù)據(jù)至PC上位機(jī)模擬開啟窗簾,當(dāng)光照大于設(shè)定數(shù)值時(shí)關(guān)閉窗簾,小于時(shí)打開窗簾。任務(wù)目標(biāo)Missionobjectives01了解什么是Z-Stack03使用OASL進(jìn)行Z-Stack組網(wǎng)02了解Z-Stack基本概念儲(chǔ)備知識(shí)Z-stack是挪威半導(dǎo)體公司Chipcon(目前已經(jīng)被TI公司收購(gòu))推出其CC2430開發(fā)平臺(tái)時(shí),推出的一款業(yè)界領(lǐng)先的商業(yè)級(jí)協(xié)議棧軟件,由于這個(gè)協(xié)議棧軟件的出現(xiàn),用戶可以很容易地開發(fā)出具體的應(yīng)用程序來,也就是大家說的掌握10個(gè)函數(shù)就能使用ZigBee通訊的原因。它使用瑞典公司IAR開發(fā)的IAREmbeddedWorkbenchforMCS-51作為它的集成開發(fā)環(huán)境。Chipcon公司為自己設(shè)計(jì)的Z-Stack協(xié)議棧中提供了一個(gè)名為操作系統(tǒng)抽象層OSAL的協(xié)議棧調(diào)度程序。對(duì)于用戶來說,除了能夠看到這個(gè)調(diào)度程序外,其它任何協(xié)議棧操作的具體實(shí)現(xiàn)細(xì)節(jié)都被封裝在庫代碼中。用戶在進(jìn)行具體的應(yīng)用開發(fā)時(shí)只能夠通過調(diào)用API接口來進(jìn)行,而無權(quán)知道ZigBee協(xié)議棧實(shí)現(xiàn)的具體細(xì)節(jié),也沒必要去知道。因此在這里提醒各位開發(fā)者,在使用ZigBee協(xié)議棧進(jìn)行實(shí)際項(xiàng)目開發(fā)時(shí),不需要關(guān)心協(xié)議棧是具體怎么實(shí)現(xiàn)的,當(dāng)然有興趣的也可以深入分析。1.什么是Z-StackZ-Stack概述儲(chǔ)備知識(shí)TI公司的基于ZigBee2007的協(xié)議棧Z-Stack-CC2530-2.3.0,所有文件目錄如圖紅色框所示,我們可以把它看做一個(gè)龐大的工程?;蛘呤且粋€(gè)小型的操作系統(tǒng)。采用任務(wù)輪詢的方法運(yùn)行。圖:Z-Stack工程ZigBee協(xié)議棧已經(jīng)實(shí)現(xiàn)ZigBee協(xié)議,用戶可以使用協(xié)議棧提供的API進(jìn)行應(yīng)用程序的開發(fā),在開發(fā)過程中完全不必關(guān)心ZigBee協(xié)議的具體實(shí)現(xiàn)細(xì)節(jié),要關(guān)心的問題是:應(yīng)用層的數(shù)據(jù)是使用哪些函數(shù)通過什么方式把數(shù)據(jù)發(fā)送出去或者把數(shù)據(jù)接收過來的。所以最重要的是我們要學(xué)會(huì)使用ZigBee協(xié)議棧。1.什么是Z-Stack儲(chǔ)備知識(shí)協(xié)議是一系列的通信標(biāo)準(zhǔn),通信雙方需要共同按照這一標(biāo)準(zhǔn)進(jìn)行正常的數(shù)據(jù)發(fā)射和接收。協(xié)議棧是協(xié)議的具體實(shí)現(xiàn)形式,通俗點(diǎn)來理解就是協(xié)議棧是協(xié)議和用戶之間的一個(gè)接口,開發(fā)人員通過使用協(xié)議棧來使用這個(gè)協(xié)議的,進(jìn)而實(shí)現(xiàn)無線數(shù)據(jù)收發(fā)。ZigBee的協(xié)議分為兩部分,IEEE802.15.4定義了PHY(物理層)和MAC(介質(zhì)訪問層)技術(shù)規(guī)范;ZigBee聯(lián)盟定義了NWK(網(wǎng)絡(luò)層)、APS(應(yīng)用程序支持子層)、APL(應(yīng)用層)技術(shù)規(guī)范。ZigBee協(xié)議棧就是將各個(gè)層定義的協(xié)議都集合在一起,以函數(shù)的形式實(shí)現(xiàn),并給用戶提供API(應(yīng)用層),用戶可以直接調(diào)用。1.什么是Z-StackZ-Stack協(xié)議儲(chǔ)備知識(shí)用戶實(shí)現(xiàn)一個(gè)簡(jiǎn)單的無線數(shù)據(jù)通信時(shí)的一般步驟為:組網(wǎng):抵用協(xié)議棧的組網(wǎng)函數(shù)、加入網(wǎng)絡(luò)函數(shù),實(shí)現(xiàn)網(wǎng)絡(luò)的建立與節(jié)點(diǎn)的加入。發(fā)送:發(fā)送節(jié)點(diǎn)調(diào)用協(xié)議棧的無線數(shù)據(jù)發(fā)送函數(shù),實(shí)現(xiàn)無線數(shù)據(jù)發(fā)送。接收:接收節(jié)點(diǎn)調(diào)用協(xié)議棧的無線數(shù)據(jù)接收函數(shù),實(shí)現(xiàn)無線數(shù)據(jù)接收。通信步驟1.什么是Z-StackZibge無線傳感網(wǎng)層Zigbee無線傳感器網(wǎng)絡(luò)的協(xié)議棧主要分為物理層、數(shù)據(jù)鏈路層(MAC)、網(wǎng)絡(luò)層、傳輸層和應(yīng)用層5層。儲(chǔ)備知識(shí)1.什么是Z-Stack圖:Zigbee層級(jí)關(guān)系儲(chǔ)備知識(shí)現(xiàn)教材制作了一套上位機(jī)軟件,用來模擬窗簾控制,使用串口與電腦通信,軟件使用波特率19200、無奇偶校驗(yàn)位、默認(rèn)COM連接COM11接口(需要手動(dòng)設(shè)置COM口為COM11)。其具體通信協(xié)議如下表所示。指令部分0xff表示為啟始符、中間兩位為光照度數(shù)據(jù)高8位與低8位、無終止符。表:上位機(jī)通信指令集合功能指令備注接收光照值0xFF0x110x10無圖:模擬窗簾上位機(jī)2.模擬窗簾上位機(jī)3.最簡(jiǎn)單的Z-Stack本任務(wù)所需硬件:下載器、1塊ZigBee開發(fā)板、光照傳感器、5V電源適配器、USB下載線。環(huán)境準(zhǔn)備任務(wù)實(shí)施任務(wù)實(shí)施
打開“Zstack”工程,編寫協(xié)調(diào)器代碼與節(jié)點(diǎn)代碼;
如果組網(wǎng)成功后,接收到節(jié)點(diǎn)發(fā)送的數(shù)據(jù)“1”,LED開始閃爍。任務(wù)要求編寫代碼步驟1:復(fù)制“配套資料\項(xiàng)目六\z-stack”目錄保存為“工程1”,并打開“工程1\Projects\zstack\Samples\SampleApp\CC2530DB\SampleApp.eww”工程文件,如圖所示。圖:打開工程文件與工程目錄3.最簡(jiǎn)單的Z-Stack任務(wù)實(shí)施步驟2:刪除Coordinator.c與Coordinator.h、EndDevice.c、EndDevice.h文件,重寫協(xié)調(diào)器、節(jié)點(diǎn)代碼,如圖所示。3.最簡(jiǎn)單的Z-Stack圖:刪除文件任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack圖:添加文件步驟3:在“Source”目錄下新建mycoordinator.c與mycoordinator.h文件并在App目錄下添加,如圖所示。Source目錄為用戶編寫程序目錄,表示協(xié)調(diào)器代碼與頭文件。任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack步驟4:在mycoordinator.c文件下編寫添加頭文件,代碼如下所示。#include"ZComDef.h"#include"OSAL.h"#include"AF.h”#include"ZDAPP.h"#include"mycoordinator.h"#include"hal_led.h"代碼小貼士:代碼:#include"AF.h"說明:后續(xù)代碼需要調(diào)用Z-Stack組網(wǎng)函數(shù),故需要添加該頭文件。代碼:#include"hal_led.h"說明:后續(xù)代碼需要調(diào)用LED閃爍函數(shù)。故需要添加頭文件。任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack步驟5:在mycoordinator.c代碼中編寫任務(wù)初始化函數(shù)App_Init(),代碼如下所示。#include"ZComDef.h"#include"OSAL.h"#include"AF.h"#include"mycoordinator.h"#include"hal_led.h"uint8app_taskid;voidApp_Init(uint8task_id){app_taskid=task_id;}任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack步驟6:在mycoordinator.c代碼中編寫任務(wù)初始化函數(shù)App_Event(),代碼如右所示。uint16App_Event(uint8task_id,uint16events){
return
0;}步驟7:編寫mycoordinator.h頭文件,把初始化函數(shù)、事件處理函數(shù)設(shè)為外部可調(diào)用函數(shù),代碼如下所示。#ifndefTEST_H#defineTEST_H#include"comdef.h"extern
voidApp_Init(uint8task_id);externuint16App_Event(uint8task_id,uint16events);#endif任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack步驟8:在App目錄下找到OSAL_SampleApp.c文件如圖所示,在OSAL_SampleApp.c中osalInitTask函數(shù)中刪除之前任務(wù)代碼,添加新任務(wù)初始化函數(shù)test_init()并傳入任務(wù)id號(hào),代碼如右所示。voidosalInitTasks(void){uint8taskID=0;tasksEvents=(uint16*)osal_mem_alloc(sizeof(uint16)*tasksCnt);osal_memset(tasksEvents,0,(sizeof(uint16)*tasksCnt));macTaskInit(taskID++);nwk_init(taskID++);Hal_Init(taskID++);#ifdefined(MT_TASK)MT_TaskInit(taskID++);#endifAPS_Init(taskID++);#ifdefined(ZIGBEE_FRAGMENTATION)APSF_Init(taskID++);#endifZDApp_Init(taskID++);#ifdefined(ZIGBEE_FREQ_AGILITY)||defined(ZIGBEE_PANID_CONFLICT)ZDNwkMgr_Init(taskID++);#endif/*添加的新初始化函數(shù)*/test_Init(taskID);/********************/}任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack步驟9:在OSAL_SampleApp.c文件tasksArr[]數(shù)組最后,添加編寫的事件函數(shù)名App_Event,并刪除SampleApp_ProcessEvent事件,代碼如右所示。//TheorderinthistablemustbeidenticaltothetaskinitializationcallsbelowinosalInitTask.constpTaskEventHandlerFntasksArr[]={macEventLoop,nwk_event_loop,Hal_ProcessEvent,#ifdefined(MT_TASK)MT_ProcessEvent,#endifAPS_event_loop,#ifdefined(ZIGBEE_FRAGMENTATION)APSF_ProcessEvent,#endifZDApp_event_loop,#ifdefined(ZIGBEE_FREQ_AGILITY)||defined(ZIGBEE_PANID_CONFLICT)ZDNwkMgr_event_loop,#endif/*添加的事件*/App_Event/************/};任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack步驟10:在完成OSAL代碼流程編寫完成后,開始編寫組網(wǎng)代碼其中初始化注冊(cè)標(biāo)志代碼,在mycoordinator.c文件,AppInit函數(shù)中編寫代碼,代碼如右所示。uint8app_taskid;endPointDesc_tAppDesc;//節(jié)點(diǎn)描述符uint16list[2]={
1};//用來描述一個(gè)ZigBee設(shè)備節(jié)點(diǎn),稱為簡(jiǎn)單設(shè)備描述符constSimpleDescriptionFormat_tApp_SimDesc={
20,0x0f08,0x0001,0,0,2,(cId_t*)list,0,(cId_t*)NULL,};voidApp_Init(uint8task_id){app_taskid=task_id;AppDesc.endPoint=20;//端口號(hào)AppDesc.task_id=&app_taskid;//任務(wù)IDAppDesc.simpleDesc=(SimpleDescriptionFormat_t*)&App_SimDesc;AppDesc.latencyReq=noLatencyReqs;//延時(shí)策略afRegister(&AppDesc);//注冊(cè)組網(wǎng)}任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack代碼小貼士:代碼:endPointDesc_tAppDesc;說明:結(jié)構(gòu)體為節(jié)點(diǎn)描述符,提供給afRegister函數(shù)注冊(cè)使用。包含有端口任務(wù)ID等信息。代碼:constSimpleDescriptionFormat_tApp_SimDesc={ 20,0x0f08,0x0001,0,0,2,(cId_t*)list,0,(cId_t*)NULL,}說明:在AppDesc結(jié)構(gòu)體中更具體的通信地址等信息,暫不理解直接使用。代碼:afRegister(&AppDesc);說明:注冊(cè)組網(wǎng)信息,只有注冊(cè)才可使用組網(wǎng)功能函數(shù)。任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack步驟11:在mycoordinator.c文件編寫,事件處理函數(shù)App_Event()代碼,代碼如下所示。uint16App_Event(uint8task_id,uint16events){afIncomingMSGPacket_t*msg;
if(events&SYS_EVENT_MSG){//接收事件與數(shù)據(jù)msg=(afIncomingMSGPacket_t*)osal_msg_receive(app_taskid);
while(msg){}
return(events^SYS_EVENT_MSG);}
return
0;}代碼小貼士:代碼:afIncomingMSGPacket_t*msg;說明:該結(jié)構(gòu)體保存著各種事件與接收的數(shù)據(jù)。代碼:msg=(afIncomingMSGPacket_t*)osal_msg_receive(app_taskid);說明:osal_msg_receive函數(shù)為接收事件消息數(shù)據(jù)的函數(shù)。任務(wù)實(shí)施步驟12:在mycoordinator.c文件編寫,事件處理函數(shù)App_Event()代碼,代碼如下所示。3.最簡(jiǎn)單的Z-Stackuint16App_Event(uint8task_id,uint16events){afIncomingMSGPacket_t*msg;
if(events&SYS_EVENT_MSG){//接收數(shù)據(jù)
msg=(afIncomingMSGPacket_t*)osal_msg_receive(app_taskid);
while(msg){
switch(msg->hdr.event){
caseAF_INCOMING_MSG_CMD://接收到數(shù)據(jù)
App_Msg(msg);//接收到數(shù)據(jù)處理函數(shù)
break;
}osal_msg_deallocate((uint8*)msg);//清除緩存空間//再次接收數(shù)據(jù),直到?jīng)]有事件
msg=(afIncomingMSGPacket_t*)osal_msg_receive(app_taskid);}
return(events^SYS_EVENT_MSG);}
return
0;}任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack代碼小貼士:代碼:while(msg)說明:循環(huán)接收數(shù)據(jù),直到?jīng)]有事件數(shù)據(jù)后退出。代碼:switch(msg->hdr.event)說明:msg結(jié)構(gòu)體中hdr.event變量為系統(tǒng)接收事件標(biāo)志,其中AF_INCOMING_MSG_CMD表示接收到數(shù)據(jù)代碼:osal_msg_deallocate((uint8*)msg);說明:處理事件后,需要釋放存儲(chǔ)空間,在Zigbee協(xié)議棧中存放是一直累加的,所以需要使用函數(shù)釋放空間。任務(wù)實(shí)施步驟13:在mycoordinator.c文件編寫,事件接收到數(shù)據(jù)處理函數(shù)App_Msg()代碼,代碼如下所示。3.最簡(jiǎn)單的Z-Stackuint16tmp=0;voidApp_Msg(afIncomingMSGPacket_t*m){
switch(m->clusterId){
case
0x0001://接收到包
if(m->cmd.Data[0]=='1'){HalLedBlink(HAL_LED_2,0,50,500);}
break;}}任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack代碼小貼士:代碼:switch(m->clusterId)說明:m->cluserID表示數(shù)據(jù)包的標(biāo)識(shí)符,0x0001為節(jié)點(diǎn)發(fā)送數(shù)據(jù)給協(xié)調(diào)器時(shí)的數(shù)據(jù)包標(biāo)識(shí)符。代碼:case0x0001:說明:如果標(biāo)識(shí)符為0x0001,則開始判斷包內(nèi)容代碼:if(m->cmd.Data[0]=='1')說明:m->cmd.Data有著發(fā)送數(shù)據(jù)包的具體內(nèi)容,判斷第0位是否為字符1,如果是則執(zhí)行if內(nèi)代碼。任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack代碼小貼士:代碼:HalLedBlink(HAL_LED_2,0,50,500);說明:函數(shù)在hal_led.h頭文件中被定義,調(diào)用函數(shù)則LED開始閃爍 參數(shù)1:表示LED的IO 參數(shù)2:閃縮次數(shù),0表示一直閃 參數(shù)3:亮與滅的比例,50表示各占一半 參數(shù)4:周期,500表示0.5s閃爍任務(wù)實(shí)施步驟14:在mycoordinator.h頭文件編寫,事件接收到數(shù)據(jù)處理函數(shù)App_Msg()引用,代碼如下所示。3.最簡(jiǎn)單的Z-Stack#ifndefMYCOORDINATOR_H#defineMYCOORDINATOR_Hextern
voidApp_Init(uint8task_id);externuint16App_Event(uint8task_id,uint16events);extern
voidApp_Msg(afIncomingMSGPacket_t*m);#endif任務(wù)實(shí)施步驟15:編譯代碼,設(shè)置系統(tǒng)是否被運(yùn)行成功,成功進(jìn)入事件,如圖所示。3.最簡(jiǎn)單的Z-Stack圖:成功進(jìn)入事件任務(wù)實(shí)施步驟16:協(xié)調(diào)器代碼編寫完成,接下來開始編寫節(jié)點(diǎn)代碼,新建一個(gè)文件“myenddevice.c”文件,并添加至APP目錄下如圖所示。3.最簡(jiǎn)單的Z-Stack圖:節(jié)點(diǎn)文件任務(wù)實(shí)施步驟17:將在CoordinatorEB工程下屏蔽myenddevice.c,如圖所示。3.最簡(jiǎn)單的Z-Stack圖:屏蔽文件任務(wù)實(shí)施步驟18:切換至EndDeviceEB,并屏蔽mycoordinator.c文件,如圖所示。3.最簡(jiǎn)單的Z-Stack圖:模式切換、屏蔽文件任務(wù)實(shí)施步驟19:復(fù)制mycoordinator.c代碼至myenddevice.c文件下,刪除接收數(shù)據(jù)事件AF_INCOMING_MSG_CMD代碼,保留其他代碼。刪除后的App_Event函數(shù)代碼如右所示。3.最簡(jiǎn)單的Z-Stackuint16App_Event(uint8task_id,uint16events){afIncomingMSGPacket_t*msg;
if(events&SYS_EVENT_MSG){//接收數(shù)據(jù)msg=(afIncomingMSGPacket_t*)osal_msg_receive(app_taskid);
while(msg){
switch(msg->hdr.event){
}osal_msg_deallocate((uint8*)msg);//清除緩存空間//再次接收數(shù)據(jù),直到?jīng)]有事件msg=(afIncomingMSGPacket_t*)osal_msg_receive(app_taskid);}
return(events^SYS_EVENT_MSG);}
return
0;}任務(wù)實(shí)施步驟20:在myenddevice.c判斷事件函數(shù)代碼中添加一段代碼,用于判斷組網(wǎng)是否完成,代碼如下所示。3.最簡(jiǎn)單的Z-Stackuint16App_Event(uint8task_id,uint16events){afIncomingMSGPacket_t*msg;
//系統(tǒng)事件定義
if(events&SYS_EVENT_MSG){//接收數(shù)據(jù)msg=(afIncomingMSGPacket_t*)osal_msg_receive(app_taskid);
while(msg){
switch(msg->hdr.event){
caseZDO_STATE_CHANGE://組網(wǎng)發(fā)送改變
if(msg->hdr.status==DEV_ZB_COORD||
msg->hdr.status==DEV_ROUTER||msg->hdr.status==DEV_END_DEVICE)App_Send();//發(fā)送數(shù)據(jù)函數(shù)}
break;}osal_msg_deallocate((uint8*)msg);//清楚緩存空間//接收數(shù)據(jù)msg=(afIncomingMSGPacket_t*)osal_msg_receive(app_taskid);}
return(events^SYS_EVENT_MSG);}
return
0;}任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack代碼小貼士:代碼:caseZDO_STATE_CHANGE:說明:該事件為組網(wǎng)發(fā)生改變時(shí)的事件。代碼:if(msg->hdr.status==DEV_ZB_COORD||msg->hdr.status==DEV_ROUTER||msg->hdr.status==DEV_END_DEVICE)說明:判斷組網(wǎng)標(biāo)志是否為指定標(biāo)志,DEV_ZB_COORD為協(xié)調(diào)器、DEV_ROUTER為路由器、DEV_END_DEVICE為節(jié)點(diǎn)。為其中一個(gè)則證明組網(wǎng)成功??砂l(fā)送數(shù)據(jù)給協(xié)調(diào)器。任務(wù)實(shí)施步驟21:在myenddevice.c文件下,添加一個(gè)發(fā)送數(shù)據(jù)函數(shù)“App_Send()”代碼如下所示。3.最簡(jiǎn)單的Z-StackvoidApp_Send(void){afAddrType_tmyaddr;myaddr.addrMode=(afAddrMode_t)Addr16Bit;//地址模式為16位模式myaddr.endPoint=20;myaddr.addr.shortAddr=0x0000;//表示發(fā)送給協(xié)調(diào)器AF_DataRequest(&myaddr,&AppDesc,1,2,"1",0,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);}任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack代碼小貼士:代碼:afAddrType_tmyaddr;說明:發(fā)送數(shù)據(jù)給協(xié)調(diào)器時(shí)需要聲明該結(jié)構(gòu)體,該結(jié)構(gòu)體存儲(chǔ)發(fā)送的模式地址等信息。代碼:myaddr.addrMode=(afAddrMode_t)Addr16Bit;說明:表示地址模式共三種 1、短地址模式Addr16Bit 2、擴(kuò)展地址模式Addr64Bit 3、無地址模式AddrNotPresent代碼:myaddr.endPoint=20;說明:與協(xié)調(diào)器保持一致即可,為20。代碼:myaddr.addr.shortAddr=0x0000;說明:0x0000表示均表示為發(fā)送給協(xié)調(diào)器任務(wù)實(shí)施3.最簡(jiǎn)單的Z-Stack代碼小貼士:代碼:AF_DataRequest(&myaddr,&AppDesc,0x0001,2,"1",0,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);說明:該函數(shù)為發(fā)送數(shù)據(jù)函數(shù)至指定設(shè)備板函數(shù)。 參數(shù)1:afAddrType_t結(jié)構(gòu)體發(fā)送設(shè)備地址等信息 參數(shù)2:描述符 參數(shù)3:事件ID號(hào)、與接收中事件m->clusterId匹配 參數(shù)4:發(fā)送數(shù)據(jù)的長(zhǎng)度 參數(shù)5:發(fā)送的數(shù)據(jù) 參數(shù)6:校驗(yàn)包自動(dòng)加1 參數(shù)7:發(fā)現(xiàn)路由默認(rèn)為AF_DISCV_ROUTE 參數(shù)8:傳送跳數(shù)默認(rèn)為AF_DEFAULT_RADIUS任務(wù)實(shí)施步驟22:在mycoordinator.h頭文件編寫,事件接收到數(shù)據(jù)處理函數(shù)App_Send()引用,代碼如下所示。3.最簡(jiǎn)單的Z-Stack#ifndefMYCOORDINATOR_H#defineMYCOORDINATOR_Hextern
voidApp_Init(uint8task_id);externuint16App_Event(uint8task_id,uint16events);extern
voidApp_Msg(afIncomingMSGPacket_t*m);externvoidApp_Send(void);#endif任務(wù)實(shí)施步驟23:開啟協(xié)調(diào)器設(shè)備電源,下載節(jié)點(diǎn)代碼至設(shè)備中,設(shè)置斷點(diǎn)查看是否組網(wǎng)成功,如圖所示。3.最簡(jiǎn)單的Z-Stack圖:組網(wǎng)成功任務(wù)實(shí)施步驟24:全速執(zhí)行,查看協(xié)調(diào)器是否閃爍。閃爍則證明協(xié)調(diào)器接收到數(shù)據(jù),如圖所示。3.最簡(jiǎn)單的Z-Stack圖:燈閃爍任務(wù)實(shí)施一、修改代碼,在節(jié)點(diǎn)設(shè)備發(fā)送數(shù)據(jù)“helloworld”,協(xié)調(diào)器接收數(shù)據(jù)并使LED閃爍,頻率為2s一次。二、在節(jié)點(diǎn)設(shè)備創(chuàng)建新事件,并在新事件下每2秒發(fā)送一次數(shù)據(jù)至協(xié)調(diào)器。技能拓展3.最簡(jiǎn)單的Z-Stack4.無線智能窗簾控制系統(tǒng)本任務(wù)所需硬件:下載器、1塊ZigBee開發(fā)板、光照傳感器、5V電源適配器、USB下載線。環(huán)境準(zhǔn)備任務(wù)實(shí)施任務(wù)實(shí)施
節(jié)點(diǎn)設(shè)備獲取光照傳感器接收光照數(shù)值實(shí)時(shí)發(fā)送數(shù)據(jù)至協(xié)調(diào)器;
協(xié)調(diào)器接收數(shù)據(jù)發(fā)送數(shù)據(jù)至PC上位機(jī)模擬開啟窗簾;
當(dāng)光照大于設(shè)定數(shù)值時(shí)關(guān)閉窗簾,小于時(shí)打開窗簾。任務(wù)要求編寫代碼步驟1:復(fù)制“上述任務(wù)代碼”目錄保存為“工程2”,并打開“工程2\Projects\zstack\Samples\SampleApp\CC2530DB\SampleApp.eww”工程文件,如圖所示。包含mycoordinator、myenddevice文件內(nèi)容。4.無線智能窗簾控制系統(tǒng)圖:文件目錄任務(wù)實(shí)施步驟2:雙擊打開“mycoordinator.c”文件添加串口初始化函數(shù),串口發(fā)送字符、字符串函數(shù)代碼,代碼如右所示。4.無線智能窗簾控制系統(tǒng)voidUartInit(void){P0SEL|=0x0c;//設(shè)置外設(shè)PERCFG=0x00;//設(shè)置I/O位置U0CSR|=0x80;//設(shè)置UART模式U0BAUD=59;//設(shè)置波特率為19200U0GCR=9;//設(shè)置波特率為19200EA=1;//開啟總中斷}voidsend(unsigned
chars){U0DBUF=s;//發(fā)送a
while(!UTX0IF);UTX0IF=0;}voidsendstr(unsigned
char*s,unsigned
charlen){
intcount=0;
while(len--){send(*(s+count));count++;}}任務(wù)實(shí)施代碼小貼士:根據(jù)上位軟件協(xié)議波特率為19200,查看項(xiàng)目四表得出U0BAUD=59、U0GCR=94.無線智能窗簾控制系統(tǒng)步驟3:雙擊打開“mycoordinator.h”頭文件添加串口初始化函數(shù),串口發(fā)送字符、字符串函數(shù)代碼聲明,代碼如下所示。extern
voidUartInit(void);extern
voidsend(unsigned
chars);extern
voidsendstr(unsigned
char*s,unsigned
charlen);任務(wù)實(shí)施步驟4:在mycoordinator.c,初始化函數(shù)App_Init()添加調(diào)用UartInit()串口初始化函數(shù),代碼如下所示。4.無線智能窗簾控制系統(tǒng)voidApp_Init(uint8task_id){app_taskid=task_id;AppDesc.endPoint=20;//端點(diǎn)號(hào)AppDesc.task_id=&app_taskid;//任務(wù)IDAppDesc.simpleDesc=(SimpleDescriptionFormat_t*)&App_SimDesc;AppDesc.latencyReq=noLatencyReqs;//延時(shí)策略afRegister(&AppDesc);//注冊(cè)組網(wǎng)UartInit();//調(diào)用串口初始化}任務(wù)實(shí)施步驟5:在mycoordinator.c,事件消息處理函數(shù)App_Msg()添加接收到數(shù)據(jù)到發(fā)送串口代碼,代碼如下所示。4.無線智能窗簾控制系統(tǒng)voidApp_Msg(afIncomingMSGPacket_t*m){
unsigned
chartmp[3];
switch(m->clusterId){
case
0x0001://接收到包tmp[0]=0xff;tmp[1]=m->cmd.Data[0];tmp[2]=m->cmd.Data[1];sendstr(tmp,3);
break;}}任務(wù)實(shí)施4.無線智能窗簾控制系統(tǒng)代碼小貼士:說明:tmp[0]=0xff;tmp[1]=m->cmd.Data[0];tmp[2]=m->cmd.Data[1];代碼:在發(fā)送緩存發(fā)送頭0xff,m->cmd.Data[0]數(shù)據(jù)高8位,m->cmd.Data[1]數(shù)據(jù)低8位。任務(wù)實(shí)施4.無線智能窗簾控制系統(tǒng)步驟6:切換至EndDeviceEB模式下,開始編寫EndDevice代碼如圖所示。圖:EndDeviceEB任務(wù)實(shí)施步驟7:在myenddevice.c文件中編寫Adc初始化函數(shù)、Adc獲取數(shù)據(jù)函數(shù),代碼如下所示。4.無線智能窗簾控制系統(tǒng)voidAdcInit(){APCFG|=0x01;//設(shè)置P0_0為ADC使用P0SEL|=0x01;//設(shè)置P0_0為外設(shè)口}unsigned
intAdcGet(){
unsigned
inttmp=0;
//參考電壓AVDD5引腳、12位精度ADC、P0_0通道
//啟動(dòng)轉(zhuǎn)換ADCCON3=(0x80|0x30|0x00);ADCIF=0;//清除標(biāo)志
while(!ADCIF);//等待完成tmp=ADCL;//提取低位tmp|=(unsigned
int)(ADCH<<8);//提取高位tmp=tmp>>3;//轉(zhuǎn)換為12位
returntmp;}任務(wù)實(shí)施步驟8:在mycoordinator.h頭文件中編寫Adc初始化函數(shù)、Adc獲取數(shù)據(jù)函數(shù),代碼如下所示。4.無線智能窗簾控制系統(tǒng)extern
voidAdcInit(void);extern
unsigned
intAdcGet(void);步驟9:在myenddevice.c文件中App_Init()函數(shù)下調(diào)用Adc初始化函數(shù),代碼如下所示。voidApp_Init(uint8task_id){app_taskid=task_id;AppDesc.endPoint=20;//端點(diǎn)號(hào)AppDesc.task_id=&app_taskid;//任務(wù)IDAppDesc.simpleDesc=(SimpleDescriptionFormat_t*)&App_SimDesc;AppDesc.latencyReq=noLatencyReqs;//延時(shí)策略afRegister(&AppDesc);//注冊(cè)組網(wǎng)AdcInit();//adc初始化}任務(wù)實(shí)施步驟10:在myenddevice.c文件中App_Event()函數(shù)下加入一個(gè)OSAL時(shí)間事件每秒發(fā)生一次,代碼如下所示。4.無線智能窗簾控制系統(tǒng)uint16App_Event(uint8task_id,uint16events){afIncomingMSGPacket_t*msg;
//系統(tǒng)事件定義
if(events&SYS_EVENT_MSG){msg=(afIncomingMSGPacket_t*)osal_msg_receive(app_taskid);//接收數(shù)據(jù)
while(msg){
switch(msg->hdr.event){
caseZDO_STATE_CHANGE://組網(wǎng)發(fā)送改變
if(msg->hdr.status==DEV_ZB_COORD||msg->hdr.status==DEV_ROUTER||msg->hdr.status==DEV_END_DEVICE){
//開始接收光照數(shù)據(jù)osal_start_timerEx(app_taskid,0x0001,1000);}break;}osal_msg_deallocate((uint8*)msg);//清楚緩存空間msg=(afIncomingMSGPacket_t*)osal_msg_receive(app_taskid);//接收數(shù)據(jù)}
return(events^SYS_EVENT_MSG);}
//接收事件
if(events&0x0001){tmp=AdcGet();App_Send(tmp);osal_start_timerEx(app_taskid,0x0001,1000);}
return
0;}任務(wù)實(shí)施4.無線智能窗簾控制系統(tǒng)代碼小貼士:說明:if(events&0x0001){tmp=AdcGet();App_Send(tmp);osal_start_timerEx(app_taskid,0x0001,1000);}代碼:如果發(fā)生0x0001事件事件時(shí),獲取Adc光照值數(shù)據(jù),并調(diào)用App_Send函數(shù)發(fā)送數(shù)據(jù)至協(xié)調(diào)器。最后重新生成事件1000后繼續(xù)調(diào)用。任務(wù)實(shí)施步驟11:在myenddevice.c文件中App_Send()函數(shù)下發(fā)送tmp光照值數(shù)據(jù)至電腦中,代碼如下所示。4.無線智能窗簾控制系統(tǒng)voidApp_Send(uint16d1){
unsigned
chara[2];a[0]=d1/100;a[1]=d1%100;afAddrType_tmyaddr;myaddr.addrMode=(afAddrMode_t)Addr16Bit;//地址模式為16位模式myaddr.endPoint=20; myaddr.addr.shortAddr=0x0000;//表示發(fā)送給協(xié)調(diào)器AF_DataRequest(&myaddr,&AppDesc,1,2,a,0,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);P1_0=1;}任務(wù)實(shí)施4.無線智能窗簾控制系統(tǒng)代碼小貼士:代碼:a[0]=d1/0x100;a[1]=d1%0x100;說明:將d1拆分成除以100取出高8位和取余數(shù)取出
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年保山市隆陽區(qū)消防救援局公開招聘財(cái)務(wù)人員的備考題庫帶答案詳解
- 2025年浙江省經(jīng)濟(jì)建設(shè)投資有限公司招聘5人備考題庫及1套參考答案詳解
- 2025年遼控集團(tuán)所屬國(guó)合集團(tuán)招聘?jìng)淇碱}庫及答案詳解1套
- 2025年無錫市第五人民醫(yī)院公開招聘高端緊缺類專技人才5人備考題庫(長(zhǎng)期)完整答案詳解
- 衛(wèi)建系統(tǒng)考試試題及答案
- 2025年長(zhǎng)嶺縣衛(wèi)健系統(tǒng)事業(yè)單位公開招聘工作人員(含專項(xiàng)招聘高校畢業(yè)生)備考題庫完整答案詳解
- 2025年南康公開招聘7人備考題庫及1套完整答案詳解
- 2025年錢塘中心衛(wèi)生院衛(wèi)生監(jiān)督協(xié)管服務(wù)項(xiàng)目培訓(xùn)考試題及答案
- 2025年安徽皖新融資租賃有限公司服務(wù)人員第二批次招聘?jìng)淇碱}庫及1套參考答案詳解
- 2025年湛江市美術(shù)中學(xué)招聘臨聘教師8人備考題庫及一套答案詳解
- 浙江省諸暨市2025年12月高三診斷性考試化學(xué)(含答案)
- 城鄉(xiāng)供水一體化項(xiàng)目施工方案
- 2025年人工智能訓(xùn)練師(中級(jí))職業(yè)資格考試核心要點(diǎn)參考題庫(300題)含答案
- 2025版《道德與法治新課程標(biāo)準(zhǔn)》課標(biāo)測(cè)試卷測(cè)試題庫(含答案)
- 恒溫恒濕倉儲(chǔ)管理操作流程規(guī)范
- 2024年秋季新人教版七年級(jí)上冊(cè)地理全冊(cè)教學(xué)課件(新版教材)
- 25秋國(guó)家開放大學(xué)《管理英語2》形考任務(wù)參考答案
- 雨課堂在線學(xué)堂《項(xiàng)目管理概論》作業(yè)單元考核答案
- 雨課堂在線學(xué)堂《軍事理論》課后作業(yè)單元考核答案
- 氣象學(xué)與氣候?qū)W基礎(chǔ)題庫及答案
- 安全生產(chǎn)隱患排查工作總結(jié)
評(píng)論
0/150
提交評(píng)論