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