使用SPI輸入Data給A8137 Tx發射資料,且喚醒對端A8137 低功率Rx(Wake Up On Rx)收到Data後,再經由SPI輸出Data
系統流程圖:
1. Tx端接線為P3_5=1,開啟SPI Function ,這裡A8137為了能接收另一顆MCU餵進來的Data,所以使用Slave mode,當SPI 系統啟動後,A8137 SPI 的MOSI將自動讀取SPDR資料填入SPI Buf裡,直到SPI Buf 塞滿64Byte
if (P3_5) { SSCR = 0xFF; // SCS=1 SPSR = 0x00; // SSEN=0; ESPI = ENABLE; // enable SPI MODULE interrupt EA = ENABLE; ESPI = DISABLE; // disable SPI MODULE interrupt SPCR = SPI_SPE;//SPI interrupt disable,SPI System enable,slave mode SPICnt=0; for(i = 0; i < 64; i++) SPIBuf[i]=0; while (1) { while(SPICnt!=64) { while ( P0_3 == LOW ) _nop_(); // wait SSO turn high SPDR =0x00; while ( ( SPSR & SPI_SPIF ) == 0 ); SPIBuf[SPICnt++] = SPDR; } SPICnt=0;
2. 由於此範例的"客戶MCU端"SPI是傳送一組從0x00,0x01,0x02,0x03.....0x3F的累加數據,所以這邊會先做一次數據的判斷,判斷A8137的SPI 接收,是否收到跟"客戶MCU端"SPI發送過來的資料是一致的,所以底下加入TEST LED Function,若資料一致將LED=0,反之不一致將LED=1
//TEST LED for(i = 0; i < 64; i++) { if(SPIBuf[i]==i) { P1_7=0; } else { P1_7=1; break; } }
3. 將A8137 SPI 收到的資料依序填入FIFO Buffer裡面,發送100次,這邊發射100次的目的,是為了能增加更大機率能喚醒對端的低功耗Rx Mode,發射完後將P1_1=0,作為一個提示功能
//write SPI data to FIFO Buffer for(i = 0; i < 64; i++) RFLIB_WriteReg(TXFIFO_REG + i , SPIBuf[i]); for(i = 0; i < 100; i++) { RF_Flag = 0; RFLIB_StrobeCmd(CMD_TX); //entry tx & transmit Delay10us(1); while(RF_Flag == 0); //wait transmit completed // Delay10ms(1); } P1_1=0;
============================================================================
Rx 端:
1. Rx端一開機後,A8137會進入WOR低功耗接收模式
WOR(24, 6, 1);
底下是WOR設定,可以根據rbt調整wakeup time & rbto調整sleep time,不過這邊建議使用原廠參數即可
注意:運行WOR功能是,因為會執行A8137_PM(2);也就是將A8137進入PM2 Mode,此時A8137的MCU Clock將OFF,直到A8137收到正確ID CODE時,才會重啟MCU,將FIFO Data給收下來
void WOR(Uint32 rbt, Uint16 rbto, Uint8 wus) { Uint8 rbt1, rbt2, rbt3; Uint8 rbto1, rbto2; RFLIB_WriteReg(GIO1_REG, 0x08); //GIO1=WOR RFLIB_WriteReg(GIO2_REG, 0x40); //GIO2=PDN_RX rbt1 = (rbt & 0x000000FF) >> 0; rbt2 = (rbt & 0x0000FF00) >> 8; rbt3 = (rbt & 0x00FF0000) >> 16; rbto1 = (rbto & 0x00FF) >> 0; rbto2 = (rbto & 0xFF00) >> 8; RFLIB_WriteReg(RBT_REG + 0, rbt1); //RBT -> Wakeup time RFLIB_WriteReg(RBT_REG + 1, rbt2); //RBT -> Wakeup time RFLIB_WriteReg(RBT_REG + 2 ,rbt3); //RBT -> Wakeup time RFLIB_WriteReg(RBTO_REG + 0, rbto1); //RBTO -> RX Active time RFLIB_WriteReg(RBTO_REG + 1, rbto2); //RBTO -> RX Active time if(wus > 3) wus = 3; RFLIB_WriteReg(RCOSC1_REG, 0x82 | (wus << 4)); //WUS -> wakeup mode RFLIB_WriteReg(RSTCTRL_REG, BFC_RST); //Back-off counter reset if(wus == 3) RFLIB_WriteReg(MODECTRL_REG, 0x02 | 0x08 | 0x80); //Enable WOR, Enable DFCRC else RFLIB_WriteReg(MODECTRL_REG, 0x02 | 0x08); //Enable WOR A8137_PM(2); while(GIO2==0); RFLIB_WriteReg(MODECTRL_REG, 0x02); //disable WOR return; }
2. 當WOR成功喚醒後,執行RX CMD將資料收下並填入Rx Data Buffer裡面
P1OE=0xFF; RF_Flag = 0; RFLIB_StrobeCmd(CMD_RX); P0_6=1; Delay10us(1); while(RF_Flag == 0); //wait receive completed RxPacket(); P1_1=~P1_1;
3. 這邊使用A8137的P0.6拉LOW通知客戶端MCU,需要將SPI 打開,並開始收下A8137 MISO發送出來的Data
設定A8137 Rx端的SPI,並且將P0_6 Pin拉Low
SSCR = 0xFF; // SCS=1 SPSR = 0x00; // SSEN=0; ESPI = ENABLE; // enable SPI interrupt EA = ENABLE; ESPI = DISABLE; // disable SPI interrupt SPCR = SPI_SPE;//SPI interrupt disable, SPI enable, slave mode SPICnt=0; P0_6=0;
4. 將RX Data=Tmpbuf裡的資料,依序填入SPDR,將SPI Data依序傳輸到另一顆MCU上
SPDR =Tmpbuf[SPICnt]; while(SPICnt!=64) { while ( P0_3 == LOW ) _nop_(); // wait SSO turn high SPDR =Tmpbuf[SPICnt++]; while ( ( SPSR & SPI_SPIF ) == 0 ); }