使用SPI輸入Data給A8137 Tx發射資料,且喚醒對端A8137 低功率Rx(Wake Up On Rx)收到Data後,再經由SPI輸出Data

SamYang2023-12-2151核137
  • 系統流程圖:

300b479a98a2f4cd4d2e7181.png

  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 );
			}


发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。