【單片機】SI4432 Based Networking 1

SI4432射頻芯片的內部狀態機以及各個狀態下的(SI4432最重要的一張圖):

各個狀態下系統細節:

SI4432的射頻參數設置比較複雜了,需要比較專業的知識才能很好的設置各種參數寄存器,好在Silicon Labs提供了一個計算器,我們只需要提供想要的參數就能給我們計算好射頻參數對應的寄存器的值了,這個計算器是一個Excel文件(這操作不錯):

打開之後灰色的欄都是可以自己選擇修改的,看到這裏我將調頻方式設置爲FSK( 移頻鍵控),TX/RX Carrier Frequency設置爲868Mhz,數據波特率40Kbps,頻偏(FSK調製模式下的一個重要參數)設置爲30Khz,下面就是相關寄存器的值了:

再來看SI4432的幀結構:

1、Preamble爲前導碼,射頻芯片通過檢測前導碼來識別是不是有一幀數據到來,不要太短。

2、Sync Word爲同步字,收到前導碼之後芯片會檢測同步字,沒有找到同步字的話則該幀接收失敗。該字段可以作爲網絡地址。

3、TX Header爲頭碼,發射數據的頭碼和接收端的接收驗證頭碼相同纔會產生一幀數據。該字段可以作爲節點設備地址。

4、Packet Length爲有效數據長度。

5、Data爲有效數據。

6、CRC爲校驗字段。

上訴的所有字段(除了CRC字段)的長度根據配置不同,長度也不同。在 Packet Handler 模式沒開啓和開啓的情況下,幀格式如下:

不使用 Packet Handler 模式的話可以自己在軟件上進行地址過濾等操作,但是這些完全可以交給SI4432來做,我使用Packet Handler模式,同時使用非固定幀長度模式單幀模式 (rx_multi_pk_en = 0),所以發送數據的有效長度範圍爲 1 ~ 64 Bytes,發送數據的時候(可以先清空Tx FIFO),寫入實際需要發送的數據長度 n 到“Register 3Eh. Packet Length”,然後向Tx FIFO中寫入 n 字節的數據即可。接收到數據幀長度存放在 “Register 4Bh. Received Packet Length” 中。

設計了一個基於SI4432的USB Dongle:

焊接了兩個設備,相距20CM,正常狀態下,兩個設備都是處於接收狀態,不向外發射信號:

軟件上(433Mhz Carrier & 9.6Kbps & 30KHz Deviation)以100Hz的速度讀取RSSI寄存器的值並顯示波形:

這時候無線芯片收到的RSSI值在60到70左右,比較平穩,這可能是環境中存在的已經來自大自然(宇宙)的雜波。SI4432的數據手冊對RSSI值的解釋:

The RSSI (Received Signal Strength Indicator) signal is an estimate of the signal strength in the channel to which

the receiver is tuned. The RSSI value can be read from an 8-bit register with 0.5 dB resolution per bit. Figure 31

demonstrates the relationship between input power level and RSSI value. The RSSI may be read at anytime, but

an incorrect error may rarely occur. The RSSI value may be incorrect if read during the update period. The update

period is approximately 10 ns every 4 Tb. For 10 kbps, this would result in a 1 in 40,000 probability that the RSSI

may be read incorrectly. This probability is extremely low, but to avoid this, one of the following options is

recommended: majority polling, reading the RSSI value within 1 Tb of the RSSI interrupt, or using the RSSI

threshold described in the next paragraph for Clear Channel Assessment.

再做一些小實驗。用手捂住第一個設備然後放開,重複數次:

讀取到的RSSI波形:

很明顯用手捂住之後RSSI波形變化很大,捂住的時候RSSI值在20左右,有明顯的降低,用一張紙遮蓋起來沒有影響,但是手算是導體,屏蔽效果比較好,如果使用封閉金屬容器封蓋的話,屏蔽效果會更好。但是手蓋住不能完全蓋住模塊,因爲模塊下面沒有被蓋住,我在高樓層,樓下的干擾也會傳上來。手持模塊在各個角度進行旋轉移動,RSSI的值也會有明顯的變化。

