本文主要是關(guān)于cc1101的相關(guān)介紹,并著重對(duì)cc1101低功耗以及驅(qū)動(dòng)收發(fā)程序進(jìn)行了詳盡的闡述。
cc1101
CC1101是一款低于1GHz設(shè)計(jì)旨在用于極低功耗RF應(yīng)用。其主要針對(duì)工業(yè)、科研和醫(yī)療(ISM)以及短距離無(wú)線通信設(shè)備(SRD)。CC1101可提供對(duì)數(shù)據(jù)包處理、數(shù)據(jù)緩沖、突發(fā)傳輸、接收信號(hào)強(qiáng)度指示(RSSI)、空閑信道評(píng)估(CCA)、鏈路質(zhì)量指示以及無(wú)線喚醒(WOR)的廣泛硬件支持。CC1101在代碼、封裝和外引腳方面均與CC1100兼容,可用于全球最為常用的開(kāi)放式低于1GHz頻率的RF設(shè)計(jì)。
● 超低功耗無(wú)線收發(fā)器
● 家庭和樓宇自動(dòng)化
● 高級(jí)抄表架構(gòu)(AMI)
● 無(wú)線報(bào)警安全系統(tǒng)
◆ 387.0MHz~464.0MHz工作頻段。
?。?33MHz,0.6kbps,1%誤碼率時(shí)為-116dBm)。
(接收模式,433MHz,1.2kbps時(shí)僅16.0mA)。
◆ 最高可設(shè)置為+10dBm的發(fā)射功率。
◆ 支持0.6kbps~500kbps的數(shù)據(jù)傳輸速率。
◆ 支持多種調(diào)制模式(OOK、ASK、GFSK、2-FSK、4-FSK和MSK)。
◆ 提供對(duì)同步字檢測(cè)、地址校驗(yàn)、靈活的數(shù)據(jù)包長(zhǎng)度以及自動(dòng)CRC處理的支持。
◆ 支持RSSI(接收信號(hào)強(qiáng)度指示)和LQI(鏈路質(zhì)量指示)。
◆ 通過(guò)4線SPI接口與MCU連接,同時(shí)提供2個(gè)可設(shè)定功能的通用數(shù)字輸出引腳。
◆ 獨(dú)立的64字節(jié)RXFIFO和TX FIFO。
◆ 工作電壓范圍:1.9V~3.6V,待機(jī)模式下電流僅為200nA。
◆ 工作溫度范圍:-40℃~+85℃
cc1101低功耗設(shè)計(jì)方案
電路設(shè)計(jì)上,只用到了一個(gè)LED、串口1、一個(gè)模擬SPI、一個(gè)中斷線、一個(gè)讀卡芯片RESET線,硬件上就只剩下這么點(diǎn)東西了,這個(gè)時(shí)候我采用的是待機(jī)模式,使用的是讀卡芯片的中斷接PA0喚醒STM32,在此之前要先使得讀卡芯片進(jìn)入低功耗、然后STM32進(jìn)入低功耗,這一步完成了,貌似沒(méi)什么問(wèn)題,功耗確實(shí)從幾十mA驟降到3mA左右,開(kāi)始還挺滿意的,但是測(cè)試廠商提供的樣板,功耗卻只有幾十uA,有點(diǎn)郁悶了。為什么會(huì)這樣?反復(fù)查看硬件、程序,都找不出原因,而且這個(gè)時(shí)候的工作效果很爛,根本就不能喚醒,所以我就懷疑是讀卡芯片一端低功耗有問(wèn)題,因?yàn)槲覍A0腳直接短接VCC,這樣就可以產(chǎn)生一個(gè)邊沿觸發(fā)STM32喚醒了,但是用讀卡芯片無(wú)法喚醒,所以我懷疑是讀卡芯片的RESET腳電平不對(duì),經(jīng)檢查,確實(shí)是因?yàn)镽ESET腳加了上拉電阻,讀卡芯片是高電平復(fù)位,在STM32進(jìn)入待機(jī)后,管腳全都浮空了,導(dǎo)致RESET被拉高,一直在復(fù)位;我去掉上拉電阻,覺(jué)得很有希望解決問(wèn)題了,但是測(cè)試結(jié)果是:有時(shí)候能喚醒,有時(shí)候不能,我仔細(xì)一想難道是因?yàn)镾TM32待機(jī)后管腳電平不確定,導(dǎo)致讀卡芯片RESET腳電平不定,而工作不正常,看樣子只有換用其他方案了。后面確實(shí)驗(yàn)證了我的想法,使用STOP模式后,喚醒問(wèn)題引刃而解。
就在關(guān)鍵時(shí)刻,芯片原廠火種送炭,送來(lái)急需的技術(shù)支持資料,一個(gè)包含低功耗源代碼,趕緊拿過(guò)來(lái)測(cè)試,先研讀下代碼,使用的是STOP模式,而不是待機(jī)模式,使用的是任意外部中斷喚醒,功耗低制40uA,這個(gè)時(shí)候就相當(dāng)激動(dòng)啊,趕快下載測(cè)試啊,結(jié)果功耗確實(shí)降了,但還是有1mA,更人家一比多了幾十倍啊。。。
我第一反應(yīng)是硬件不對(duì),經(jīng)過(guò)測(cè)試修改,首先找到第一個(gè)原因,讀卡芯片RESET管腳上拉電阻又給焊上去了。。.,拆掉后功耗驟降到幾百uA,還是不行。。 測(cè)試過(guò)程中,為了去掉LDO的干擾,整板采用3.3V供電,但是后面經(jīng)過(guò)測(cè)試,LDO的功耗其實(shí)也只有5uA不到,這LDO功耗值得贊一個(gè);雖然結(jié)果還是沒(méi)達(dá)到預(yù)期,但是看到了希望,勝利就在眼前啊。
為此我反復(fù)看了技術(shù)支持提供的程序,發(fā)現(xiàn)他們的STM32的所有管腳都的設(shè)置都有所考究:(因?yàn)?a target="_blank">公司保密原則,代碼中刪除掉了關(guān)于該讀卡芯片的前綴信息等)
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這些管腳應(yīng)該設(shè)置為推挽輸出,TXD設(shè)置為復(fù)用輸出,而IRQ、RXD、MISO設(shè)置浮空輸入,什么都沒(méi)接的管腳全都設(shè)置為下拉輸入,而TESTI、TESO我一直不解是什么東東,開(kāi)始就沒(méi)管,而開(kāi)始的時(shí)候MISO我也沒(méi)怎么注意,設(shè)置成上拉輸入(而不是浮空輸入),反正大部分按照廠家提供的參考,我并沒(méi)有照搬,測(cè)試效果一樣,但功耗確是還有80-90uA,期間我找了好久沒(méi)找到原因,給技術(shù)支持一看,原來(lái)是因?yàn)镸ISO沒(méi)有設(shè)置成浮空輸入,我是設(shè)置成了上拉輸入,上拉電阻一直在消耗大約40uA的電流。。。 好吧,這是自己不夠細(xì)心導(dǎo)致的,以后做低功耗的項(xiàng)目管腳配置是個(gè)大問(wèn)題,不能再這么馬虎了?。?! 我將MISO設(shè)置成浮空輸入之后,最低功耗還是有40+,離10uA的最低功耗還有段距離,到底是為什么呢?最后我發(fā)現(xiàn)
,該讀卡芯片有個(gè)TESTIN/TESTOUT管腳,是用來(lái)測(cè)試用的,出廠后也就用不上了,我也一直以為這兩個(gè)腳確實(shí)沒(méi)什么用,就沒(méi)接;可是我發(fā)現(xiàn)廠家提供的樣板居然接了這兩個(gè)腳,但是廠商也沒(méi)說(shuō)這兩個(gè)腳接或不接會(huì)影響功耗啊,抱著試一試的心態(tài),我我把TESTIN/TESTOUT兩個(gè)管腳接到單片機(jī)上進(jìn)行相應(yīng)的配置,接下來(lái)是見(jiàn)證奇跡的時(shí)刻了,功耗居然真的、真的降到10uA了。。。。。。。。。。。 此處省略n個(gè)字
這時(shí)候真的很激動(dòng),真的很想罵人啊,坑爹的廠家,為什么不給提示說(shuō)這兩個(gè)腳不接單片機(jī)會(huì)消耗電流呢?(也許是文檔里面提到了,但是幾百頁(yè)的文檔,還是全英文的,一堆堆的文字,我再看一遍,確實(shí)沒(méi)有提到這兩個(gè)管腳會(huì)有漏電流。)
項(xiàng)目就這樣完工了,中間最重要的是技術(shù)支持的強(qiáng)力支持,不然項(xiàng)目不能完工了,這個(gè)項(xiàng)目低功耗STM32方面難度不高,主要是讀卡芯片上面的低功耗調(diào)試起來(lái)問(wèn)題很多,還是人家原廠的出馬才解決了問(wèn)題,因?yàn)楸姸嘣?,不能公布該芯片的資料,包括該芯片怎么進(jìn)入低功耗也無(wú)法公開(kāi),所以抱歉~~。
關(guān)于STM32進(jìn)入低功耗,我簡(jiǎn)單的總結(jié)了一下:
1.管腳設(shè)置,這個(gè)很關(guān)鍵,還是跟你電路有關(guān)系,外加上拉、下拉電阻切記不能隨便加
2.STM32的systick clock、DMA、TIM什么的,能關(guān)就全都關(guān)掉,STM32低功耗很簡(jiǎn)單,關(guān)鍵是外圍電路功耗是關(guān)鍵
3.選擇一個(gè)低功耗的LDO,這個(gè)項(xiàng)目用到的LDO功耗就很不錯(cuò),靜態(tài)功耗10uA都不到。
4.確定STM32設(shè)置沒(méi)問(wèn)題,進(jìn)入低功耗有好幾種情況可以選擇(睡眠、停機(jī)、待機(jī)),我還是推薦選擇STOP模式,這個(gè)我覺(jué)的比較好是因?yàn)榭梢匀我馔獠恐袛喽伎梢詥拘?,而且管腳可以保留之前的設(shè)置,進(jìn)入停機(jī)模式的代碼使用庫(kù)函數(shù)自帶的,就一句:
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
意思是,在進(jìn)入停機(jī)模式之前,也關(guān)掉電壓調(diào)節(jié)器,進(jìn)一步降低功耗,使用WFI指令(任意中斷喚醒),但是經(jīng)過(guò)測(cè)試,使用WFE(任事件喚醒)指令效果、功耗一模一樣。
最后一步是從STOP模式怎么恢復(fù)了,恢復(fù)其實(shí)也很簡(jiǎn)單,外部中斷來(lái)了會(huì)進(jìn)入中斷函數(shù),然后STM32就被喚醒,喚醒還要做一些工作,需要開(kāi)啟外部晶振(當(dāng)然你也可以選擇使用內(nèi)部自帶振蕩器)、開(kāi)啟你需要的外設(shè)等等。
CC1101收發(fā)驅(qū)動(dòng)程序
#include “system.h”
#include “delay.h”
#include “CC1101.h”
//CC1101命令掩碼
#define WRITE_BURST 0x40 //連續(xù)寫入
#define READ_SINGLE 0x80 //讀
#define WRITE_SINGLE 0x00 //寫
#define READ_BURST 0xC0
//連續(xù)讀
#define BURST_READ_FIFO 0xff //突發(fā)讀取RX FIFO
#define BYTE_READ_FIFO 0xBF //單字節(jié)讀取 RX FIFO
#define BURST_WRITE_FIFO 0x7f //突發(fā)寫TX FIFO
#define BYTE_WRITE_FIFO 0x3f //單字節(jié)寫 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讀寫一字節(jié)
//不帶片選
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(); //時(shí)鐘上升沿寫入數(shù)據(jù)
temp 《《= 1;nop;
if(CC1101_GetMISO()) temp ++;
CC1101_SCLK_L(); //時(shí)鐘下降沿讀取數(shù)據(jù)
}
return temp;
}
/*************************************************************************************************************************
* 函數(shù) : u8 CC1101_Command(CC1101_CMD_TYPE Cmd)
* 功能 : 發(fā)送單字節(jié)命令
* 參數(shù) : Cmd;命令,見(jiàn)CC1101_CMD_TYPE
* 返回 : 寄存器的值
* 依賴 : 底層宏定義
* 作者 : cp1300@139.com
* 時(shí)間 : 2013-12-06
* 最后修改時(shí)間 : 2013-12-06
* 說(shuō)明 : 以寫的方式單直接訪問(wèn)將觸發(fā)響應(yīng)的命令
*************************************************************************************************************************/
u8 CC1101_Command(CC1101_CMD_TYPE Cmd)
{
u8 status;
CC1101_CS_L(); //片選有效
while(CC1101_GetMISO());
status = CC1101_ReadWriteByte((u8)Cmd); //發(fā)送命令
while(CC1101_GetMISO());
CC1101_CS_H(); //片選關(guān)閉
return status;
}
/*************************************************************************************************************************
* 函數(shù) : u8 CC1101_ReadReg(CC1101_REG_TYPE RegAddr)
* 功能 : 讀取CC1101通用寄存器
* 參數(shù) : RegAddr:寄存器地址,見(jiàn):CC1101_REG_TYPE
* 返回 : 寄存器的值
* 依賴 : 底層宏定義
* 作者 : cp1300@139.com
* 時(shí)間 : 2013-12-06
* 最后修改時(shí)間 : 2013-12-06
* 說(shuō)明 : 一次讀取一個(gè)寄存器
*************************************************************************************************************************/
u8 CC1101_ReadReg(CC1101_REG_TYPE RegAddr)
{
u8 data;
CC1101_CS_L(); //片選有效
CC1101_ReadWriteByte((u8)READ_SINGLE|RegAddr); //發(fā)送讀命令以及寄存器索引
data = CC1101_ReadWriteByte(0xff); //讀取
CC1101_CS_H(); //片選關(guān)閉
return data;
}
/*************************************************************************************************************************
* 函數(shù) : u8 CC1101_WriteReg(CC1101_REG_TYPE RegAddr, u8 data)
* 功能 : 寫入CC1101通用寄存器
* 參數(shù) : RegAddr:寄存器地址,見(jiàn):CC1101_REG_TYPE,data:需要寫入的數(shù)據(jù)
* 返回 : 狀態(tài)寄存器的值
* 依賴 : 底層宏定義
* 作者 : cp1300@139.com
* 時(shí)間 : 2013-12-06
* 最后修改時(shí)間 : 2013-12-06
* 說(shuō)明 : 一次寫入一個(gè)寄存器,并返回狀態(tài)
不要對(duì)只讀的寄存器進(jìn)行寫操作
*************************************************************************************************************************/
u8 CC1101_WriteReg(CC1101_REG_TYPE RegAddr, u8 data)
{
u8 status;
if(RegAddr 》 0x80) return 0; //防止誤操作,0x30以后的寄存器為只讀狀態(tài)寄存器
CC1101_CS_L(); //片選有效
while(CC1101_GetMISO());
status = CC1101_ReadWriteByte((u8)WRITE_SINGLE|RegAddr); //發(fā)送寫命令以及寄存器索引
CC1101_ReadWriteByte(data); //寫入數(shù)據(jù)
CC1101_CS_H(); //片選關(guān)閉
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對(duì)應(yīng)PC3,PC4
GPIOx_Init(GPIOC, BIT3, IN_UP);
GPIOx_Init(GPIOC, BIT4, IN_UP);
//初始化寄存器
CC1101_Command(CC1101_CMD_SRES); //復(fù)位
Delay_MS(10);
while(CC1101_ReadReg(CC1101_REG_AGCTEST) != 0x3F) //檢測(cè)通信
{
LED_ON();
Delay_MS(10);
LED_OFF();
Delay_MS(100);
}
LED_OFF();
CC1101_WriteReg(CC1101_REG_IOCFG0,0x06); //發(fā)送提示引腳
CC1101_WriteReg(CC1101_REG_IOCFG2,0x01); //接收提示引腳
CC1101_WriteReg(CC1101_REG_FIFOTHR,0x0f); //RX FIFO和TX FIFO門限
CC1101_WriteReg(CC1101_REG_SYNC1,0xD3); //同步詞匯,高字節(jié)
CC1101_WriteReg(CC1101_REG_SYNC0,0x91); //同步詞匯,低字節(jié)
CC1101_WriteReg(CC1101_REG_PKTLEN,CC1101_DATA_LEN); //數(shù)據(jù)包長(zhǎng)度,255
CC1101_WriteReg(CC1101_REG_PKTCTRL1,0x04); //數(shù)據(jù)包自動(dòng)控制
CC1101_WriteReg(CC1101_REG_PKTCTRL0,0x04); //數(shù)據(jù)包自動(dòng)控制
CC1101_WriteReg(CC1101_REG_ADDR,0x00); //設(shè)備地址
CC1101_WriteReg(CC1101_REG_CHANNR,0x00); //信道
CC1101_WriteReg(CC1101_REG_FSCTRL1,0x06); //頻率合成器控制,高字節(jié)
CC1101_WriteReg(CC1101_REG_FSCTRL0,0x00); //頻率合成器控制,低字節(jié)
CC1101_WriteReg(CC1101_REG_FREQ2,0x10); //頻率控制詞匯,高字節(jié)
CC1101_WriteReg(CC1101_REG_FREQ1,0xb1); //頻率控制詞匯,中間字節(jié)
CC1101_WriteReg(CC1101_REG_FREQ0,0x3b); //頻率控制詞匯,低字節(jié)
//2.4KBPS
CC1101_WriteReg(CC1101_REG_MDMCFG4,0xF6); //調(diào)制器配置
CC1101_WriteReg(CC1101_REG_MDMCFG3,0x83); //調(diào)制器配置
CC1101_WriteReg(CC1101_REG_MDMCFG2,0x13); //調(diào)制器配置
CC1101_WriteReg(CC1101_REG_MDMCFG1,0x22); //調(diào)制器配置
CC1101_WriteReg(CC1101_REG_MDMCFG0,0xf8); //調(diào)制器配置
CC1101_WriteReg(CC1101_REG_DEVIATN,0x15); //調(diào)制器背離設(shè)置
CC1101_WriteReg(CC1101_REG_MCSM2,0x07); //主通信控制狀態(tài)機(jī)配置
CC1101_WriteReg(CC1101_REG_MCSM1,0x30); //主通信控制狀態(tài)機(jī)配置
CC1101_WriteReg(CC1101_REG_MCSM0,0x18); //主通信控制狀態(tài)機(jī)配置
CC1101_WriteReg(CC1101_REG_FOCCFG,0x16); //頻率偏移補(bǔ)償配置
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); //高字節(jié)時(shí)間0暫停
CC1101_WriteReg(CC1101_REG_WOREVT0,0x6b); //低字節(jié)時(shí)間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); //頻率合成器校準(zhǔn)
CC1101_WriteReg(CC1101_REG_FSCAL2,0x2a); //頻率合成器校準(zhǔn)
CC1101_WriteReg(CC1101_REG_FSCAL1,0x00); //頻率合成器校準(zhǔn)
CC1101_WriteReg(CC1101_REG_FSCAL0,0x1f); //頻率合成器校準(zhǔn)
CC1101_WriteReg(CC1101_REG_RCCTRL1,0x41); //RC振蕩器配置
CC1101_WriteReg(CC1101_REG_RCCTRL0,0x00); //RC振蕩器配置
CC1101_WriteReg(CC1101_REG_FSTEST,0x59); //頻率合成器校準(zhǔn)控制
//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);
}
/*************************************************************************************************************************
* 函數(shù) : void CC1101_WriteTxFIFO(u8 *pBuff,u8 len)
* 功能 : 寫入數(shù)據(jù)到發(fā)送緩沖區(qū)
* 參數(shù) : pBuff:需要寫入的數(shù)據(jù)緩沖區(qū)指針,len:需要寫入的數(shù)據(jù)長(zhǎng)度
* 返回 : 無(wú)
* 依賴 : 底層宏定義
* 作者 : cp1300@139.com
* 時(shí)間 : 2014-01-01
* 最后修改時(shí)間 : 2014-01-01
* 說(shuō)明 : 寫入數(shù)據(jù)到發(fā)送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();
}
/*************************************************************************************************************************
* 函數(shù) : void CC1101_ReadRxFIFO(u8 *pBuff,u8 len)
* 功能 : 讀取接收緩沖區(qū)
* 參數(shù) : pBuff:需要讀取的數(shù)據(jù)緩沖區(qū)指針,len:需要讀取的數(shù)據(jù)長(zhǎng)度
* 返回 : 無(wú)
* 依賴 : 底層宏定義
* 作者 : cp1300@139.com
* 時(shí)間 : 2014-01-01
* 最后修改時(shí)間 : 2014-01-01
* 說(shuō)明 : 從接收FIFO讀取數(shù)據(jù)
*************************************************************************************************************************/
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();
}
//發(fā)送數(shù)據(jù),將緩沖區(qū)數(shù)據(jù)全部發(fā)送出去
//一次最多64B,因?yàn)槭艿紽IFO限制
void CC1101_RfDataSend(u8 *pBuff,u8 len)
{
CC1101_Command(CC1101_CMD_SIDLE); //退出當(dāng)前模式
CC1101_Command(CC1101_CMD_SFTX); //清空發(fā)送緩沖區(qū)
CC1101_WriteTxFIFO(pBuff, len); //寫入數(shù)據(jù)到發(fā)送緩沖區(qū)
CC1101_Command(CC1101_CMD_STX); //開(kāi)始發(fā)送數(shù)據(jù)
while(!CC1101_GDO0);
while(CC1101_GDO0);
CC1101_Command(CC1101_CMD_SIDLE); //退出當(dāng)前模式
}
//發(fā)送數(shù)據(jù)包
//每次發(fā)送最多65B,第一字節(jié)為長(zhǎng)度,數(shù)據(jù)多將會(huì)重復(fù)發(fā)送
//可以發(fā)送任意大小
//CC1101PackSize有效數(shù)據(jù)包大小,0-64,也就是CC1101單次發(fā)送數(shù)據(jù)大小-1
void CC1101_RfDataSendPack(u8 *pBuff, u16 len)
{
u16 i,m,n,j;
m = len / (CC1101_DATA_LEN-1); //整數(shù)數(shù)據(jù)幀數(shù)量
n = len % (CC1101_DATA_LEN-1); //余數(shù)
//發(fā)送整數(shù)包
for(i = 0;i 《 m;i ++)
{
Delay_MS(1);
CC1101_Command(CC1101_CMD_SIDLE); //退出當(dāng)前模式
CC1101_Command(CC1101_CMD_SFTX); //清空發(fā)送緩沖區(qū)
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++); //寫入數(shù)據(jù)到發(fā)送緩沖區(qū)
}
CC1101_CS_H();
CC1101_Command(CC1101_CMD_STX); //開(kāi)始發(fā)送數(shù)據(jù)
while(!CC1101_GDO0);
while(CC1101_GDO0); //等待發(fā)送完成
}
//發(fā)送余數(shù)包
if(n!=0)
{
Delay_MS(1);
CC1101_Command(CC1101_CMD_SIDLE); //退出當(dāng)前模式
CC1101_Command(CC1101_CMD_SFTX); //清空發(fā)送緩沖區(qū)
CC1101_CS_L();
CC1101_ReadWriteByte(BURST_WRITE_FIFO);
CC1101_ReadWriteByte(n); //先寫入包大小
for(j = 0;j 《 n;j ++)
{
CC1101_ReadWriteByte(*pBuff++); //寫入數(shù)據(jù)到發(fā)送緩沖區(qū)
}
CC1101_CS_H();
CC1101_Command(CC1101_CMD_STX); //開(kāi)始發(fā)送數(shù)據(jù)
while(!CC1101_GDO0);
while(CC1101_GDO0); //等待發(fā)送完成
}
CC1101_Command(CC1101_CMD_SIDLE); //退出當(dāng)前模式
}
//讀取芯片狀態(tài)
u8 CC1101_GetStatus(void)
{
return CC1101_WriteReg(CC1101_REG_TEST2, 0x98);
}
結(jié)語(yǔ)
關(guān)于cc1101的相關(guān)介紹就到這了,如有不足之處歡迎指正。
評(píng)論
查看更多