(0x34)狀態(tài)寄存器里面的值。
狀態(tài)字節(jié):
狀態(tài)字節(jié)包含一些關(guān)鍵的狀態(tài)信號,當(dāng)通過SPI接口發(fā)送報頭字節(jié)、數(shù)據(jù)字節(jié)或指令選通脈沖時,CC1100e的狀態(tài)字節(jié)通過MISO引腳發(fā)送。狀態(tài)字節(jié)的最后四位(3:0)FIFO_BYTES_AVAILABLE,進行讀取操作時,報頭字節(jié)的BIT7設(shè)置為1,F(xiàn)IFO_BYTES_AVAILABLE域包含了可從FIFO讀取的字節(jié)數(shù)。進行寫操作時,F(xiàn)IFO_BYTES_AVAILABLE字段包含了可寫至TX
FIFO的字節(jié)數(shù)。當(dāng)FIFO_BYTES_AVAILABLE=15時,表示15或更多的字節(jié)為可用字節(jié)。
FIFO存。
關(guān)于FIFO的訪問,其分為TX FIFO和RX
FIFO。64字節(jié)的TX FIFO和64字節(jié)的RX FIFO均通過0x3F地址進行存取。對其既可以通過單字節(jié)訪問也可以通過突發(fā)訪問。當(dāng)讀寫控制位BIT7為1時訪問的是RX
FIFO,BIT7是0時訪問的TX FIFO。這樣得到下列報頭字節(jié):0x3F為單字節(jié)訪問TX FIFO,0xBF為單字節(jié)訪問RX
FIFO,0x7F為突發(fā)訪問TX FIFO,0xFF為突發(fā)訪問 RX FIFO。
當(dāng)對TX
FIFO進行寫入操作時,每個數(shù)據(jù)字節(jié)的狀態(tài)字節(jié)均在MISO上輸出。該狀態(tài)字節(jié)用于檢測TX
FIFO寫數(shù)據(jù)時的下溢。狀態(tài)字節(jié)包含將其寫入TX FIFO過程以前自由的字節(jié)數(shù),當(dāng)可寫入TX
FIFO的最后一個字節(jié)在MOSI上發(fā)送時,與此同時在MISO引腳上接收到的狀態(tài)字節(jié)將表明TXFIFO中存在一個自由字節(jié)。TX
FIFO可能會由于寫入一條SFTX指令選通脈沖而被刷新,同樣,一條SFRX指令選通脈沖也會刷新RX
FIFO。
PTABLE存。
0x3E地址用于存取PATABLE,用來設(shè)置發(fā)射功率的。接收到此地址之后,SPI要求有高達8個數(shù)據(jù)字節(jié)。PATABLE是一個8字節(jié)表,其定義了PA控制設(shè)置。讀寫還是通過讀寫控制位BIT7控制,突發(fā)訪問還是單字節(jié)訪問還是通過突發(fā)位BIT6來控制。內(nèi)部有個計數(shù)器用來控制對該表的存取,每讀取或?qū)懭朐摫碇幸粋字節(jié),計數(shù)器就自動加1,當(dāng)計數(shù)到7時會自動從0開始計數(shù).當(dāng)設(shè)置Csn為高電平時,內(nèi)部計數(shù)器會變?yōu)?.如果向PTABLE寫入一個字節(jié),并且要讀取該值,那么在讀取存取以前必須將CSN設(shè)置為高電平,以將計數(shù)器重新設(shè)置為0.
數(shù)據(jù)包格式:
由cc1100的datasheet可以知道,其數(shù)據(jù)包是由前導(dǎo)碼、同步字節(jié)、可選的數(shù)據(jù)包長度、可選的目標(biāo)地址、數(shù)據(jù)區(qū)以及兩個字節(jié)的CRC校驗碼。前導(dǎo)碼的最小長度可以通過MDMCFG1.NUM_PREAMBLE的值進行編程。當(dāng)開啟TX模式時,調(diào)制器將開始發(fā)送前導(dǎo)碼。當(dāng)編程的前導(dǎo)字節(jié)數(shù)被發(fā)送完畢后,調(diào)制器將開始發(fā)送同步字節(jié),然后發(fā)送來自TX
FIFO的數(shù)據(jù)。若TXFIFO為空,調(diào)制器將繼續(xù)發(fā)送前導(dǎo)碼,知道第一個字節(jié)被寫入TX
FIFO為止,調(diào)制器隨后發(fā)送同步字,然后發(fā)送數(shù)據(jù)字節(jié)。
同步字是設(shè)置于SYNC1和SYNC0兩個寄存器中的2字節(jié)值。在可變數(shù)據(jù)包長度模式下,通過同步字后面的第一個字節(jié)來配置數(shù)據(jù)包長度。數(shù)據(jù)包長度被定義為有效負載數(shù)據(jù),但不包括長度字節(jié)和可選CRC。PKTLEN寄存器用于設(shè)置RX模式中允許的最大數(shù)據(jù)包長度。任何長度字節(jié)值大于PKTLEN的接收數(shù)據(jù)包將被丟棄。
接收模式下的數(shù)據(jù)包濾波:
CC1100e支持三種不同類型的濾波:地址濾波、最大長度濾波和CRC濾波。
地址濾波:設(shè)置PKTCTRL1.ADR_CHK為0以外的任何值均可開啟數(shù)據(jù)包的地址濾波器。radio將目標(biāo)地址字節(jié)與ADDR寄存器中地址,以及PKTCTRL1.ADR_CHK=10時的0x00廣播地址或者PKTCTRL1.ADR_CHK=11時的0x00和0xff廣播地址進行比較。如果接收的地址匹配一個有效地址,則接收該數(shù)據(jù)包,并將其寫入RX
FIFO,如果地址匹配失敗,則丟棄該數(shù)據(jù)包,并重新啟動接收模式。
最大長度濾波:在可變數(shù)據(jù)包長度模式下,PKTLEN.PACKET_LENGTH寄存器的值用來設(shè)置最大允許數(shù)據(jù)包長度,當(dāng)接收字節(jié)值比這個值大,則數(shù)據(jù)包被丟棄,并且重新啟動接收模式。
CRC濾波:(不懂,不寫)
發(fā)送模式下的數(shù)據(jù)包處理:
必須要將即將發(fā)送的有效數(shù)據(jù)長度寫入TX
FIFO中,開啟可變數(shù)據(jù)包長度以后,長度字節(jié)必須最先被寫入。長度字節(jié)具有一個與數(shù)據(jù)包有效負載相當(dāng)?shù)闹。如果接收機端開啟了地址識別,則寫入TX
FIFO的第二個字節(jié)必須為地址字節(jié)。如果開啟了固定數(shù)據(jù)包長度,則寫入TX FIFO的第一個字節(jié)應(yīng)為地址字節(jié)。
調(diào)制器會首先發(fā)送編程的前導(dǎo)字節(jié)數(shù),如果TX FIFO中的數(shù)據(jù)可用,則調(diào)制器會發(fā)送兩個字節(jié)同步字,之后是TX FIFO
中的有效負載。如果開啟了CRC,則在所有取自TXFIFO的數(shù)據(jù)上計算驗和,并在有效負載之后以兩個額外字節(jié)發(fā)送該結(jié)果。如果TXFIFO在發(fā)送完全部數(shù)據(jù)包以前變?yōu)榭,那么該無線電設(shè)備將進入TXFIFO_UNDERFLOW狀態(tài)。退出該狀態(tài)的唯一方法是發(fā)出一個SFTX選通脈沖。
接收模式下的數(shù)據(jù)包處理:
在接收模式下,解調(diào)器和數(shù)據(jù)包處理器將會搜索一個有效的前導(dǎo)和同步字。如果找到,解調(diào)器就獲得了位和字節(jié)同步機制,并將接收第一個有效負載字節(jié)。當(dāng)可變數(shù)據(jù)包長度模式開啟時,則第一個字節(jié)為長度字節(jié)。數(shù)據(jù)包處理器把這個值作為數(shù)據(jù)包長度存儲,并接收該長度字節(jié)線束數(shù)目的字節(jié)。
固件中的數(shù)據(jù)包處理:
在固件中執(zhí)行數(shù)據(jù)包導(dǎo)向無線協(xié)議時,MSP430需要知道一個數(shù)據(jù)包何時被接收到、何時被發(fā)送出去。當(dāng)數(shù)據(jù)包長度大于64字節(jié)時,需要在RX模式下讀取RX
FIFO,需要在TX模式下重填TXFIFO。
中斷驅(qū)動法:當(dāng)通過設(shè)置IOCFGx.GDOx_CFG=0x06接收到或發(fā)送出去一個同步字或接收到發(fā)送出去一個完整的數(shù)據(jù)包時,在RX和TX模式下均可使用GDO引腳來實現(xiàn)中斷。
SPI輪詢:可以某個給定速率對PKTSTATUS寄存器輪詢,以獲取GDO2和GDO0當(dāng)前值的相關(guān)信息?梢阅硞給定速率對RXBYTES和TXBYTES寄存器輪詢,以獲取RXFIFO和TXFIFO中所含字節(jié)數(shù)的相關(guān)信息。另外,在SPI總線上每發(fā)送一個報頭字節(jié)、數(shù)據(jù)字節(jié)或指令選通脈沖時,可從MISO線路上返回的芯片狀態(tài)字節(jié)讀取到RXFIFO和TXFIFO中所含的字節(jié)數(shù)。
具體編程時必須注意一下事項:
1、拉低CSN引腳電平時,在開始傳輸報頭字節(jié)以前,msp430必須等待SISO引腳變?yōu)榈碗娖綖橹,表明?nèi)部穩(wěn)定。
2、每當(dāng)一個字節(jié)通過SI引腳寫入到寄存器時,狀態(tài)字節(jié)將被送到MISO引腳
3、狀態(tài)字節(jié)的最后4位用來表示FIFO的可用字節(jié),其最大值是15,此時表示15或更多的字節(jié)是可以使用的。
4、只有radio處于XOSC空閑,并且數(shù)字中心的能量開啟,其他模塊處于功率降低狀態(tài),這時候頻率和信道配置才能被更新。(不是很理解)
5、寄存器的突發(fā)訪問時,內(nèi)部計數(shù)器會自動設(shè)置起始地址,每增加一個字節(jié),地址會自動加1,無論讀寫操作,必須通過拉高Csn終止操作。
6、關(guān)于命令濾波,其實是單字節(jié)指令,通過指令對寄存器的選址,內(nèi)部功能做出相應(yīng)的啟動或關(guān)閉。不像對其他寄存器一樣必須先寫地址后寫數(shù)據(jù)。
7、當(dāng)radio進入休眠狀態(tài)時,兩個FIFO都被刷新為空。
8、一般所有的濾波命令會立即執(zhí)行,只有休眠濾波命令SPWD不會立即執(zhí)行,它會延遲到Csn為高電平時執(zhí)行。
部分程序如下:
//SPI讀取和發(fā)送函數(shù)
unsigned int SpiTxRxByte(unsigned data)
{
unsigned char i,temp;
temp=0;
SCK_0;
for(i=0;i<8;i++)
{
if(data&0x80)
{
MOSI_1;
}
else
{
MOSI_0;
}
data<<=1;
SCK_1;
temp<<=1;
if(MISO)temp++;
SCK_0;
}
teturn temp;
}
//重啟芯片函數(shù)
void RESET_CC1100(void)
{
CSN_0;
while(MISO);
SpiTxRxByte(SRES);
while(MISO);
CSN_1;
}
//上電重啟芯片函數(shù)
void POWER_UP_RESET_CC1100(void)
{
CSN_1;
delayus(1);
CSN_0;
delayus(1);
CSN_1;
delayus(41);
ESET_CC1100();
}
//單字節(jié)寫寄存器函數(shù)
void SpiWriteReg(unsigned char addr,unchar int value)
{
CSN_0;
while(MISO);
SpiTxRxByte(addr); //寫入地址
SpiTxRxByte(value);//寫入配置
CSN_1;
}
//突發(fā)訪問方式寫寄存器函數(shù)
void SpiWriteBurstReg(unsigned int addr,unsigned int
*buffer,unsigned int count)
{
unsigned int i,temp;
temp=addr|0x40;//將突發(fā)訪問位置1
CSN_0;
while(MISO);
SpiTxRxByte(temp);
for(i=0;i<count;i++)
{
SpiTxRxByte(buffer[i]);
}
CSN_1;
}
//寫命令濾波函數(shù)
void SpiStrobe(unsigned int strobe)
{
CSN_0;
while(MISO);
SpiTxRxByte(strobe);
CSN_1;
}
//單字節(jié)讀寄存器函數(shù)
unsigned int SpiReadReg(unsigned int addr)
{
unsigned int temp,value;
temp=addr|0x80;
CSN_0;
while(MISO);
SpiTxRxByte(temp);
value=SpiTxRxByte(0);
CSN_1;
return value;
}
//突發(fā)訪問讀寄存器函數(shù)
void SpiReadBurstReg(unsigned int addr,unsigned int
*buffer,unsigned int count)
{
unsigned int i,temp;
temp=addr|0xc0;
CSN_0;
while(MISO);
SpiTxRxByte(temp);
for(i=0;i<count;i++)
{
buffer[i]=SpiTxRxByte(0);
}
CSN_1;
}
//讀寄存器狀態(tài)函數(shù)
unsigned int SpiReadStatus(unsigned int addr)
{
unsigned int value,temp;
temp=addr|0xc0;
CSN_0;
while(MISO);
SpiTxRxByte(temp);
value=SpiTxRxByte(0);
CSN_1;
return value;
}
//
//
//CC1100發(fā)送一組數(shù)據(jù)的函數(shù)
void RFSpiSendPacket(unsigned int *txbuffer,unsigned int
size)
{
SpiWriteReg(TXFIFO,size);//是否和下句沖突?
SpiWriteBurstReg(TXFIFO,txbuffer,size);//寫入要發(fā)送的數(shù)據(jù)
SpiStrobe(STX);//進入發(fā)送模式發(fā)送數(shù)據(jù)
//wait for GDO0 to be
set--->sync transmitted
while(!(GDO0));
//wait for GDO0 to be cleared--->end of
packet
while(GDO0);
SpiStrobe(SFTX);//沖洗 TXFIFO
}
//
//
//
//CC1100接收一組數(shù)據(jù)
unsigned int RFReceivePacket(unsigned int *rxbuffer,unsigned
int *length)
{
unsigned int status[2];
unsigned int packetlength;
unsigned int i=(*length)*4;
SpiStrobe(SRX);//進入接收狀態(tài)
delayus(2);
while(GDO0)
{
delayus(2);
--i;
if(i<1)
return 0;
}
if((SpiReadStatus(RXBYTES)&0x7F))//如果接的字節(jié)數(shù)不為0
{
packetlength=SpiReadReg(RXFIFO);//讀出第一個字節(jié),此字節(jié)為該幀數(shù)據(jù)長度
if(packetlength<=*length)
{
SpiReadBurstReg(RXFIFO,rxbuffer,packetlength);//讀出所有接收到的數(shù)據(jù)
*length=packetlength;
SpiReadBurstReg(RXFIFO,status,2);//讀出CRC校驗位
SpiStrobe(SFRX);//清洗接收緩沖區(qū)
return(status[1]&0x80);//如果校驗成功 返回接收成功
}
else
{
*length=packetlength;
SpiStrobe(SFRX);//清洗接收緩沖區(qū)
return
0;
}
}
else
return 0;
}