拿一個手機在模塊旁邊,RSSI波形幾乎沒有變化,撥打一個騷擾電話,RSSI波形如下:

手機信號的頻率一般如下:

1、中國移動:885-909(上行)、930-954Mhz(下行);

2、中國聯通:909-915(上行)、954-960Mhz(下行);

3、中國電信:825-835(上行)、870-880Mhz(下行)。

而模塊的頻率設置爲433Mhz,所以打電話的時候干擾不大,如果模塊是868Mhz或者915Mhz的話,干擾可能會很大。

然後另一個模塊發送數據,發送功率爲最高功率20dB,查看RSSI波形:

波形中每產生個波峯都是因爲另一個模塊發送一次數據(手動觸發發送),RSSI波峯值可以達到222左右,因爲SI4432中的RSSI寄存器是8位的,最大值是255,所以這裏的RSSI值已經很高了,可能是兩個模塊離得近的原因吧。另外可以會讀到兩個RSSI峯值,原因是射頻發射總時間(測試程序中無線波特率9600bps,發送了8個字節的數據、16個Nibble佔8個字節、4個字節的Sync、4個字節的頭部,一共24個字節,以9600的波特率算需要大約25ms)大於RSSI的讀取打印週期10ms(100Hz),所以會讀到兩次RSSI峯值。

那麼爲什麼我玩RSSI玩的這麼開心呢?我想要實現類似於CSMA/CA的功能,簡單來說就是如果無線信道被佔用(有設備正在佔用信道發送數據),那麼就等待一段隨機的時間再發送數據。

SI4432芯片內部有一個寄存器:"Register 27h. RSSI Threshold for Clear Channel Indicator ,Interrupt is set if the RSSI value is above this threshold."。這個寄存器是用於存儲一個閾值,當RSSI的值高於這個閾值的時候,“If the signal strength is above the programmed threshold then a 1 will be shown in the RSSI status bit in "Register 02h. Device Status", "Register 04h. Interrupt/Status 2", or configurable GPIO (GPIOx[3:0] = 11100).”

配置RSSI Threshold的值爲100,GPIO2爲“11100: Clear Channel Assessment (output)”,軟件上讀取GPIO2並打印(放大100倍),同時另一個模塊手動發送數據:

可以看到在發送數據的時候,接收模塊的GPIO2引腳會變成1,表示信道忙。當然了,如果射頻芯片不提供硬件“RSSI Threshold”功能,也可以通過SPI讀取RSSI值,然後在單片機軟件中自己設置一個閾值用於Clear Channel Assessment。接下來在發送數據的時候,先進行Clear Channel Assessment,也就是如果當前GPIO2引腳爲1,則表示信道忙,執行退避算法。

 

 

附:SI4432操作示例代碼(基於STM32F030)

#include "SI4432.h"

unsigned char ItStatus1, ItStatus2;
enum SI4432_FLAGS SI4432_Flags = SI4432_FLAGS_NONE;
const u16 Network_Address = 0x1234;
const u16 Device_Address = 0x0001;

//STM32F030的SPI和STM32F103的SPI不同:
//https://www.amobbs.com/thread-5614282-1-1.html?_dsign=9ffc5097
u8 SPI_RW(u8 data)
{
	u16 retry=0;
	while((SPI1->SR&SPI_SR_TXE)==0)		//等待發送區空			  
	{
//		retry++;
//		if(retry>=200)return 0;			//超時退出
	}
	*(uint8_t*)&(SPI1->DR)=data;		//發送一個byte 
	retry = 0;
	while ((SPI1->SR&SPI_SR_BSY)) 		//等待接收完一個byte  
	{
//		retry++;
//		if(retry>=200)return 0;			//超時退出
	}
	return *(uint8_t*)&(SPI1->DR);		//返回收到的數據				    
}

