本文主要是關于cc1101的相關介紹,并著重對cc1101低功耗以及驅動收發程序進行了詳盡的闡述。
cc1101
CC1101是一款低于1GHz設計旨在用于極低功耗RF應用。其主要針對工業、科研和醫療(ISM)以及短距離無線通信設備(SRD)。CC1101可提供對數據包處理、數據緩沖、突發傳輸、接收信號強度指示(RSSI)、空閑信道評估(CCA)、鏈路質量指示以及無線喚醒(WOR)的廣泛硬件支持。CC1101在代碼、封裝和外引腳方面均與CC1100兼容,可用于全球最為常用的開放式低于1GHz頻率的RF設計。
● 超低功耗無線收發器
● 家庭和樓宇自動化
● 高級抄表架構(AMI)
● 無線報警安全系統
◆ 387.0MHz~464.0MHz工作頻段。
(433MHz,0.6kbps,1%誤碼率時為-116dBm)。
(接收模式,433MHz,1.2kbps時僅16.0mA)。
◆ 最高可設置為+10dBm的發射功率。
◆ 支持0.6kbps~500kbps的數據傳輸速率。
◆ 支持多種調制模式(OOK、ASK、GFSK、2-FSK、4-FSK和MSK)。
◆ 提供對同步字檢測、地址校驗、靈活的數據包長度以及自動CRC處理的支持。
◆ 支持RSSI(接收信號強度指示)和LQI(鏈路質量指示)。
◆ 通過4線SPI接口與MCU連接,同時提供2個可設定功能的通用數字輸出引腳。
◆ 獨立的64字節RXFIFO和TX FIFO。
◆ 工作電壓范圍:1.9V~3.6V,待機模式下電流僅為200nA。
◆ 工作溫度范圍:-40℃~+85℃
cc1101低功耗設計方案
電路設計上,只用到了一個LED、串口1、一個模擬SPI、一個中斷線、一個讀卡芯片RESET線,硬件上就只剩下這么點東西了,這個時候我采用的是待機模式,使用的是讀卡芯片的中斷接PA0喚醒STM32,在此之前要先使得讀卡芯片進入低功耗、然后STM32進入低功耗,這一步完成了,貌似沒什么問題,功耗確實從幾十mA驟降到3mA左右,開始還挺滿意的,但是測試廠商提供的樣板,功耗卻只有幾十uA,有點郁悶了。為什么會這樣?反復查看硬件、程序,都找不出原因,而且這個時候的工作效果很爛,根本就不能喚醒,所以我就懷疑是讀卡芯片一端低功耗有問題,因為我將PA0腳直接短接VCC,這樣就可以產生一個邊沿觸發STM32喚醒了,但是用讀卡芯片無法喚醒,所以我懷疑是讀卡芯片的RESET腳電平不對,經檢查,確實是因為RESET腳加了上拉電阻,讀卡芯片是高電平復位,在STM32進入待機后,管腳全都浮空了,導致RESET被拉高,一直在復位;我去掉上拉電阻,覺得很有希望解決問題了,但是測試結果是:有時候能喚醒,有時候不能,我仔細一想難道是因為STM32待機后管腳電平不確定,導致讀卡芯片RESET腳電平不定,而工作不正常,看樣子只有換用其他方案了。后面確實驗證了我的想法,使用STOP模式后,喚醒問題引刃而解。
就在關鍵時刻,芯片原廠火種送炭,送來急需的技術支持資料,一個包含低功耗源代碼,趕緊拿過來測試,先研讀下代碼,使用的是STOP模式,而不是待機模式,使用的是任意外部中斷喚醒,功耗低制40uA,這個時候就相當激動啊,趕快下載測試啊,結果功耗確實降了,但還是有1mA,更人家一比多了幾十倍啊。。。
我第一反應是硬件不對,經過測試修改,首先找到第一個原因,讀卡芯片RESET管腳上拉電阻又給焊上去了。。.,拆掉后功耗驟降到幾百uA,還是不行。。 測試過程中,為了去掉LDO的干擾,整板采用3.3V供電,但是后面經過測試,LDO的功耗其實也只有5uA不到,這LDO功耗值得贊一個;雖然結果還是沒達到預期,但是看到了希望,勝利就在眼前啊。
為此我反復看了技術支持提供的程序,發現他們的STM32的所有管腳都的設置都有所考究:(因為公司保密原則,代碼中刪除掉了關于該讀卡芯片的前綴信息等)
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* GPIOB Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* GPIOC Periph clock enable */
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//####################################################
//USART1 Port Set
//TXD
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//RXD
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//RST output pushpull mode
GPIO_InitStructure.GPIO_Pin = TRST;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(PORT1, &GPIO_InitStructure);
//IRQ input pull-up mode
GPIO_InitStructure.GPIO_Pin = TIRQ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(PORT1, &GPIO_InitStructure);
//MISO input pull-up mode
GPIO_InitStructure.GPIO_Pin = MISO;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(PORT2, &GPIO_InitStructure);
//NSS,SCK,MOSI output pushpull mode
GPIO_InitStructure.GPIO_Pin = (NSS|SCK|MOSI);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(PORT2, &GPIO_InitStructure);
//############################################################################
//TEST Port set
//TESTO input pushpull mode
GPIO_InitStructure.GPIO_Pin = TESTO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(TEST_PORT, &GPIO_InitStructure);
//############################################################################
//TEST Port set
//TESTI output pushpull mode
GPIO_InitStructure.GPIO_Pin = TESTI;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(TEST_PORT, &GPIO_InitStructure);
//############################################################################
//LED Port Set
//LED output pushpull mode
GPIO_InitStructure.GPIO_Pin = LED;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LED_PORT, &GPIO_InitStructure);
//############################################################
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_8|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_15);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOC, &GPIO_InitStructure);
首先,想MOSI、SCK、CS、LED、RST這些管腳應該設置為推挽輸出,TXD設置為復用輸出,而IRQ、RXD、MISO設置浮空輸入,什么都沒接的管腳全都設置為下拉輸入,而TESTI、TESO我一直不解是什么東東,開始就沒管,而開始的時候MISO我也沒怎么注意,設置成上拉輸入(而不是浮空輸入),反正大部分按照廠家提供的參考,我并沒有照搬,測試效果一樣,但功耗確是還有80-90uA,期間我找了好久沒找到原因,給技術支持一看,原來是因為MISO沒有設置成浮空輸入,我是設置成了上拉輸入,上拉電阻一直在消耗大約40uA的電流。。。 好吧,這是自己不夠細心導致的,以后做低功耗的項目管腳配置是個大問題,不能再這么馬虎了!!! 我將MISO設置成浮空輸入之后,最低功耗還是有40+,離10uA的最低功耗還有段距離,到底是為什么呢?最后我發現
,該讀卡芯片有個TESTIN/TESTOUT管腳,是用來測試用的,出廠后也就用不上了,我也一直以為這兩個腳確實沒什么用,就沒接;可是我發現廠家提供的樣板居然接了這兩個腳,但是廠商也沒說這兩個腳接或不接會影響功耗啊,抱著試一試的心態,我我把TESTIN/TESTOUT兩個管腳接到單片機上進行相應的配置,接下來是見證奇跡的時刻了,功耗居然真的、真的降到10uA了。。。。。。。。。。。 此處省略n個字
這時候真的很激動,真的很想罵人啊,坑爹的廠家,為什么不給提示說這兩個腳不接單片機會消耗電流呢?(也許是文檔里面提到了,但是幾百頁的文檔,還是全英文的,一堆堆的文字,我再看一遍,確實沒有提到這兩個管腳會有漏電流。)
項目就這樣完工了,中間最重要的是技術支持的強力支持,不然項目不能完工了,這個項目低功耗STM32方面難度不高,主要是讀卡芯片上面的低功耗調試起來問題很多,還是人家原廠的出馬才解決了問題,因為眾多原因,不能公布該芯片的資料,包括該芯片怎么進入低功耗也無法公開,所以抱歉~~。
關于STM32進入低功耗,我簡單的總結了一下:
1.管腳設置,這個很關鍵,還是跟你電路有關系,外加上拉、下拉電阻切記不能隨便加
2.STM32的systick clock、DMA、TIM什么的,能關就全都關掉,STM32低功耗很簡單,關鍵是外圍電路功耗是關鍵
3.選擇一個低功耗的LDO,這個項目用到的LDO功耗就很不錯,靜態功耗10uA都不到。
4.確定STM32設置沒問題,進入低功耗有好幾種情況可以選擇(睡眠、停機、待機),我還是推薦選擇STOP模式,這個我覺的比較好是因為可以任意外部中斷都可以喚醒,而且管腳可以保留之前的設置,進入停機模式的代碼使用庫函數自帶的,就一句:
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
意思是,在進入停機模式之前,也關掉電壓調節器,進一步降低功耗,使用WFI指令(任意中斷喚醒),但是經過測試,使用WFE(任事件喚醒)指令效果、功耗一模一樣。
最后一步是從STOP模式怎么恢復了,恢復其實也很簡單,外部中斷來了會進入中斷函數,然后STM32就被喚醒,喚醒還要做一些工作,需要開啟外部晶振(當然你也可以選擇使用內部自帶振蕩器)、開啟你需要的外設等等。
CC1101收發驅動程序
#include “system.h”
#include “delay.h”
#include “CC1101.h”
//CC1101命令掩碼
#define WRITE_BURST 0x40 //連續寫入
#define READ_SINGLE 0x80 //讀
#define WRITE_SINGLE 0x00 //寫
#define READ_BURST 0xC0
//連續讀
#define BURST_READ_FIFO 0xff //突發讀取RX FIFO
#define BYTE_READ_FIFO 0xBF //單字節讀取 RX FIFO
#define BURST_WRITE_FIFO 0x7f //突發寫TX FIFO
#define BYTE_WRITE_FIFO 0x3f //單字節寫 TX FIFO
#define CC1101_DATA_LEN 64
//SPI接口
//底層接口宏定義
#define CC1101_CS_H() (GPIOA-》ODR|=BIT3) //PA3=1
#define CC1101_CS_L() (GPIOA-》ODR&=~BIT3) //PA3=0
#define CC1101_MOSI_H() (GPIOC-》ODR|=BIT6) //PC6
#define CC1101_MOSI_L() (GPIOC-》ODR&=~BIT6) //PC6
#define CC1101_SCLK_H() (GPIOC-》ODR|=BIT5) //PC5
#define CC1101_SCLK_L() (GPIOC-》ODR&=~BIT5) //PC5
#define CC1101_GetMISO() (GPIOC-》IDR&BIT7) //PC7
//CC1101 SPI讀寫一字節
//不帶片選
u8 CC1101_ReadWriteByte(u8 data)
{
u8 i;
u8 temp = 0;
for(i = 0;i 《 8;i ++)
{
if(data & 0x80)
{
CC1101_MOSI_H();
}
else
{
CC1101_MOSI_L();
}
data 《《= 1;nop;
CC1101_SCLK_H(); //時鐘上升沿寫入數據
temp 《《= 1;nop;
if(CC1101_GetMISO()) temp ++;
CC1101_SCLK_L(); //時鐘下降沿讀取數據
}
return temp;
}
/*************************************************************************************************************************
* 函數 : u8 CC1101_Command(CC1101_CMD_TYPE Cmd)
* 功能 : 發送單字節命令
* 參數 : Cmd;命令,見CC1101_CMD_TYPE
* 返回 : 寄存器的值
* 依賴 : 底層宏定義
* 作者 : cp1300@139.com
* 時間 : 2013-12-06
* 最后修改時間 : 2013-12-06
* 說明 : 以寫的方式單直接訪問將觸發響應的命令
*************************************************************************************************************************/
u8 CC1101_Command(CC1101_CMD_TYPE Cmd)
{
u8 status;
CC1101_CS_L(); //片選有效
while(CC1101_GetMISO());
status = CC1101_ReadWriteByte((u8)Cmd); //發送命令
while(CC1101_GetMISO());
CC1101_CS_H(); //片選關閉
return status;
}
/*************************************************************************************************************************
* 函數 : u8 CC1101_ReadReg(CC1101_REG_TYPE RegAddr)
* 功能 : 讀取CC1101通用寄存器
* 參數 : RegAddr:寄存器地址,見:CC1101_REG_TYPE
* 返回 : 寄存器的值
* 依賴 : 底層宏定義
* 作者 : cp1300@139.com
* 時間 : 2013-12-06
* 最后修改時間 : 2013-12-06
* 說明 : 一次讀取一個寄存器
*************************************************************************************************************************/
u8 CC1101_ReadReg(CC1101_REG_TYPE RegAddr)
{
u8 data;
CC1101_CS_L(); //片選有效
CC1101_ReadWriteByte((u8)READ_SINGLE|RegAddr); //發送讀命令以及寄存器索引
data = CC1101_ReadWriteByte(0xff); //讀取
CC1101_CS_H(); //片選關閉
return data;
}
/*************************************************************************************************************************
* 函數 : u8 CC1101_WriteReg(CC1101_REG_TYPE RegAddr, u8 data)
* 功能 : 寫入CC1101通用寄存器
* 參數 : RegAddr:寄存器地址,見:CC1101_REG_TYPE,data:需要寫入的數據
* 返回 : 狀態寄存器的值
* 依賴 : 底層宏定義
* 作者 : cp1300@139.com
* 時間 : 2013-12-06
* 最后修改時間 : 2013-12-06
* 說明 : 一次寫入一個寄存器,并返回狀態
不要對只讀的寄存器進行寫操作
*************************************************************************************************************************/
u8 CC1101_WriteReg(CC1101_REG_TYPE RegAddr, u8 data)
{
u8 status;
if(RegAddr 》 0x80) return 0; //防止誤操作,0x30以后的寄存器為只讀狀態寄存器
CC1101_CS_L(); //片選有效
while(CC1101_GetMISO());
status = CC1101_ReadWriteByte((u8)WRITE_SINGLE|RegAddr); //發送寫命令以及寄存器索引
CC1101_ReadWriteByte(data); //寫入數據
CC1101_CS_H(); //片選關閉
return status;
}
#include “LED.h”
void CC1101_Init(u8 Addr)
{
//初始化片選
GPIOx_Init(GPIOA, BIT3, OUT_PP_10M);
CC1101_CS_H();
//初始化SCLK
GPIOx_Init(GPIOC, BIT5, OUT_PP_10M);
CC1101_SCLK_H();
//初始化MOSI
GPIOx_Init(GPIOC, BIT6, OUT_PP_10M);
CC1101_MOSI_H();
//初始化MISO
GPIOx_Init(GPIOC, BIT7, IN_UP);
CC1101_SCLK_L();
CC1101_MOSI_L();
//初始化GDO0,GDO2對應PC3,PC4
GPIOx_Init(GPIOC, BIT3, IN_UP);
GPIOx_Init(GPIOC, BIT4, IN_UP);
//初始化寄存器
CC1101_Command(CC1101_CMD_SRES); //復位
Delay_MS(10);
while(CC1101_ReadReg(CC1101_REG_AGCTEST) != 0x3F) //檢測通信
{
LED_ON();
Delay_MS(10);
LED_OFF();
Delay_MS(100);
}
LED_OFF();
CC1101_WriteReg(CC1101_REG_IOCFG0,0x06); //發送提示引腳
CC1101_WriteReg(CC1101_REG_IOCFG2,0x01); //接收提示引腳
CC1101_WriteReg(CC1101_REG_FIFOTHR,0x0f); //RX FIFO和TX FIFO門限
CC1101_WriteReg(CC1101_REG_SYNC1,0xD3); //同步詞匯,高字節
CC1101_WriteReg(CC1101_REG_SYNC0,0x91); //同步詞匯,低字節
CC1101_WriteReg(CC1101_REG_PKTLEN,CC1101_DATA_LEN); //數據包長度,255
CC1101_WriteReg(CC1101_REG_PKTCTRL1,0x04); //數據包自動控制
CC1101_WriteReg(CC1101_REG_PKTCTRL0,0x04); //數據包自動控制
CC1101_WriteReg(CC1101_REG_ADDR,0x00); //設備地址
CC1101_WriteReg(CC1101_REG_CHANNR,0x00); //信道
CC1101_WriteReg(CC1101_REG_FSCTRL1,0x06); //頻率合成器控制,高字節
CC1101_WriteReg(CC1101_REG_FSCTRL0,0x00); //頻率合成器控制,低字節
CC1101_WriteReg(CC1101_REG_FREQ2,0x10); //頻率控制詞匯,高字節
CC1101_WriteReg(CC1101_REG_FREQ1,0xb1); //頻率控制詞匯,中間字節
CC1101_WriteReg(CC1101_REG_FREQ0,0x3b); //頻率控制詞匯,低字節
//2.4KBPS
CC1101_WriteReg(CC1101_REG_MDMCFG4,0xF6); //調制器配置
CC1101_WriteReg(CC1101_REG_MDMCFG3,0x83); //調制器配置
CC1101_WriteReg(CC1101_REG_MDMCFG2,0x13); //調制器配置
CC1101_WriteReg(CC1101_REG_MDMCFG1,0x22); //調制器配置
CC1101_WriteReg(CC1101_REG_MDMCFG0,0xf8); //調制器配置
CC1101_WriteReg(CC1101_REG_DEVIATN,0x15); //調制器背離設置
CC1101_WriteReg(CC1101_REG_MCSM2,0x07); //主通信控制狀態機配置
CC1101_WriteReg(CC1101_REG_MCSM1,0x30); //主通信控制狀態機配置
CC1101_WriteReg(CC1101_REG_MCSM0,0x18); //主通信控制狀態機配置
CC1101_WriteReg(CC1101_REG_FOCCFG,0x16); //頻率偏移補償配置
CC1101_WriteReg(CC1101_REG_BSCFG,0x6c); //位同步配置
CC1101_WriteReg(CC1101_REG_AGCTRL2,0x03); //AGC控制
CC1101_WriteReg(CC1101_REG_AGCTRL1,0x40); //AGC控制
CC1101_WriteReg(CC1101_REG_AGCTRL0,0x91); //AGC控制
CC1101_WriteReg(CC1101_REG_WOREVT1,0x87); //高字節時間0暫停
CC1101_WriteReg(CC1101_REG_WOREVT0,0x6b); //低字節時間0暫停
CC1101_WriteReg(CC1101_REG_WORCTRL,0xfb); //電磁波激活控制
CC1101_WriteReg(CC1101_REG_FREND1,0x56); //前末端RX配置
CC1101_WriteReg(CC1101_REG_FREND0,0x10); //前末端TX配置
CC1101_WriteReg(CC1101_REG_FSCAL3,0xe9); //頻率合成器校準
CC1101_WriteReg(CC1101_REG_FSCAL2,0x2a); //頻率合成器校準
CC1101_WriteReg(CC1101_REG_FSCAL1,0x00); //頻率合成器校準
CC1101_WriteReg(CC1101_REG_FSCAL0,0x1f); //頻率合成器校準
CC1101_WriteReg(CC1101_REG_RCCTRL1,0x41); //RC振蕩器配置
CC1101_WriteReg(CC1101_REG_RCCTRL0,0x00); //RC振蕩器配置
CC1101_WriteReg(CC1101_REG_FSTEST,0x59); //頻率合成器校準控制
//10DB
//CC1101_WriteReg(CC1101_REG_PATABLE0,0xc0);
//CC1101_WriteReg(CC1101_REG_PATABLE1,0xc0);
/*CC1101_WriteReg(CC1101_REG_PATABLE2,0xc0);
CC1101_WriteReg(CC1101_REG_PATABLE3,0xc0);
CC1101_WriteReg(CC1101_REG_PATABLE4,0xc0);
CC1101_WriteReg(CC1101_REG_PATABLE5,0xc0);
CC1101_WriteReg(CC1101_REG_PATABLE6,0xc0);
CC1101_WriteReg(CC1101_REG_PATABLE7,0xc0); */
Delay_MS(10);
}
/*************************************************************************************************************************
* 函數 : void CC1101_WriteTxFIFO(u8 *pBuff,u8 len)
* 功能 : 寫入數據到發送緩沖區
* 參數 : pBuff:需要寫入的數據緩沖區指針,len:需要寫入的數據長度
* 返回 : 無
* 依賴 : 底層宏定義
* 作者 : cp1300@139.com
* 時間 : 2014-01-01
* 最后修改時間 : 2014-01-01
* 說明 : 寫入數據到發送FIFO
*************************************************************************************************************************/
void CC1101_WriteTxFIFO(u8 *pBuff,u8 len)
{
u16 i;
CC1101_CS_L();
CC1101_ReadWriteByte(BURST_WRITE_FIFO);
for(i = 0;i 《 len;i ++)
{
CC1101_ReadWriteByte(pBuff);
}
CC1101_CS_H();
}
/*************************************************************************************************************************
* 函數 : void CC1101_ReadRxFIFO(u8 *pBuff,u8 len)
* 功能 : 讀取接收緩沖區
* 參數 : pBuff:需要讀取的數據緩沖區指針,len:需要讀取的數據長度
* 返回 : 無
* 依賴 : 底層宏定義
* 作者 : cp1300@139.com
* 時間 : 2014-01-01
* 最后修改時間 : 2014-01-01
* 說明 : 從接收FIFO讀取數據
*************************************************************************************************************************/
void CC1101_ReadRxFIFO(u8 *pBuff,u8 len)
{
u16 i;
CC1101_CS_L();
CC1101_ReadWriteByte(BURST_READ_FIFO);
for(i = 0;i 《 len;i ++)
{
pBuff = CC1101_ReadWriteByte(0xff);
}
CC1101_CS_H();
}
//發送數據,將緩沖區數據全部發送出去
//一次最多64B,因為受到FIFO限制
void CC1101_RfDataSend(u8 *pBuff,u8 len)
{
CC1101_Command(CC1101_CMD_SIDLE); //退出當前模式
CC1101_Command(CC1101_CMD_SFTX); //清空發送緩沖區
CC1101_WriteTxFIFO(pBuff, len); //寫入數據到發送緩沖區
CC1101_Command(CC1101_CMD_STX); //開始發送數據
while(!CC1101_GDO0);
while(CC1101_GDO0);
CC1101_Command(CC1101_CMD_SIDLE); //退出當前模式
}
//發送數據包
//每次發送最多65B,第一字節為長度,數據多將會重復發送
//可以發送任意大小
//CC1101PackSize有效數據包大小,0-64,也就是CC1101單次發送數據大小-1
void CC1101_RfDataSendPack(u8 *pBuff, u16 len)
{
u16 i,m,n,j;
m = len / (CC1101_DATA_LEN-1); //整數數據幀數量
n = len % (CC1101_DATA_LEN-1); //余數
//發送整數包
for(i = 0;i 《 m;i ++)
{
Delay_MS(1);
CC1101_Command(CC1101_CMD_SIDLE); //退出當前模式
CC1101_Command(CC1101_CMD_SFTX); //清空發送緩沖區
CC1101_CS_L();
CC1101_ReadWriteByte(BURST_WRITE_FIFO);
CC1101_ReadWriteByte(CC1101_DATA_LEN-1);//先寫入包大小
for(j = 0;j 《 (CC1101_DATA_LEN-1);j ++)
{
CC1101_ReadWriteByte(*pBuff++); //寫入數據到發送緩沖區
}
CC1101_CS_H();
CC1101_Command(CC1101_CMD_STX); //開始發送數據
while(!CC1101_GDO0);
while(CC1101_GDO0); //等待發送完成
}
//發送余數包
if(n!=0)
{
Delay_MS(1);
CC1101_Command(CC1101_CMD_SIDLE); //退出當前模式
CC1101_Command(CC1101_CMD_SFTX); //清空發送緩沖區
CC1101_CS_L();
CC1101_ReadWriteByte(BURST_WRITE_FIFO);
CC1101_ReadWriteByte(n); //先寫入包大小
for(j = 0;j 《 n;j ++)
{
CC1101_ReadWriteByte(*pBuff++); //寫入數據到發送緩沖區
}
CC1101_CS_H();
CC1101_Command(CC1101_CMD_STX); //開始發送數據
while(!CC1101_GDO0);
while(CC1101_GDO0); //等待發送完成
}
CC1101_Command(CC1101_CMD_SIDLE); //退出當前模式
}
//讀取芯片狀態
u8 CC1101_GetStatus(void)
{
return CC1101_WriteReg(CC1101_REG_TEST2, 0x98);
}
結語
關于cc1101的相關介紹就到這了,如有不足之處歡迎指正。
評論
查看更多