本文主要是關于CC1101的相關介紹,并著重對基于STM32驅動CC1101的程序進行了詳盡的分析。
基于STM32驅動CC1101的程序分析
首先明確:CC1101是通過SPI與MCU進行通信的。根據從TI官方上獲得CC1101驅動,直接先移植SPI部分,STM32F103提供了SPI1和SPI2兩條SPI總線,可自行選擇,對于SPI的移植,直接參考STM32開發板上關于通過SPI操作Flash示例代碼,對于SPI的配置與TI提供的驅動代碼里的SPI配置保持一致。SPI移植完成之后,接上CC1101射頻模塊,測試SPI是否能正常通信,主要通過向CC1101任意可讀可寫寄存器寫一個任意值,然后再讀出該寄存器里的值,通過串口打印出該值,通過以上操作判斷SPI是否正常通信,SPI移植是否成功。當然,這里使用到了串口,所以需要同時將串口的代碼實現,同樣參考串口實例。
其次,當STM32與CC1101的SPI通信完成后,果斷開始CC1101后續驅動的移植。移植過程中,所有變量名、函數名與TI提供的驅動里的保持一致,當然CC1101寄存器配置也保持移植。對于移植初期,我并沒有太多的關心CC1101的時序問題,只關心怎么去移植,這也是自己的一個不好的習慣,所以初期移植的時候,對著TI提供的驅動代碼,TI代碼里有什么函數,我也移植什么函數;函數里有CS管腳的操作,也對應在操作在STM32下定義的CS管腳;TI里延時多長,我也跟著在STM32下延時相應的時間。整個驅動移植下來,關于CC1101的驅動函數也大多了然在心了。
/*
** CC1101 433MHz無線模塊相互通信
** 2014-11-16
*/
#include “stm32f10x.h”
#include “cc1101.h”
#include “led.h”
/*************NVIC控制器配置***************************/
//組號 搶占位數 子優先級數量
// 組0 0 4
// 組1 1 3
// 組2 2 2
// 組3 3 1
// 組4 4 0
#define NVIC_PRIORITY_GROUP_0 (7 - 0)
#define NVIC_PRIORITY_GROUP_1 (7 - 1)
#define NVIC_PRIORITY_GROUP_2 (7 - 2)
#define NVIC_PRIORITY_GROUP_3 (7 - 3)
#define NVIC_PRIORITY_GROUP_4 (7 - 4)
#define NVIC_PRIORITY_GROUP (NVIC_PRIORITY_GROUP_2) /* 設置為組2 */
//#include “RF_Send.h”
//#include “task.h”
//***************更多功率參數設置可詳細參考DATACC1100英文文檔中第48-49頁的參數表******************
//INT8U PaTabel[8] = {0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04}; //-30dBm 功率最小
//INT8U PaTabel[8] = {0x17,0x17 ,0x17 ,0x17 ,0x17 ,0x17,0x17 ,0x17}; //-20dBm
//INT8U PaTabel[8] = {0x1D,0x1D ,0x1D ,0x1D ,0x1D ,0x1D,0x1D ,0x1D}; //-15dBm
//INT8U PaTabel[8] = {0x26,0x26 ,0x26 ,0x26 ,0x26 ,0x26,0x26 ,0x26}; //-10dBm
//INT8U PaTabel[8] = {0x37,0x37 ,0x37 ,0x37 ,0x37 ,0x37,0x37 ,0x37}; //-6dBm
//INT8U PaTabel[8] = {0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60 ,0x60};//0dBm
//INT8U PaTabel[8] = {0x86,0x86 ,0x86 ,0x86 ,0x86 ,0x86,0x86 ,0x86}; //5dBm
const u8 PaTabel[8] = {0xC0 ,0xC0 ,0xC0 ,0xC0 ,0xC0 ,0xC0 ,0xC0 ,0xC0};//12dBm
u8 RF_Read_Buff[64];//接收緩沖區
_RF_Sta RF_Sta;//RF狀態
/////////////////////////////////////////////////////////////////
const RF_SETTINGS rfSettings =
{
0x00,
0x08, // FSCTRL1 Frequency synthesizer control.
0x00, // FSCTRL0 Frequency synthesizer control.
0x10, // FREQ2 Frequency control word, high byte.
0xA7, // FREQ1 Frequency control word, middle byte.
0x62, // FREQ0 Frequency control word, low byte.
0x5B, // MDMCFG4 Modem configuration.
0xF8, // MDMCFG3 Modem configuration.
0x03, // MDMCFG2 Modem configuration.
0x22, // MDMCFG1 Modem configuration.
0xF8, // MDMCFG0 Modem configuration.
0x00, // CHANNR Channel number.
0x47, // DEVIATN Modem deviation setting (when FSK modulation is enabled)。
0xB6, // FREND1 Front end RX configuration.
0x10, // FREND0 Front end RX configuration.
0x18, // MCSM0 Main Radio Control State Machine configuration.
// 0x0F, // MCSM1 Main Radio Control State Machine configuration.
0x1D, // FOCCFG Frequency Offset Compensation Configuration.
0x1C, // BSCFG Bit synchronization Configuration.
0xC7, // AGCCTRL2 AGC control.
0x00, // AGCCTRL1 AGC control.
0xB2, // AGCCTRL0 AGC control.
0xEA, // FSCAL3 Frequency synthesizer calibration.
0x2A, // FSCAL2 Frequency synthesizer calibration.
0x00, // FSCAL1 Frequency synthesizer calibration.
0x11, // FSCAL0 Frequency synthesizer calibration.
0x59, // FSTEST Frequency synthesizer calibration.
0x81, // TEST2 Various test settings.
0x35, // TEST1 Various test settings.
0x09, // TEST0 Various test settings.
0x0B, // IOCFG2 GDO2 output pin configuration.
0x06, // IOCFG0D GDO0 output pin configuration. Refer to SmartRF?Studio User Manual for detailed pseudo register explanation.
0x04, // PKTCTRL1 Packet automation control.
0x05, // PKTCTRL0 Packet automation control.
0x00, // ADDR Device address.
RFDATLEN // PKTLEN Packet length.
};
//*****************************************************************************************
//函數名:delayus(unsigned int s)
//輸入:時間
//輸出:無
//功能描述:普通廷時,內部用
//*****************************************************************************************
void delayus(u16 timeout)
{
u8 i;
do
{
for(i=0; i《20; i++);
}
while (--timeout);
}
/*****************************************************************************************/
//函數名:CC1101_SpiInit()
//輸入:無
//輸出:無
//功能描述:SPI初始化程序
/*****************************************************************************************/
void CC1101_SpiInit(void)
{
RCC-》APB2ENR|=1《《4; //使能PORTC時鐘
GPIOC-》CRL&=0Xff000000;
GPIOC-》CRL|=0X00833388;
GPIOC-》ODR|=0x00000023;
}
void Open_GD0_Interrupt(void)
{
uint32_t priority;
/* 使能io復用時鐘 */
RCC-》APB2ENR |= 1 《《 0;
/* 配置為輸外部中斷5在PC5上 */
AFIO-》EXTICR[1] &= ~(0xF 《《 4);
AFIO-》EXTICR[1] |= (2 《《 4);
/* 開啟外部中斷5 */
EXTI-》IMR |= (1 《《 5);
/* 上升沿觸發 */
EXTI-》RTSR |= (1 《《 5);
EXTI-》FTSR &= ~(1 《《 5);
NVIC_SetPriorityGrouping(NVIC_PRIORITY_GROUP); /* 設置為組2 */
priority = NVIC_EncodePriority (NVIC_PRIORITY_GROUP, 2, 3);
NVIC_SetPriority(EXTI9_5_IRQn,priority); /* EXTIx_IRQn 在stm32f10x.h中有定義 */
NVIC_EnableIRQ(EXTI9_5_IRQn);
}
//*****************************************************************************************
//函數名:SpisendByte(INT8U dat)
//輸入:發送的數據
//輸出:無
//功能描述:SPI發送一個字節
//*****************************************************************************************
u8 SpiTxRxByte(u8 dat)
{
u8 i,j,temp= 0;
SCK = 0;
for(i=0; i《8; i++)
{
if(dat & 0x80)MOSI = 1;
else MOSI = 0;
j++;j++;
dat 《《= 1;
j++;j++;
SCK = 1;
j++;j++;
temp 《《= 1;
if(MISO)temp++;
SCK = 0;
j++;j++;
}
return temp;
}
//*****************************************************************************************
//函數名:void RESET_CC1100(void)
//輸入:無
//輸出:無
//功能描述:復位CC1100
//*****************************************************************************************
u8 RESET_CC1100(void)
{
u16 n=0;
CSN = 0;
while(MISO)
{
if(++n》300)return 0;
delayus(5);
}
n=0;
SpiTxRxByte(CCxxx0_SRES); //寫入復位命令
while(MISO)
{
if(++n》300)return 0;
delayus(5);
}
CSN = 1;
return 1;
}
//*****************************************************************************************
//函數名:void POWER_UP_RESET_CC1100(void)
//輸入:無
//輸出:無
//功能描述:上電復位CC1100
//*****************************************************************************************
u8 POWER_UP_RESET_CC1100(void)
{
CSN = 1;
delayus(10);
CSN = 0;
delayus(10);
CSN = 1;
delayus(100);
if(RESET_CC1100())return 1; //復位CC1100
return 0;
}
CC1101調試
關于濾波指令和寄存器配置:
其實這里也TFT配置差不多,玩過TFT的都有同感,TFT可以通過RW引腳控制是讀還是寫,如果是寫寄存器,先寫寄存器的地址,然后寫數據,數據就到了相應的寄存器里面了;讀就是RW引腳設置為讀對應的電平,先寫寄存器的地址,該寄存器里面的數據就可以讀出來了。明白了這些其實理解CC1101就可以很容易理解了。
那么對應CC1101的理解:
寄存器的配置:
CC1101寄存器地址是0~0x3F,也就是BIT0~BIT5
CC1101讀寫控制是BIT7,BIT7為1時,為讀對應的寄存器,BIT7為0時,為寫相應的寄存器。
那么還剩下一個BIT6,BIT6是突發訪問控制為,BIT6為1為突發訪問,BIT6為0為單字節訪問。(突發訪問下面說)
這樣我們就可以很容易理解了,比如配置PKTCTRL0寄存器,其地址0x08,我們突發訪問寫的話寫先數據0x48,再連續寫數據,這里明白了突發訪問后就很容易知道了,如果單字節讀這個寄存器,先寫數據0x88,讀一下就可以了。
命令濾波:
命令濾波這里和TFT的寫0x22是一樣的,它就自動跳轉到寄存器的出口,cc1101這里也是,只要寫一下對應的寄存器的地址,不用寫數據,它就內部自動執行相應的指令,比如重啟芯片,設置為發送模式,共有14個濾波指令,地址從0x30~0x3D。
關于濾波指令的狀態寄存器其實是可讀不可寫的,
也就是0x30~0x3D的地址加上0xC0,(BIT7 和IBT6為1,前面說過了),比如寫數據0xF4,就可以讀到相應RSSI狀態寄存器里面的值。
CC1101的幾個狀態:
幾個狀態分別是,IDLE,TX,RX,FSTXON,校準,遷移,RXFIFO_OVERFLOW,TXFIFO_OVERFLOW,有讀的狀態字的BIT6~BIT4決定
結語
關于基于STM32驅動CC1101的程序的相關介紹就到這了,如有不足之處歡迎指正。
-
STM32
+關注
關注
2270文章
10895瀏覽量
355744 -
CC1101
+關注
關注
4文章
36瀏覽量
23141
發布評論請先 登錄
相關推薦
評論