u8 SI4432_WR(u8 addr,u8 TRdata)
{
	u8 status;
	CLR_nSEL;		//打開SPI片選
	SPI_RW(addr);
	status = SPI_RW(TRdata);

//    while((SPI1->SR&0x0002)==0);
//    SPI1->DR = addr;
//    while((SPI1->SR&0x0001)==0);
//    status = SPI1->DR;

//    while((SPI1->SR&0x0002)==0);
//    SPI1->DR = TRdata;
//    while((SPI1->SR&0x0001)==0);
//    status = SPI1->DR;
	
	SET_nSEL;		//關閉SPI片選
	return status;
}

void SI4432_WriteFIFO(u8 *buff,int plen)
{
	CLR_nSEL;		//打開SPI片選
	SPI_RW(0x7f|0x80);
	int i;
	for(i=0;i<plen;i++)
		SPI_RW(buff[i]);
	SET_nSEL;		//關閉SPI片選
}

void SI4432_READ_BUF(u8 addr,u8 lenth,u8* data)
{
	u8 i;
	CLR_nSEL;		//打開SPI片選
	SPI_RW(addr);
	for(i=0;i<lenth;i++)
	{
		data[i] = SPI_RW(0x00);
	}
	SET_nSEL;		//關閉SPI片選
}

void SI4432_CLR_INT(void)
{
	ItStatus1 = SI4432_WR(0x03,0x00);		//清掉現有的中斷標誌
	ItStatus2 = SI4432_WR(0x04,0x00);		//清掉現有的中斷標誌
}

void SI4432_EMPTY_BUF(void)
{
	SI4432_WR(0x08|0x80, 0x03);  									//清發射,接收緩衝區
	SI4432_WR(0x08|0x80, 0x00);
}

int SI4432_FETCH_DATA(u8 *rx_buf)
{
	SI4432_CLR_INT();
	int plen = SI4432_WR(0x4B,0x00);	//Length Byte of the Received Packet during fixpklen = 0.
	SI4432_READ_BUF(0x7f,plen,rx_buf);
	SI4432_WR(0x07|0x80,SI4432_PWRSTATE_RX );  		// RF 模塊進入接收模式
	SI4432_EMPTY_BUF();
	return plen;
}

void SI4432_SEND_DATA(u8 *buff,int plen)
{
	u8 i;
	SI4432_EMPTY_BUF();
	SI4432_WR(0x3e | 0x80, plen);		// 發送幀長度
	//先發送低字節
	for(i=0;i<plen;i++)
		SI4432_WR(0x7f|0x80,buff[i]);
}

void SI4432_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	EXTI_InitTypeDef EXTI_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	SPI_InitTypeDef SPI_InitStruct;

/*======================================引腳及時鐘初始化=============================================*/
{
	/* 使能GPIOA時鐘 */
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

	/* 配置MODULE相應引腳*/
	GPIO_InitStructure.GPIO_Pin = SDN_PIN | nSEL_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_SetBits(GPIOA, SDN_PIN);
	GPIO_SetBits(GPIOA, nSEL_PIN);
//	while(1)
//	{
//		GPIO_SetBits(GPIOA, SDN_PIN);
//		GPIO_SetBits(GPIOA, nSEL_PIN);
//		delay_ms(500);
//		GPIO_ResetBits(GPIOA, SDN_PIN);
//		GPIO_ResetBits(GPIOA, nSEL_PIN);
//		delay_ms(500);
//	}
//	while(1)
//	{
//		CLR_nSEL;
//		delay_ms(1000);
//		SET_nSEL;
//		delay_ms(1000);
//	}

	GPIO_InitStructure.GPIO_Pin = nIRQ_PIN | GPIO2_PIN;// | GPIO1_PIN | GPIO2_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_0);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_0);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_0);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
	SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
	SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
	SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
	SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
	SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStruct.SPI_CRCPolynomial = 7;    //CRC 校驗
	SPI_Init(SPI1,&SPI_InitStruct);
//	SPI_NSSInternalSoftwareConfig(SPI1,SPI_NSSInternalSoft_Set);
//	SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);    //重要,把應答數據位設置爲 8 位
	SPI_Cmd(SPI1,ENABLE);
//	SPI_RW(0xff);	//啓動傳輸		 
	                                    
//	SPI_Init(SPI1);
//	SPI_SetSpeed(SPIl;    I1,SPI_SPEED_16);
/*===================================================================================================*/

/*======================================接收中斷初始化=============================================*/
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

	//中斷初始化
	NVIC_InitStruct.NVIC_IRQChannel = EXTI0_1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelPriority = 0x00;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStruct);

	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource1);
	EXTI_InitStruct.EXTI_Line = EXTI_Line1;
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStruct);
	DISABLE_INT(1); // 關閉nIRQ引腳中斷
