A9139M0 星形組網 1Master to 512 Slave Node
本篇使用A9139M0 製作1 to 512 Network System ,Master (集中器)可以同時連接512個Slave(Node節點ex:溫溼度計) 傳送資料,本系統採用星形組網架構,Master會主動分配設備ID,並主動輪詢每個Slave是否有資料要回傳,當其中一個Slave離線,Master也會主動空出此Slave的ID給其他需要加入的Node分配新的ID
P.S.
1.此系統為1 Master與512 Slave做資料交換系統,彼此Slave Node間是"無法"交涉資料的,資料都需要經過Master轉發才可以,因此若有需要ex:第100 node Slave 要跟第 200 node Slave做資料交換,就需要先經過master才能互相轉發。
2.此組網系統比較適用於1個集中器收集n個Node資料時使用,Node跟Node間不需要做資料交換。
整體系統的RF傳輸採用雙向的T/RX傳輸,Master會主動Request,Slave收到Request後會Response,也就是說Master負責調度與Slave設備之間的通信。Master決定何時、與哪個Slave設備進行通信,並控制RF資源的分配。
而Slave設備處於被動狀態,它們等待主設備的命令,並根據收到的命令執行相應的操作,如傳輸數據或回應請求,Slave設備僅在Master設備允許或要求時才進行數據傳輸,這可以有效避免數據碰撞和通信衝突。
此系統為一個固定1 to 512資源分配系統,經實測每個Node需要經過"41.31s"後才會主動被Master再次喚醒"做時序對準",時序對準後會再休眠 "0.154 "才會被喚醒進入接收 Master 資料與回傳Slave資料
也就是當Node數未滿512個,每個Node之間還是需要經41.31s+0.154s後才會被動收到Master分配的資源
Demo Code:<RC_A9139M0_x1_433MHz Band Ref. Code for FIFO mode V0.4_1to512_NetworkSystemDemo_ADC_20241029.zip>
此Demo Code為實現Slave端具有ADC Input檢測功能(模擬溫濕度計變化),Master請求Slave將每個Node的ADC 值做回傳收集動作
底下為設定A9139M0的RF 參數與Load Config /InitRF等初始化RF動作,這邊就不再贅述
ConfigType = SelectConfig; __disable_irq(); // Clear reset flag //Initial HW InitMCU(); CrystalSelect(); RFLIB_InitCrystalCL ( 28 ); //CrystalCL 0x1C(20pF) Delay100us ( 5 ); //Delay 500us For Regulator Stabilized RFLIB_Reset ( RF_RST ); CalResult = RFLIB_InitRF(); if ( CalResult ) //Check Return Value In A9139M0_RFLIB.h Err_State(); RFLIB_StrobeCmd ( CMD_STBY ); //User define UserRegister(); PWRCTL1_Reg = A9139M0_Config[INDEX_PWRCTL1].load[ConfigType]; POWER->PWR_TA = 0xAAAAAAAA; POWER->PWR_TA = 0x55555555; POWER->POWERCTRL1 = PWRCTL1_Reg & 0xFFBFFFFF ;//RGS Bit22 = 0
一些RF基礎設定
1.寫入RF協議ID,注意這裡的ID指的是RF協議層的ID Code,並非組網的設備ID
2.設定RF TX power,相關的Tx Power可參考此份App Node,調整對應的TX power參數AN_A9129M0F7_HW_U00 V0.1.pdf
3. 設定RF FIFO 長度,這裡設定 55Byte = head 7(6+1) data 48(5+43)共55Byte的Tx/Rx Packet
4. 需開啟FSK調變
5. Enable CRC
6.Enable RTC==>用於睡眠時的計時器
A9139M0_WriteID();//此ID為RF協議的ID Code並非組網的Slave的ID Node TXPower ( 63, 2 , 1);// , SelectConfig); //TBG=12~63 TDC=0~3 PAC=0~1 FIFOLength ( RF_Length); TXModeSel ( FIFO);// , SelectConfig); TXModulation ( ENABLE);// , SelectConfig); CODE1_Reg = CODE1_Reg |0x00000009; RADIO->CODE1 = CODE1_Reg;//0x3D580309;//CODE1_Reg; CRCS MSCRC RTC_Enable();
初始化Link模式,可以使用P0.11來選擇Master/Slave端,也可以不使用P0.11,直接開啟定義_MASTER_MODE_ & 關閉_MASTER_MODE_來定義Master/Slave端,最後將ID_MAC_ADDRESS[5]資料塞入AddressID[0],ID_MAC_ADDRESS[4]資料塞入AddressID[1],後面會將此2 Byte塞入要發射的TX 封包裡當作資料包頭
InitLink();
void InitLink(void) { #ifdef _IO_SET_MODE_ if ( GPIO0->DATA_PIN.P11 ) //master { InitMaster(); } else //P0.11=0, slave { InitSlave(); } #else #ifdef _MASTER_MODE_ InitMaster(); #else InitSlave(); #endif #endif AddressID[0] = ID_MAC_ADDRESS[5]; AddressID[1] = ID_MAC_ADDRESS[4]; }
初始化Uart0 P0.16/P0.17 波特率Uart 8bit, Baud Rate 230400,目的是為了後面輸出UART資料使用
void InitUART0(void) { Uint32 baudrate; // 12.8MHz, 230400KHz baudrate = 230400; UART0->BAUDDIV = SystemCoreClock / baudrate; UART0->CTRL = 0x0F; GPIO0->ALTFUNCSET |= BIT16 | BIT17; NVIC_EnableIRQ( UART0_IRQn ); }
RF_SetBBIO函數是開啟/關閉 gio1,gio2,cko這三隻Pin是要當作RF的State Pin或是普通i/o pin
RF_SetBBIO
組網系統主要分成2大部分,分別為”配對模式” 與 “資料傳送模式
P.S. Master 在每個頻率與 Slave 配對/資料傳送前會先去偵測環境的 RSSI 值,環境的 RSSI 值大於設定值時該頻率不與 Slave 做配對/資料傳送之動作。
開啟adc檢測rssi 值
//Auto Rssi ADC_Reg = ADC_Reg & 0xFFFFF0E7; ADC_Reg = ADC_Reg | 0x00000018; RADIO->ADC = ADC_Reg;//0x00200380;//0x50001240
RSSI檢測部分Amiccom已經封裝成"SetMasterTx_RSSI_Threshold"函數,用戶只需要調整此函數的Value則可改變檢測的門檻值預設=150約-75dBm,數值越大,表示檢測的RSSI Power越大,觸發門檻的環境干擾就要越大
SetMasterTx_RSSI_Threshold(150);
檢測完Rssi後,Master可以主動檢測若未收到Slave Response 回來的次數滿幾次後,就主動認為此Slave已斷線,並將此設備ID讓出來給其他新的Slave使用,使用者可以調整"SetMasterDataLostBackLinkMode"函數來設定此功能
預設=5,表示該Master連續3次發送Request後都未收到Slave端Response ,Master 會將 設備ID釋出。
SetMasterDataLostBackLinkMode(5);
此系統設計Master/Slave的Data Len=48Byte,因此我們需要先執行TxDatatInit函數,將資料寫入MasterSlaveTxBuff,這邊只是先對MasterSlaveTxBuff寫入隨意資料,為了只是填充該數組而已,並非真實要發射的資料
void TxDatatInit(void) { Uint8 i; { for (i=0;i<DATA_Length;i++) { MasterSlaveTxBuff[i] = i;//MasterSlaveRxBuff[SlaveNodeNum][i];// | 0x80; } } }
啟動Timer0 ,該Timer被用來分配每個Slave交換時間,因此也被Amiccom給封裝起來,這裡只需調用即可
EnableTimer0();
再開始進入組網時我們還可以調整頻率參數" FreqChannel_Tab[3] ",系統預測使用3個頻點進行跳頻,關於如何設定頻點對應相應的PLL2 PLL3 PLL4 Reg值,可以參考之前介紹過使用Amiccom EK Tool去計算該頻點對應的Value,這邊也會根據之前設定的RSSI_Threshold去決定是否要拋棄某個不乾淨的頻點
const Uint32 FreqChannel_Tab[3] = { //PLL2 PLL3 PLL4 0x00875014, //freq 433.001MHz 0x00879014, //freq 433.801MHz 0x0087D014, //freq 434.601MHz };
配對模式介紹:
因為組網的配對流程與如何篩選配對Slave的部分,被Amiccom封裝在MasterProcess()函數裡,這邊只能介紹整體配對的設計概念
Master上電後為配對模式,Master系統會自動生成一設備ID與 Slave 端連接後,會將此ID分配給該 Slave,而此 Slave會進入資料傳送模式,Master 工作於資料傳送模式中亦會不定時去偵測有無新的 Slave 加入,並進行配對。
如何配對 :
Master 第一次使用時需依序與slave配對,配對方式為Slave上電後收到Master配對Response後完成配對。
Master 與Slave 配對後,若有重新上電或是Reset時會重新進入配對連線。
Master 在未配對滿全部slave (512 Slave Node)時,都可隨時跟新的Slave 配對。
如何確認該設備ID 狀態 :
使用者可自行透過讀取資料陣列變數NodeState[slot] 確認現在 所有/個別Slot(ID設備)的狀態(可利用迴圈確認所有Slot狀態,單一值確認單個Slot狀態,Slot範圍為0~511)。值為0x01時表示該ID是空的,為0x02時表示該ID已配對已連線傳送資料,為0x04時表示該ID正在配對。
使用者可從 NodeReceive[slot]、NodeLost[slot]、NodeDisconnect[slot]得知對應Slot(ID設備)的資訊。
NodeReceive[slot]:在資料傳送模式收到資料就會加1,一旦NodeLost[slot]加1就會清為0。
NodeLost[slot]:未接收到資料就會加1,一旦NodeReceive[slot]加1就會清為0。
NodeDisconnect[slot]:從資料傳送模式離開就會加1。
附註:以上三者為8 bit counter 超過255就變為0。
這些數據也都會輸出到UART供使用者Check連線狀態
程式碼會構造 "Data" 開頭的字串,並將節點的"編號"、"接收數據"、"丟失數據"和"斷開數據"格式化後加入到
UartBuffer,
同時,若Flag1.bit.MasterDataOkFlag
為真,則會將主從通信緩衝區(MasterSlaveRxBuff
)的數據轉換為十六進制格式,並加入到UartBuffer
中,最後,使用UartTx(receive)
將完整的數據發送出去Master Uart內容(目的是為了解測與Slave的連線狀況 & 輸出master要發給slave的資料內容):
void MasterUartOut(void) { Uint16 i; Uint8 lost; Uint8 receive; Uint8 disconnect; Uint16 slot; slot = MasterSlot; { lost = NodeLost[slot]; receive = NodeReceive[slot]; disconnect = NodeDisconnect[slot]; if (NodeState[slot]==DATA_STATE) { UartBuffer[0] = 'D'; UartBuffer[1] = 'a'; UartBuffer[2] = 't'; UartBuffer[3] = 'a'; UartBuffer[4] = '_'; i = slot; if (i>999) { i = i/1000; UartBuffer[5] = '0'+i; } else { UartBuffer[5] = '0'; } i = slot%1000; if (i>99) { i = i/100; UartBuffer[6] = '0'+i; } else { UartBuffer[6] = '0'; } i = slot%100; if (i>9) { i = i/10; UartBuffer[7] = '0'+i; } else { UartBuffer[7] = '0'; } i = slot%10; UartBuffer[8] = '0'+ i; UartBuffer[9] = ' '; if (receive>99) { i = receive/100; UartBuffer[10] = '0' + i; receive = receive % 100; } else UartBuffer[10] = ' '; if (NodeReceive[slot]>9) { i = receive/10; UartBuffer[11] = '0' + i; receive = receive % 10; } else UartBuffer[11] = ' '; UartBuffer[12] = '0'+receive; UartBuffer[13] = ' '; if (lost>99) { i = lost/100; UartBuffer[14] = '0' + i; lost = lost % 100; } else UartBuffer[14] = ' '; if (NodeLost[slot]>9) { i = lost/10; UartBuffer[15] = '0' + i; lost = lost % 10; } else UartBuffer[15] = ' '; UartBuffer[16] = '0'+lost; UartBuffer[17] = ' '; if (disconnect>99) { i = disconnect/100; UartBuffer[18] = '0' + i; disconnect = disconnect % 100; } else UartBuffer[18] = ' '; if (NodeDisconnect[slot]>9) { i = disconnect/10; UartBuffer[19] = '0' + i; disconnect = disconnect % 10; } else UartBuffer[19] = ' '; UartBuffer[20] = '0'+disconnect; receive = 21; if (Flag1.bit.MasterDataOkFlag) { //for (i=0;i<5;i++) for (i=0;i<DATA_Length;i++) { UartBuffer[receive] = ' '; receive++; lost = (MasterSlaveRxBuff[i])>>4; if (lost>9) UartBuffer[receive] = 'A'+lost-10; else UartBuffer[receive] = '0'+lost; receive++; lost = (MasterSlaveRxBuff[i])&0x0F; if (lost>9) UartBuffer[receive] = 'A'+lost-10; else UartBuffer[receive] = '0'+lost; receive++; } } UartBuffer[receive++] = 0x0D; UartBuffer[receive++] = 0x0A; UartTx(receive); } else { if (NodeState[slot]==LINK_STATE) { UartBuffer[0] = 'L'; UartBuffer[1] = 'i'; UartBuffer[2] = 'n'; UartBuffer[3] = 'k'; } else { UartBuffer[0] = 'A'; UartBuffer[1] = 's'; UartBuffer[2] = 's'; UartBuffer[3] = 'i'; } UartBuffer[4] = '_'; i = slot; if (i>999) { i = i/1000; UartBuffer[5] = '0'+i; } else { UartBuffer[5] = '0'; } i = slot%1000; if (i>99) { i = i/100; UartBuffer[6] = '0'+i; } else { UartBuffer[6] = '0'; } i = slot%100; if (i>9) { i = i/10; UartBuffer[7] = '0'+i; } else { UartBuffer[7] = '0'; } i = slot%10; UartBuffer[8] = '0'+ i; UartBuffer[9] = ' '; if (receive>99) { i = receive/100; UartBuffer[10] = '0' + i; receive = receive % 100; } else UartBuffer[10] = ' '; if (NodeReceive[slot]>9) { i = receive/10; UartBuffer[11] = '0' + i; receive = receive % 10; } else UartBuffer[11] = ' '; UartBuffer[12] = '0'+receive; UartBuffer[13] = ' '; if (lost>99) { i = lost/100; UartBuffer[14] = '0' + i; lost = lost % 100; } else UartBuffer[14] = ' '; if (NodeLost[slot]>9) { i = lost/10; UartBuffer[15] = '0' + i; lost = lost % 10; } else UartBuffer[15] = ' '; UartBuffer[16] = '0'+lost; UartBuffer[17] = ' '; if (disconnect>99) { i = disconnect/100; UartBuffer[18] = '0' + i; disconnect = disconnect % 100; } else UartBuffer[18] = ' '; if (NodeDisconnect[slot]>9) { i = disconnect/10; UartBuffer[19] = '0' + i; disconnect = disconnect % 10; } else UartBuffer[19] = ' '; UartBuffer[20] = '0'+disconnect; UartBuffer[21] = 0x0D; UartBuffer[22] = 0x0A; UartTx(23); } } }
輸出欄位介紹:
Uart輸出“Link_xxx RRR LLL DDD ” ,表示xxx節點在等待Slave配對模式,RRR表示接收到過幾筆資料,LLL表示未接收到過幾筆資料,DDD表示斷線過次數,如下圖。
Uart輸出“Assi_xxx RRR LLL DDD ” ,表示xxx節點在Slave配對模式,RRR表示接收到過幾筆資料,LLL表示未接收到過幾筆資料,DDD表示斷線過次數,如下圖。
Uart輸出“Data_xxx RRR LLL DDD HH HH HH …..” ,表示xxx節點在Slave 已配對資料傳送模式,RRR表示接收到過幾筆資料,LLL表示未接收到過幾筆資料,DDD表示斷線過次數,HH為MasterSlaveRxBuff[]接收的資料內容。
傳送資料模式
資料傳送模式下Master會在每個Slave傳送48 Bytes 資料,MasterSlaveTxBuff[48]為存放要傳送出去的資料陣列變數,位於MasterTxDatatSet 函數裡
MasterSlaveTxBuff[0] & MasterSlaveTxBuff[1]被先前介紹的AddressID[0] & AddressID[1]給佔用,因此這裡從 MasterSlaveTxBuff[2]開始填
void MasterTxDatatSet(void) { Uint16 slot; Uint8 i; slot = MasterSlot; { if (NodeState[slot]==DATA_STATE) { MasterSlaveTxBuff[2] = MasterSlaveTxBuff[2]+1; MasterSlaveTxBuff[3] = MasterSlaveTxBuff[2]; MasterSlaveTxBuff[4] = MasterSlaveTxBuff[3]; } } //使用者可以利用MasterSlaveTxBuff[5]後面的空間buffer塞入想傳送給Slave端的資料,這裡只是假設用個for迴圈++ 5~48的數組而已,使用者可以自行替換掉 for (i=5;i<DATA_Length;i++) { MasterSlaveTxBuff[i] = i;//MasterSlaveRxBuff[SlaveNodeNum][i];// | 0x80; } }
當Flag1.bit.MasterDataOkFlag = 1時表示有收到Slave傳送過來的資料,此Flag會在下個slot開始時清除,使用者可自行在系統非忙碌時處理Slave回傳資料。
程式中MasterProcessBusyFlag旗標等於1時表示系統處與送收資料忙碌中,使用者要操作系統需在旗標等於0時操作。
Slave Node端:
Slave 第一次使用一樣會處於配對模式,會在三個不同頻率切換連線Master,連線後進入資料傳送模式,Slave設的頻率方式與Master一樣。
配對的流程Code,一樣被寫入SlaveProcess();函數裡,這裡只能介紹說明其流程
1. Slave 一開始會進入Rx搜尋Master作對準時間。
2. 收到MasterData 對準時間後,會隨意產生1~512的數值,之後的1~512 slot(ID設備)來做回應Master配對請求,並得到可配對的slot。
3. 在回應Master配對請求後,會進入休眠到可配對的ID後,才喚醒確認是否可跟Master配對,如果失敗則重新配對。
4. 如果Slave同時多的上電時,則需考慮Slave同時回應問題,同一時間勿超過32個Slave上電,Slave數量越少越少配對碰撞配對失敗狀況
這區塊猜測是在做Slave接收Master的Request資料,因Amiccom原廠並沒有對此區塊多做說明,且代碼函數被封裝起來,無法做詳細說明,姑且先當在做Slave Node Receive的部分
if(NodeReceive[SlaveNodeNum] != TestReceiveCnt ) { TestReceiveCnt = NodeReceive[SlaveNodeNum]; TestDataCnt0++; if (TestDataCnt0==0) { TestDataCnt1++; if (TestDataCnt1==0) TestDataCnt2++; } }
這邊是當Slave收完Master的Request時,開始要向Master Response資料,這裡使用的是一adc輸入值當作是要Response給master的資料內容
else { //Uart output if ((UartOutFlag)) { UartOutFlag = 0; SlaveUartOut(); while (Uart_TxLen<Uart_TxCnt) { __NOP();//_nop_(); } ADC_Val = ADC12B_Measure ( ADC12B, 1 ); SlaveTxDatatSet(); } SlavePowerDown(); }
SlaveUartOut函數為輸出master傳輸過來的資料,如SlaveNodeNum & Master Request 資料
void SlaveUartOut(void) { Uint8 i; Uint8 j; Uint8 tmp; UartBuffer[0] = 'D'; UartBuffer[1] = 'a'; UartBuffer[2] = 't'; UartBuffer[3] = 'a'; UartBuffer[4] = '_'; if (SlaveNodeNum>9) { i = SlaveNodeNum/10; UartBuffer[5] = '0'+i; i = SlaveNodeNum%10; UartBuffer[6] = '0'+ i; //UartBuffer[5] = '1'; //UartBuffer[6] = '0'+ SlaveNodeNum-10; } else { UartBuffer[5] = '0'+ SlaveNodeNum; UartBuffer[6] = ' '; } UartBuffer[7] = ' '; j = 8; for (i=0;i<DATA_Length;i++) { UartBuffer[j] = ' '; j++; tmp = (MasterSlaveRxBuff[i])>>4; if (tmp>9) UartBuffer[j] = 'A'+tmp-10; else UartBuffer[j] = '0'+tmp; j++; tmp = (MasterSlaveRxBuff[i])&0x0F; if (tmp>9) UartBuffer[j] = 'A'+tmp-10; else UartBuffer[j] = '0'+tmp; j++; } UartBuffer[j++] = 0x0D; UartBuffer[j++] = 0x0A; UartBuffer[j++] = 0xFF; UartTx(j); }
ADC使用A9139M0的Pin 0.19當作輸入pin,這部分可以根據使用者的需求加入應用代碼,不一定是ADC功能,也可以是其他SPI/I2C/IO中斷檢測等(這裡只是用ADC當作Demo而已)
ADC_Val = ADC12B_Measure ( ADC12B, 1 );
uint32_t ADC12B_Measure(ADC12B_Type *adc12b, uint32_t ch) { uint32_t control = 0; uint32_t mvadc; adc12b->Control = ADC12B_CONTROL_ADC12RN_Msk; // ADC reset control = ADC12B_CONTROL_ADCE_Msk | // start ADC measure (6 << ADC12B_CONTROL_VADS_Pos) | // Ref Voltage = 1.8V (3 << ADC12B_CONTROL_MVS_Pos) | // Average 8 times (0 << ADC12B_CONTROL_CKS_Pos) | // clock 3.2MHz ADC12B_CONTROL_ENADC_Msk | // ADC clock on ADC12B_CONTROL_MODE_Msk; // continue mode switch(ch) { case 0: GPIO0->OUTENABLECLR = ( 1 << 18 ); // set to input GPIO0->PUN_PIN.P18 = 1; // disable pull-high break; case 1: GPIO0->OUTENABLECLR = ( 1 << 19 ); // set to input GPIO0->PUN_PIN.P19 = 1; // disable pull-high break; case 2: GPIO0->OUTENABLECLR = ( 1 << 8 ); // set to input GPIO0->PUN_PIN.P08 = 1; // disable pull-high break; case 3: GPIO0->OUTENABLECLR = ( 1 << 9 ); // set to input GPIO0->PUN_PIN.P09 = 1; // disable pull-high break; case 4: GPIO0->OUTENABLECLR = ( 1 << 12 ); // set to input GPIO0->PUN_PIN.P12 = 1; // disable pull-high break; case 5: GPIO0->OUTENABLECLR = ( 1 << 13 ); // set to input GPIO0->PUN_PIN.P13 = 1; // disable pull-high break; case 6: GPIO0->OUTENABLECLR = ( 1 << 14 ); // set to input GPIO0->PUN_PIN.P14 = 1; // disable pull-high break; case 7: GPIO0->OUTENABLECLR = ( 1 << 15 ); // set to input GPIO0->PUN_PIN.P15 = 1; // disable pull-high break; } adc12b->ADCIOS = ((ch << ADC12B_IOSEL_CH_Pos) & ADC12B_IOSEL_CH_Msk) | ADC12B_IOSEL_EN_Msk; adc12b->Control = control; // ADC measure start //----------------------------------------------------- // Delay for ADC measure // delay time = 2*(32*8)/3.2M = 160us Delay10us(16); //----------------------------------------------------- mvadc = adc12b->ValueItem.MVADC; // read mvadc value adc12b->Control = 0; // close ADC 12Bits adc12b->ADCIOS = 0; // close ADC channel return mvadc; }
檢測完ADC後再將其值塞入SlaveTxDatatSet函數中的MasterSlaveTxBuff裡,這裡是ADC的Low Byte寫在 MasterSlaveTxBuff[5],High Byte寫在 MasterSlaveTxBuff[6]傳給Master,前面[0]~[1]為ID MAC固定格式,[2]~[4]為計算接收到過幾筆資料,未接收到過幾筆資料,斷線過次數,[5]~[6]=ADC檢測值,[7]~[47]=使用者可自行定義封包值
void SlaveTxDatatSet(void) { Uint8 i; /*for (i=0;i<DATA_Length;i++) { MasterSlaveTxBuff[SlaveNodeNum][i] = MasterSlaveRxBuff[SlaveNodeNum][i];// | 0x80; }*/ MasterSlaveTxBuff[0] = AddressID[1];//ID_MAC_ADDRESS[6]; MasterSlaveTxBuff[1] = AddressID[0];//ID_MAC_ADDRESS[7]; MasterSlaveTxBuff[2] = TestDataCnt0; MasterSlaveTxBuff[3] = TestDataCnt1; MasterSlaveTxBuff[4] = TestDataCnt2; ADC_Val_L = (Uint8)ADC_Val; ADC_Val_H = (Uint8)(ADC_Val>>8); MasterSlaveTxBuff[5] = ADC_Val_L; MasterSlaveTxBuff[6] = ADC_Val_H; for (i=7;i<DATA_Length;i++) { MasterSlaveTxBuff[i] = i;//MasterSlaveRxBuff[SlaveNodeNum][i];// | 0x80; } }
Slave發送完1包給master後主動進入休眠模式SlavePowerDown,等待下次Master的Request
SlavePowerDown();
補充Slave端還有以下參數可以調整
設定連續未收到資料次數:
使用者可以利用SetSlaveDataLostBackLinkMode fucntion來設定連續未收到資料次數,預設連續5次喚醒都未收到則會重新進入配對模式。
SetSlaveDataLostBackLinkMode(5);
設定配對時間:
使用者可以利用 SetSlaveLinkTimeout function 來設定配對時間,預設如果 6000 秒內都未連線 Master,則會離開配對模式進入休眠模式。
SetSlaveLinkTimeout(6000);
設定休眠時間與配對周期 :
Slave休眠一段時間後會重新醒來配對,使用者可以利用"SetSlaveReLinkSleepTimer"設定重新配對周期。配對周期是配對時間加上休眠時間,預設6000秒配對時間與10秒休眠時間,則配對周期是6010秒。
SetSlaveReLinkSleepTimer(10);
設定配對周期次數 :
使用者可以利用SetSlaveReLinkTime function來設定配對周期次數,預設3週期未連線後則完全休眠不再喚醒,需重新上電或Reset才可回到配對模式。(也就是徹底放棄掉此Slave端設備,直到Slave重新上電進入配對)
SetSlaveReLinkTime(5);
配對成功時會得到分配的節點編號存放在"SlaveNodeNum"變數中
傳送資料模式:
在資料傳送模式下可以接收Master傳送的48 Bytes 資料,資料存放在MasterSlaveRxBuff[]數組裡,使用者可在系統非忙碌時處理接收Master傳送的資料。
在接收完也可以傳送48 Bytes資料給Master。使用者可在SlaveTxDatatSet 函數中透過MasterSlaveTxBuff[]數組夾帶要傳給master端的資料內容
到此我們就完成1跟Master如何Request Slave Node,並且Slave如何Response資料給Master,也算是一種多次Request/ Response來回傳遞的組網系統。