/*=================================================================================================*/
}

/*======================================芯片初始化=============================================*/
	SET_SDN;
 	delay_ms(10);		// RF 模塊上電覆位
	CLR_SDN;
 	delay_ms(200);		// 延時200ms RF 模塊進入工作狀態

	SI4432_CLR_INT();				// 清RF模塊中斷
	SI4432_WR(0x05 | 0x80, 0x00);	// 關閉不需要的中斷
	SI4432_WR(0x06 | 0x80, 0x00);	// 關閉不需要的中斷
		
	SI4432_WR(0x07 | 0x80, SI4432_PWRSTATE_READY);   // 進入 Ready 模式

	SI4432_WR(0x09 | 0x80, 0x1f);	// 負載電容= 12P

	SI4432_WR(0x0a | 0x80, 0x05);	// 關閉低頻輸出
	SI4432_WR(0x0b | 0x80, 0xea);	// GPIO 0 當做普通輸出口
	SI4432_WR(0x0c | 0x80, 0xea);	// GPIO 1 當做普通輸出口	
	SI4432_WR(0x0d | 0x80, 0x1C);	// GPIO 2 Clear Channel Assessment (output)
	
	SI4432_WR(0x27 | 0x80, 100);	//RSSI Threshold for Clear Channel Indicator
	

{	//使用SI4432計算器《SI443x Register Settings_RevB1-v7》計算
	
	// RX/TX Carrier Frequency Settings:868Mhz
	SI4432_WR(0x75 | 0x80, 0x73);
	SI4432_WR(0x76 | 0x80, 0x64);
	SI4432_WR(0x77 | 0x80, 0x00);

	// TX Data Rate Settings:40Kbps
	SI4432_WR(0x6e | 0x80, 0x0A);	// txdr[15:0] = 0x0A3D;
	SI4432_WR(0x6f | 0x80, 0x3D);	// DR_TX (bps) = 40Kbps;
	SI4432_WR(0x70 | 0x80, 0x0c);	// 清除txdtrtscale位
	SI4432_WR(0x58 | 0x80, 0x80);

	// TX Frequency Deviation Settings:30Khz
	SI4432_WR(0x72 | 0x80, 0x30);  	// 頻偏爲 30KHz	
	SI4432_WR(0x71 | 0x80, 0x22); 	// 發射不需要 CLK,FiFo , FSK模式
	
	// GFSK/FSK RX Modem Settings
	SI4432_WR(0x1c | 0x80, 0x05);
	SI4432_WR(0x20 | 0x80, 0x64);
	SI4432_WR(0x21 | 0x80, 0x01); 
	SI4432_WR(0x22 | 0x80, 0x47); 
	SI4432_WR(0x23 | 0x80, 0xAE); 
	SI4432_WR(0x24 | 0x80, 0x03); 
	SI4432_WR(0x25 | 0x80, 0x6C); 
	SI4432_WR(0x1d | 0x80, 0x3C);
	SI4432_WR(0x1e | 0x80, 0x02);
	SI4432_WR(0x2a | 0x80, 0xFF);
	SI4432_WR(0x1f | 0x80, 0x03);
	SI4432_WR(0x69 | 0x80, 0x60);
}

	SI4432_WR(0x30 | 0x80, 0x8c);	// 使能PH+ FIFO模式,高位在前面,使能CRC校驗	 				
	SI4432_WR(0x32 | 0x80, 0xff);	// byte 0,1,2,3 作爲頭碼
//	SI4432_WR(0x33 | 0x80, 0x42);	// 4 bytes Header, 非固定幀長度模式, 2 bytes Sync Word
	SI4432_WR(0x33 | 0x80, 0x22);	// 2 bytes Header, 非固定幀長度模式, 2 bytes Sync Word
	SI4432_WR(0x34 | 0x80, 16);		// 發射16個Nibble(4 bits)的Preamble
	SI4432_WR(0x35 | 0x80, 0x20);	// 需要檢測4個nibble的Preamble
	
	/*****************Sync Word settings*****************/
	SI4432_WR(0x36 | 0x80, (u8)(Network_Address >> 8));		// Sync Word 3 
	SI4432_WR(0x37 | 0x80, (u8)Network_Address);			// Sync Word 2 
	SI4432_WR(0x38 | 0x80, 0x00);	// Sync Word 1 (unused)
	SI4432_WR(0x39 | 0x80, 0x00);	// Sync Word 0 (unused)
	
	/*****************TX Header settings*****************/
	SI4432_WR(0x3a | 0x80, 0x00);	// Transmit Header 3 
	SI4432_WR(0x3b | 0x80, 0x01);	// Transmit Header 2 
	SI4432_WR(0x3c | 0x80, 0);   	// Transmit Header 1 
	SI4432_WR(0x3d | 0x80, 0);   	// Transmit Header 0 
	
	SI4432_WR(0x3e | 0x80, 1);		// 發送幀長度
	
	/*****************RX Header settings*****************/
	SI4432_WR(0x3f | 0x80, (u8)(Device_Address >> 8));   	// Check Header 3 'T'
	SI4432_WR(0x40 | 0x80, (u8)Device_Address);   	// Check Header 2 'Q'
	SI4432_WR(0x41 | 0x80, 0);   	// Check Header 1 
	SI4432_WR(0x42 | 0x80, 0);   	// Check Header 0 
	
	SI4432_WR(0x43 | 0x80, 0xff);  	// 頭碼1,2,3,4 的所有位都需要校驗
	SI4432_WR(0x44 | 0x80, 0xff);  	// 
	SI4432_WR(0x45 | 0x80, 0xff);  	// 
	SI4432_WR(0x46 | 0x80, 0xff);  	// 
	
	SI4432_WR(0x6d | 0x80, 0x07);  	// 設置爲最大功率發射20dB
                     
	SI4432_WR(0x79 | 0x80, 0x0);  	// 不需要跳頻
	SI4432_WR(0x7a | 0x80, 0x0);  	// 不需要跳頻
                     
	SI4432_WR(0x73 | 0x80, 0x0);  	// 沒有頻率偏差
	SI4432_WR(0x74 | 0x80, 0x0);  	// 沒有頻率偏差
                     
/*====================================芯 片 初 始 化===============================================*/
	
	int i;
	printf("\r\n\r\n\r\n\r\n\r\n");
	for(i=0;i<=0x7F;i++)
	{
		u8 a = SI4432_WR(i, 0x00);
		printf("%.2X:%.2X\r\n",i,a);
	}
	
//	while(1)
//	{
//		printf("a");
//		TX1_RX0;
//		delay_ms(500);
//		printf("b");
//		TX0_RX1;
//		delay_ms(500);
//		printf("c");
//		TX0_RX0;
//		delay_ms(500);
//	}

// 	SI4432_EMPTY_BUF();
	TX0_RX0;	// 天線開關不在發射,接收狀態

	//默認進入接收狀態RXD
//	SI4432_RxState();
	
//	SI4432_SwitchState(SI4432_STATE_IDLE_STANDBY);
	SI4432_IdleState_Standby();
}

u8 SI4432_RSSI(void)
{
	__disable_irq();	//關閉全局中斷
	u8 tmp = SI4432_WR(0x26, 0x00);
	__enable_irq();		//打開全局中斷
	return tmp;
}

void SI4432_IdleState_Ready(void)
{
/*	READY Mode is designed to give a fast transition time to TX mode with reasonable current consumption. In this
	mode the Crystal oscillator remains enabled reducing the time required to switch to the TX or RX mode by
	eliminating the crystal start-up time. Ready mode is entered by setting xton = 1 in "Register 07h. Operating Mode
	and Function Control 1". To achieve the lowest current consumption state the crystal oscillator buffer should be
	disabled. This is done by setting "Register 62h. Crystal Oscillator/Power-on-Reset Control" to a value of 02h. To
	exit ready mode, bufovr (bit 1) of this register must be set back to 0.*/
	SI4432_WR(0x07|0x80, SI4432_PWRSTATE_READY);	// 進入 Ready 模式
}

void SI4432_IdleState_Standby(void)
{
/*	STANDBY mode has the lowest current consumption possible with only the LPLDO enabled to maintain the
	register values. In this mode the registers can be accessed in both read and write mode. The standby mode can be
	entered by writing 0h to "Register 07h. Operating Mode and Function Control 1". If an interrupt has occurred (i.e.,
	the nIRQ pin = 0) the interrupt registers must be read to achieve the minimum current consumption. Additionally,
	the ADC should not be selected as an input to the GPIO in this mode as it will cause excess current consumption. */
	SI4432_CLR_INT();	// 清中斷
	SI4432_WR(0x07|0x80, SI4432_PWRSTATE_STANDBY);	// 進入 Standby 模式
}

void SI4432_RxState(void)
{
	SI4432_IdleState_Ready();
	TX0_RX1;
	ENABLE_INT(1);	// 打開nIRQ引腳中斷
//	delay_ms(5);
	//先清除中斷再設置中斷允許寄存器
	SI4432_CLR_INT();	// 清中斷後開始發射
	SI4432_WR(0x05|0x80, SI4432_VALID_PACKET_INTERRUPT);  // RF模塊收到整包數據後,產生中斷		
	SI4432_WR(0x07|0x80, SI4432_PWRSTATE_RX );	// RF 模塊進入接收模式
}

void SI4432_TxState(u8 *buff,int plen)
{
	SI4432_IdleState_Ready();
	TX1_RX0;
	DISABLE_INT(1);	// 關閉nIRQ引腳中斷
//	delay_ms(5);

	SI4432_EMPTY_BUF();
	SI4432_WR(0x3e|0x80, plen);		//發送幀長度
	SI4432_WriteFIFO(buff,plen);	//寫入FIFO

	//先清除中斷再設置中斷允許寄存器
	SI4432_CLR_INT();	// 清中斷後開始發射
	SI4432_WR(0x05|0x80, SI4432_PACKET_SENT_INTERRUPT);	// 整包數據發射完後產生中斷
	SI4432_WR(0x07|0x80, SI4432_PWRSTATE_TX);	// 進入發射模式
	
	while(nIRQ);	// 等待中斷
	SI4432_CLR_INT();	// 清中斷
	ENABLE_INT(1);	// 打開nIRQ引腳中斷
// 	printf("ST1:%d ST2:%d \n",ItStatus1,ItStatus2);
// 	SI4432_RxState();	//rf 發射完成,進入接收模式
	SI4432_IdleState_Ready();
}

void EXTI0_1_IRQHandler(void)
{
	EXTI->PR |= 1<<1;
	SI4432_Flags |= SI4432_FLAGS_NEW_PACKAGE;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章