背景
cc1101模块给的是stm8的例程,工作用不上,要用stm32的,所以要做移植;该模块使用的是spi通信,所以需要配置一下stm32的spi1来进行使用;
stm32 SPI1
我使用的是SPI1,配置如下,不同型号,配成不同的脚位就可以了;
void SPIx_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI1 and GPIOA clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1|RCC_APB2Periph_AFIO| RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB, ENABLE);
/* Configure SPI1 pins: NSS, SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//SPI1 NSS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//GPIO_SetBits(GPIOC, GPIO_Pin_4);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_4);
/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI1设置为两线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI1为主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行时钟在不操作时,时钟为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第二个时钟沿开始采样数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件(使用SSI位)管理
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //定义波特率预分频的值:波特率预分频值为8
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE); //使能SPI1外设
}
SPI1的读写:
u8 SPIx_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
}
cc1101操作文件
个人感觉cc1101的坑在于配置初始化的参数,虽然说可以使用smartRF来进行生成,但是这个过程会产生很多问题,假如我要用ASK调通了,但是我换成GFSK发现不行;这个初始化的配置寄存器我没有深究,反正你看了初始化代码和发送接收代码和我的差不多,但是就是不通的话,大多数就是初始化的时候寄存器配置有问题。下面共享一下代码,我就不放GitHub,感觉嵌入式没什么人用GitHub,Linux和前端,服务端用得比较多:
cc1101.h:
/*******************************************************************************
** 文件名: cc1101.h
** 版本: 1.0
** 工作环境: RealView MDK-ARM 5
** 作者: huangyong
** 生成日期: 2017-09-18
** 功能: firmware_set文件的头文件声明
** 相关文件:
** 修改日志: 2017-09-18 创建文档
*******************************************************************************/
#ifndef _CC1101_H
#define _CC1101_H
/* 包含头文件 *****************************************************************/
#include "stdint.h"
#include "spi.h"
/* define ********************************************************************/
//#define CSN PAout(4)
#define CSN_L GPIO_ResetBits(GPIOA,GPIO_Pin_4)
#define CSN_H GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define GDO0 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)
typedef enum {false,true}bool;
/* 变量 **********************************************************************/
typedef enum { TX_MODE, RX_MODE }TRMODE;
typedef enum { BROAD_ALL, BROAD_NO, BROAD_0, BROAD_0AND255 }ADDR_MODE;
typedef enum { BROADCAST, ADDRESS_CHECK} TX_DATA_MODE;
/* 方法 **********************************************************************/
/*read a byte from the specified register*/
uint8_t CC1101ReadReg( uint8_t addr );
/*Read a status register*/
uint8_t CC1101ReadStatus( uint8_t addr );
/*Set the device as TX mode or RX mode*/
void CC1101SetTRMode( TRMODE mode );
/*Write a command byte to the device*/
void CC1101WriteCmd( uint8_t command );
/*Set the CC1101 into IDLE mode*/
void CC1101SetIdle( void );
/*Send a packet*/
void CC1101SendPacket( uint8_t *txbuffer, uint8_t size, TX_DATA_MODE mode );
/*Set the address and address mode of the CC1101*/
void CC1101SetAddress( uint8_t address, ADDR_MODE AddressMode);
/*Set the SYNC bytes of the CC1101*/
void CC1101SetSYNC( uint16_t sync );
/*Receive a packet*/
uint8_t CC1101RecPacket( uint8_t *rxBuffer );
/*Initialize the WOR function of CC1101*/
void CC1101WORInit( void );
/*Initialize the CC1101, User can modify it*/
void CC1101Init( void );
//*****************************************************************************************
// CC1100 STROBE, CONTROL AND STATUS REGSITER
#define CC1101_IOCFG2 0x00 // GDO2 output pin configuration
#define CC1101_IOCFG1 0x01 // GDO1 output pin configuration
#define CC1101_IOCFG0 0x02 // GDO0 output pin configuration
#define CC1101_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
#define CC1101_SYNC1 0x04 // Sync word, high u8
#define CC1101_SYNC0 0x05 // Sync word, low u8
#define CC1101_PKTLEN 0x06 // Packet length
#define CC1101_PKTCTRL1 0x07 // Packet automation control
#define CC1101_PKTCTRL0 0x08 // Packet automation control
#define CC1101_ADDR 0x09 // Device address
#define CC1101_CHANNR 0x0A // Channel number
#define CC1101_FSCTRL1 0x0B // Frequency synthesizer control
#define CC1101_FSCTRL0 0x0C // Frequency synthesizer control
#define CC1101_FREQ2 0x0D // Frequency control word, high u8
#define CC1101_FREQ1 0x0E // Frequency control word, middle u8
#define CC1101_FREQ0 0x0F // Frequency control word, low u8
#define CC1101_MDMCFG4 0x10 // Modem configuration
#define CC1101_MDMCFG3 0x11 // Modem configuration
#define CC1101_MDMCFG2 0x12 // Modem configuration
#define CC1101_MDMCFG1 0x13 // Modem configuration
#define CC1101_MDMCFG0 0x14 // Modem configuration
#define CC1101_DEVIATN 0x15 // Modem deviation setting
#define CC1101_MCSM2 0x16 // Main Radio Control State Machine configuration
#define CC1101_MCSM1 0x17 // Main Radio Control State Machine configuration
#define CC1101_MCSM0 0x18 // Main Radio Control State Machine configuration
#define CC1101_FOCCFG 0x19 // Frequency Offset Compensation configuration
#define CC1101_BSCFG 0x1A // Bit Synchronization configuration
#define CC1101_AGCCTRL2 0x1B // AGC control
#define CC1101_AGCCTRL1 0x1C // AGC control
#define CC1101_AGCCTRL0 0x1D // AGC control
#define CC1101_WOREVT1 0x1E // High u8 Event 0 timeout
#define CC1101_WOREVT0 0x1F // Low u8 Event 0 timeout
#define CC1101_WORCTRL 0x20 // Wake On Radio control
#define CC1101_FREND1 0x21 // Front end RX configuration
#define CC1101_FREND0 0x22 // Front end TX configuration
#define CC1101_FSCAL3 0x23 // Frequency synthesizer calibration
#define CC1101_FSCAL2 0x24 // Frequency synthesizer calibration
#define CC1101_FSCAL1 0x25 // Frequency synthesizer calibration
#define CC1101_FSCAL0 0x26 // Frequency synthesizer calibration
#define CC1101_RCCTRL1 0x27 // RC oscillator configuration
#define CC1101_RCCTRL0 0x28 // RC oscillator configuration
#define CC1101_FSTEST 0x29 // Frequency synthesizer calibration control
#define CC1101_PTEST 0x2A // Production test
#define CC1101_AGCTEST 0x2B // AGC test
#define CC1101_TEST2 0x2C // Various test settings
#define CC1101_TEST1 0x2D // Various test settings
#define CC1101_TEST0 0x2E // Various test settings
// Strobe commands
#define CC1101_SRES 0x30 // Reset chip.
#define CC1101_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
// If in RX/TX: Go to a wait state where only the synthesizer is
// running (for quick RX / TX turnaround).
#define CC1101_SXOFF 0x32 // Turn off crystal oscillator.
#define CC1101_SCAL 0x33 // Calibrate frequency synthesizer and turn it off
// (enables quick start).
#define CC1101_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and
// MCSM0.FS_AUTOCAL=1.
#define CC1101_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if
// MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
// Only go to TX if channel is clear.
#define CC1101_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit
// Wake-On-Radio mode if applicable.
#define CC1101_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer
#define CC1101_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)
#define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high.
#define CC1101_SFRX 0x3A // Flush the RX FIFO buffer.
#define CC1101_SFTX 0x3B // Flush the TX FIFO buffer.
#define CC1101_SWORRST 0x3C // Reset real time clock.
#define CC1101_SNOP 0x3D // No operation. May be used to pad strobe commands to two
// u8s for simpler software.
#define CC1101_PARTNUM 0x30
#define CC1101_VERSION 0x31
#define CC1101_FREQEST 0x32
#define CC1101_LQI 0x33
#define CC1101_RSSI 0x34
#define CC1101_MARCSTATE 0x35
#define CC1101_WORTIME1 0x36
#define CC1101_WORTIME0 0x37
#define CC1101_PKTSTATUS 0x38
#define CC1101_VCO_VC_DAC 0x39
#define CC1101_TXBYTES 0x3A
#define CC1101_RXBYTES 0x3B
#define CC1101_PATABLE 0x3E
#define CC1101_TXFIFO 0x3F
#define CC1101_RXFIFO 0x3F
#define WRITE_BURST 0x40 //连续写入
#define READ_SINGLE 0x80 //读
#define READ_BURST 0xC0 //连续读
#define BYTES_IN_RXFIFO 0x7F //接收缓冲区的有效字节数
#define CRC_OK 0x80 //CRC校验通过位标志
#endif
cc1101.c:
/*******************************************************************************
** 文件名: cc1101.c
** 版本: 1.0
** 工作环境: RealView MDK-ARM 5
** 作者: huangyong
** 生成日期: 2017-09-18
** 功能: 获取外部flash的关于要跳转的应用程序的配置信息
** 目前外部flash的配置信息存在w25x32的第一个block(0x000000h)
** imageA地址在第二个block(0x010000h),imageB地址在第三个block(0x020000h)
** 相关文件:
** 修改日志: 2017-09-18 创建文档
*******************************************************************************/
/* 包含头文件 *****************************************************************/
#include "cc1101.h"
/* 变量 ----------------------------------------------------------------------*/
/*******************************************************************************
* @函数名称 cc1101_init
* @函数说明 初始化cc1101模块
* @输入参数 无
* @输出参数 无
* @返回参数 无
*******************************************************************************/
/*******************************************************************************
* @函数名称 cc1101_sentData
* @函数说明 cc1101模块发送数据
* @输入参数 无
* @输出参数 无
* @返回参数 无
*******************************************************************************/
/*================================================================================
Copyright : Ebyte electronic co.,LTD
Website : http://yh-ebyte.taobao.com
http://yiheliyong.cn.alibaba.com
Description : This module contains the low level operations for CC1101
================================================================================*/
//10, 7, 5, 0, -5, -10, -15, -20, dbm output power, 0x12 == -30dbm
//u8 PaTabel[] = { 0xc0, 0xC8, 0x84, 0x60, 0x68, 0x34, 0x1D, 0x0E};//433M的table
u8 PaTabel[] = { 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// Sync word qualifier mode = 30/32 sync word bits detected
// CRC autoflush = false
// Channel spacing = 199.951172
// Data format = Normal mode
// Data rate = 2.00224
// RX filter BW = 58.035714
// PA ramping = false
// Preamble count = 4
// Whitening = false
// Address config = No address check
// Carrier frequency = 400.199890
// Device address = 0
// TX power = 10
// Manchester enable = false
// CRC enable = true
// Deviation = 5.157471
// Packet length mode = Variable packet length mode. Packet length configured by the first byte after sync word
// Packet length = 255
// Modulation format = GFSK
// Base frequency = 399.999939
// Modulated = true
// Channel number = 1
// PA table
#define PA_TABLE {0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}
static const u8 CC1101InitData[24][2]=
{
/* {CC1101_IOCFG0, 0x06},
{CC1101_FIFOTHR, 0x47},
{CC1101_PKTCTRL0, 0x05},
{CC1101_CHANNR, 0x00},
{CC1101_FSCTRL1, 0x08},
{CC1101_FREQ2, 0x10},//433.92
{CC1101_FREQ1, 0xB0},
{CC1101_FREQ0, 0x3f},
// {CC1101_FREQ2, 0x10},//433.862
// {CC1101_FREQ1, 0xAf},
// {CC1101_FREQ0, 0xdf},
{CC1101_MDMCFG4, 0x5B},
{CC1101_MDMCFG3, 0xF8},
{CC1101_MDMCFG2, 0x03},
{CC1101_DEVIATN, 0x47},
{CC1101_MCSM0, 0x18},
{CC1101_FOCCFG, 0x1D},
{CC1101_WORCTRL, 0xFB},
{CC1101_FSCAL3, 0xEA},
{CC1101_FSCAL2, 0x2A},
{CC1101_FSCAL1, 0x00},
{CC1101_FSCAL0, 0x11},
{CC1101_TEST2, 0x81},
{CC1101_TEST1, 0x35},
{CC1101_MCSM1, 0x3B},*/
//2-FSK
{CC1101_IOCFG0, 0x06},
{CC1101_FIFOTHR, 0x47},
{CC1101_PKTCTRL0, 0x05},
{CC1101_CHANNR, 0x01},
{CC1101_FSCTRL1, 0x06},
{CC1101_FREQ2, 0x10}, //433.92
{CC1101_FREQ1, 0xB0},
{CC1101_FREQ0, 0x3f},
{CC1101_MDMCFG4, 0xF6},
{CC1101_MDMCFG3, 0x43}, //2.00224kBaud 58.035714khz
{CC1101_MDMCFG2, 0x03},
{CC1101_MDMCFG1, 0x20},
{CC1101_MDMCFG0, 0x00},
{CC1101_DEVIATN, 0x15}, //0x15:5.157471khz 0x34:19khz, 0x77:380.85khz,0x64:152khz,0x71:228.5khz
{CC1101_MCSM0, 0x18},
{CC1101_FOCCFG, 0x16},
{CC1101_WORCTRL, 0xFB},
{CC1101_FSCAL3, 0xE9},
{CC1101_FSCAL2, 0x2A},
{CC1101_FSCAL1, 0x00},
{CC1101_FSCAL0, 0x1F},
{CC1101_TEST2, 0x81},
{CC1101_TEST1, 0x35},
{CC1101_TEST0, 0x09},
};
/*read a byte from the specified register*/
u8 CC1101ReadReg( u8 addr );
/*Read some bytes from the rigisters continously*/
void CC1101ReadMultiReg( u8 addr, u8 *buff, u8 size );
/*Write a byte to the specified register*/
void CC1101WriteReg( u8 addr, u8 value );
/*Flush the TX buffer of CC1101*/
void CC1101ClrTXBuff( void );
/*Flush the RX buffer of CC1101*/
void CC1101ClrRXBuff( void );
/*Get received count of CC1101*/
u8 CC1101GetRXCnt( void );
/*Reset the CC1101 device*/
void CC1101Reset( void );
/*Write some bytes to the specified register*/
void CC1101WriteMultiReg( u8 addr, u8 *buff, u8 size );
/*
================================================================================
Function : CC1101WORInit( )
Initialize the WOR function of CC1101
INPUT : None
OUTPUT : None
================================================================================
*/
void CC1101WORInit( void )
{
CC1101WriteReg(CC1101_MCSM0,0x18);
CC1101WriteReg(CC1101_WORCTRL,0x78); //Wake On Radio Control
CC1101WriteReg(CC1101_MCSM2,0x00);
CC1101WriteReg(CC1101_WOREVT1,0x8C);
CC1101WriteReg(CC1101_WOREVT0,0xA0);
CC1101WriteCmd( CC1101_SWORRST );
}
/*
================================================================================
Function : CC1101ReadReg( )
read a byte from the specified register
INPUT : addr, The address of the register
OUTPUT : the byte read from the rigister
================================================================================
*/
u8 CC1101ReadReg( u8 addr )
{
u8 i;
CSN_L; //CSN = 0;
SPIx_ReadWriteByte( addr | READ_SINGLE);
i = SPIx_ReadWriteByte( 0xFF );
CSN_H;//CSN = 1;
return i;
}
/*
================================================================================
Function : CC1101ReadMultiReg( )
Read some bytes from the rigisters continously
INPUT : addr, The address of the register
buff, The buffer stores the data
size, How many bytes should be read
OUTPUT : None
================================================================================
*/
void CC1101ReadMultiReg( u8 addr, u8 *buff, u8 size )
{
u8 i, j;
CSN_L; //CSN = 0;
SPIx_ReadWriteByte( addr | READ_BURST);
for( i = 0; i < size; i ++ )
{
for( j = 0; j < 20; j ++ );
*( buff + i ) = SPIx_ReadWriteByte( 0xFF );
}
CSN_H;//CSN = 1;
}
/*
================================================================================
Function : CC1101ReadStatus( )
Read a status register
INPUT : addr, The address of the register
OUTPUT : the value read from the status register
================================================================================
*/
u8 CC1101ReadStatus( u8 addr )
{
u8 i;
CSN_L; //CSN = 0;
SPIx_ReadWriteByte( addr | READ_BURST);
i = SPIx_ReadWriteByte( 0xFF );
CSN_H;//CSN = 1;
return i;
}
/*
================================================================================
Function : CC1101SetTRMode( )
Set the device as TX mode or RX mode
INPUT : mode selection
OUTPUT : None
================================================================================
*/
void CC1101SetTRMode( TRMODE mode )
{
if( mode == TX_MODE )
{
CC1101WriteReg(CC1101_IOCFG0,0x46);
CC1101WriteCmd( CC1101_STX );
}
else if( mode == RX_MODE )
{
CC1101WriteReg(CC1101_IOCFG0,0x46);
CC1101WriteCmd( CC1101_SRX );
}
}
/*
================================================================================
Function : CC1101WriteReg( )
Write a byte to the specified register
INPUT : addr, The address of the register
value, the byte you want to write
OUTPUT : None
================================================================================
*/
void CC1101WriteReg( u8 addr, u8 value )
{
CSN_L; //CSN = 0;
SPIx_ReadWriteByte( addr );
SPIx_ReadWriteByte( value );
CSN_H;//CSN = 1;
}
/*
================================================================================
Function : CC1101WriteMultiReg( )
Write some bytes to the specified register
INPUT : addr, The address of the register
buff, a buffer stores the values
size, How many byte should be written
OUTPUT : None
================================================================================
*/
void CC1101WriteMultiReg( u8 addr, u8 *buff, u8 size )
{
u8 i;
CSN_L; //CSN = 0;
SPIx_ReadWriteByte( addr | WRITE_BURST );
for( i = 0; i < size; i ++ )
{
SPIx_ReadWriteByte( *( buff + i ) );
}
CSN_H;//CSN = 1;
}
/*
================================================================================
Function : CC1101WriteCmd( )
Write a command byte to the device
INPUT : command, the byte you want to write
OUTPUT : None
================================================================================
*/
void CC1101WriteCmd( u8 command )
{
CSN_L; //CSN = 0;
SPIx_ReadWriteByte( command );
CSN_H;//CSN = 1;
}
/*
================================================================================
Function : CC1101Reset( )
Reset the CC1101 device
INPUT : None
OUTPUT : None
================================================================================
*/
void CC1101Reset( void )
{
u8 x;
CSN_H;//CSN = 1;
CSN_L; //CSN = 0;
CSN_H;//CSN = 1;
for( x = 0; x < 100; x ++ );
CC1101WriteCmd( CC1101_SRES );
}
/*
================================================================================
Function : CC1101SetIdle( )
Set the CC1101 into IDLE mode
INPUT : None
OUTPUT : None
================================================================================
*/
void CC1101SetIdle( void )
{
CC1101WriteCmd(CC1101_SIDLE);
}
/*
================================================================================
Function : CC1101ClrTXBuff( )
Flush the TX buffer of CC1101
INPUT : None
OUTPUT : None
================================================================================
*/
void CC1101ClrTXBuff( void )
{
CC1101SetIdle();//MUST BE IDLE MODE
CC1101WriteCmd( CC1101_SFTX );
}
/*
================================================================================
Function : CC1101ClrRXBuff( )
Flush the RX buffer of CC1101
INPUT : None
OUTPUT : None
================================================================================
*/
void CC1101ClrRXBuff( void )
{
CC1101SetIdle();//MUST BE IDLE MODE
CC1101WriteCmd( CC1101_SFRX );
}
/*
================================================================================
Function : CC1101SendPacket( )
Send a packet
INPUT : txbuffer, The buffer stores data to be sent
size, How many bytes should be sent
mode, Broadcast or address check packet
OUTPUT : None
================================================================================
*/
void CC1101SendPacket( u8 *txbuffer, u8 size, TX_DATA_MODE mode )
{
u8 address;
if( mode == BROADCAST ) { address = 0; }
else if( mode == ADDRESS_CHECK ) { address = CC1101ReadReg( CC1101_ADDR ); }
CC1101ClrTXBuff( );
if( ( CC1101ReadReg( CC1101_PKTCTRL1 ) & ~0x03 ) != 0 )
{
CC1101WriteReg( CC1101_TXFIFO, size + 1 );
CC1101WriteReg( CC1101_TXFIFO, address );
}
else
{
CC1101WriteReg( CC1101_TXFIFO, size );
}
CC1101WriteMultiReg( CC1101_TXFIFO, txbuffer, size );
CC1101SetTRMode( TX_MODE );
while( GDO0 != 0 );
while( GDO0 == 0 );
CC1101ClrTXBuff( );
}
/*
================================================================================
Function : CC1101GetRXCnt( )
Get received count of CC1101
INPUT : None
OUTPUT : How many bytes hae been received
================================================================================
*/
u8 CC1101GetRXCnt( void )
{
return ( CC1101ReadStatus( CC1101_RXBYTES ) & BYTES_IN_RXFIFO );
}
/*
================================================================================
Function : CC1101SetAddress( )
Set the address and address mode of the CC1101
INPUT : address, The address byte
AddressMode, the address check mode
OUTPUT : None
================================================================================
*/
void CC1101SetAddress( u8 address, ADDR_MODE AddressMode)
{
u8 btmp = CC1101ReadReg( CC1101_PKTCTRL1 ) & ~0x03;
CC1101WriteReg(CC1101_ADDR, address);
if ( AddressMode == BROAD_ALL ) {}
else if( AddressMode == BROAD_NO ) { btmp |= 0x01; }
else if( AddressMode == BROAD_0 ) { btmp |= 0x02; }
else if( AddressMode == BROAD_0AND255 ) { btmp |= 0x03; }
}
/*
================================================================================
Function : CC1101SetSYNC( )
Set the SYNC bytes of the CC1101
INPUT : sync, 16bit sync
OUTPUT : None
================================================================================
*/
void CC1101SetSYNC( u16 sync )
{
CC1101WriteReg(CC1101_SYNC1, 0xFF & ( sync>>8 ) );
CC1101WriteReg(CC1101_SYNC0, 0xFF & sync );
}
/*
================================================================================
Function : CC1101RecPacket( )
Receive a packet
INPUT : rxBuffer, A buffer store the received data
OUTPUT : 1:received count, 0:no data
================================================================================
*/
u8 CC1101RecPacket( u8 *rxBuffer )
{
u8 status[2];
u8 pktLen;
u16 x;
if ( CC1101GetRXCnt( ) != 0 )
{
pktLen = CC1101ReadReg(CC1101_RXFIFO); // Read length byte
if( ( CC1101ReadReg( CC1101_PKTCTRL1 ) & ~0x03 ) != 0 )
{
x = CC1101ReadReg(CC1101_RXFIFO);
}
if( pktLen == 0 ) { return 0; }
else { pktLen --; }
CC1101ReadMultiReg(CC1101_RXFIFO, rxBuffer, pktLen); // Pull data
CC1101ReadMultiReg(CC1101_RXFIFO, status, 2); // Read status bytes
CC1101ClrRXBuff( );
if( status[1] & CRC_OK ) { return pktLen; }
else { return 0; }
}
else { return 0; } // Error
}
/*
================================================================================
Function : CC1101Init( )
Initialize the CC1101, User can modify it
INPUT : None
OUTPUT : None
================================================================================
*/
void CC1101Init( void )
{
volatile u8 i, j;
CC1101Reset( );
for( i = 0; i < 24; i++ )
{
CC1101WriteReg( CC1101InitData[i][0], CC1101InitData[i][1] );
}
CC1101SetAddress( 0x05, BROAD_0AND255 );
CC1101SetSYNC( 0x8799 );
CC1101WriteReg(CC1101_MDMCFG1, 0x72); //Modem Configuration
CC1101WriteMultiReg(CC1101_PATABLE, PaTabel, 8 );
//CC1101WriteReg(CC1101_FREND0,0x40);
i = CC1101ReadStatus( CC1101_PARTNUM );//for test, must be 0x80
i = CC1101ReadStatus( CC1101_VERSION );//for test, refer to the datasheet
CC1101WriteReg(CC1101_TEST1,0xaa);
i=CC1101ReadStatus(CC1101_TEST1);
i=0;
}
/*
================================================================================
------------------------------------THE END-------------------------------------
================================================================================
*/
另外附上另外一篇cc1101的文章
http://blog.163.com/chenwenbo625@126/blog/static/28838103201382942147744/
1、 木棉黑虎狼狗的专栏:
利尔达的Demo板,软件SmartRF Studio 7.0,有问题可以找寻利尔达的FAE门帮忙。
先说说GDO0和GDO2,这两个东西是搞CC1101很重要的两个东西,它连着你的单片机的IO口。因此你完全可以利用中断来判断当前的模块处于一种什么样的情况,当然这个还跟你怎么去设置IFGDO0和IFGDO2这两个寄存器有关系了,详见CC1101中文手册64页。
不过我的发送没有用中断来做,因为查询够了。当然查询也看你怎么查了,我见到过的有两种,如下:
1.先判断GDO0/GDO2(看你怎么连了)是否变高电平,然后再判断是否变低电平,这么一个过程就是发送一帧数据的过程。
2.判断CC1101的状态寄存器,这个也要看你的设置了,如果你发送完之后是IDLE状态则等待0x01如果发送完之后是接收状态则等待0x0d;
说到发送数据,这里说明一下,CC1101发送数据的时候是先发送前导码和同步字的,然后在发送FIFO数据长度、地址(如果接收端开启了地址过滤)以及FIFO中的数据。
在这里要说明一点:当时我和同事一起做这个的时候发现当低速率的时候他发送的数据我总是接收不到。原因就是我发送完之后等待IDLE的时间太短,所以数据根本就没发完就超时了。
说到寄存器,那CC1101的功能那么多,寄存器自然就很多。其实真正我们需要手动去设置的寄存器却不是很多,大多数寄存器都是SmartRF来自动生成的,在这里说说几个比较重要的寄存器:
FIFOTHR:这个主要是设置发送和接受FIFO能够放的下多少发送和接受的数据,一般来说都只要设置成0x07就可以了,因为如果你数据比较长你可以分包发送或者分包接收即可。
PKTLEN:最大数据包长度设置。
PKTCTRL1:这个寄存器如果你需要地址过滤的话那就需要开启地址过滤,还有就是如果你想在你的数据FIFO最后两个字节放上RSSI的值和LQI值以及CRC_OK的话就需要做相应的设置。
PKTCTRL0:想开启数据白化和CRC校验的话就设置一下咯,当然还有比较重的就是是否是固定长度数据包或者是可变长度数据包,区别就是固定的话那前导码和同步字后就不需要加上FIFO数据长度了,反之则需要加上FIFO数据长度。否则CC1101怎么知道你要发多少数据呢?
MCSM1:这个太重要了,决定了你发送完或者接收完数据后下一个状态是什么。
MCSM0:选择自动校准还是手动校准,听说不校准的话速率低倒关系不大,速率高了可能跑偏了影响就大了。
CC1101的寄存器初始化,是在CC1101工作这前必须做的一件事情,最主要初始化的三个参数是频率,速率,功率。最好是以结构体的方式初始化,否则当你改动速率或者频率或者功率的时候,你还要改变其他几个相关的寄存器,这样做就比较麻烦,我当初的做法是:利用SmartRF,把我需要的频率431,433,435,我需要的速率1.2K,2.4K,4.8K,10K…等等全部配置一边,然后利用截图截下SmartRF的值,然后利用这么一个结构体:
typedef struct
{
u8 IOCFG2;
u8 IOCFG1;
u8 IOCFG0;
u8 FIFOTHR;
u8 SYNC1;
u8 SYNC0;
u8 PKTLEN;
u8 PKTCTRL1;
u8 PKTCTRL0;
u8 ADDR;
u8 CHANNR;
u8 FSCTRL1;
u8 FSCTRL0;
u8 FREQ2;
u8 FREQ1;
u8 FREQ0;
u8 MDMCFG4;
u8 MDMCFG3;
u8 MDMCFG2;
u8 MDMCFG1;
u8 MDMCFG0;
u8 DEVAITN;
u8 MCSM2;
u8 MCSM1;
u8 MCSM0;
u8 FOCCFG;
u8 BSCFG;
u8 AGCCTRL2;
u8 AGCCTRL1;
u8 AGCCTRL0;
u8 WOREVT1;
u8 WOREVT0;
u8 WORCTRL;
u8 FREND1;
u8 FREND0;
u8 FSCAL3;
u8 FSCAL2;
u8 FSCAL1;
u8 FSCAL0;
u8 RCCTRL1;
u8 RCCTRL0;
u8 FSTEST;
u8 PTEST;
u8 AGCTEST;
u8 TEST2;
u8 TEST1;
u8 TEST0;
}Struct_RF_Reg;
做初始化
#if RF_BAUD_RATE == 2400
Struct_RF_Reg My_RF_Config = {
0x0B, // IOCFG2
0x2E, // IOCFG1
0x01, // IOCFG0
0x07, // FIFOTHR
0xB3, // SYNC1
0x9C, // SYNC0
0x40, // PKTLEN
0x0C, // PKTCTRL1
0x45, // PKTCTRL0
0x00, // ADDR
0x00, // CHANNR
0x06, // FSCTRL1
0x00, // FSCTRL0
#if RF_FREQUENCY == 431
0x10, // FREQ2
0x93, // FREQ1
0xB1, // FREQ0
#elif RF_FREQUENCY == 433
0x10, // FREQ2
0xA7, // FREQ1
0x62, // FREQ0
#elif RF_FREQUENCY == 435
0X10,
0XBB,
0X13,
#endif
0xF6, // MDMCFG4
0x83, // MDMCFG3
0x13, // MDMCFG2
0x22, // MDMCFG1
0xF8, // MDMCFG0
0x15, // DEVIATN
0x07, // MCSM2
0x3C, // MCSM1
0x18, // MCSM0
0x16, // FOCCFG
0x6C, // BSCFG
0x03, // AGCCTRL2
0x40, // AGCCTRL1
0x91, // AGCCTRL0
0x87, // WOREVT1
0x6B, // WOREVT0
0xFB, // WORCTRL
0x56, // FREND1
0x10, // FREND0
0xE9, // FSCAL3
0x2A, // FSCAL2
0x00, // FSCAL1
0x1F, // FSCAL0
0x41, // RCCTRL1
0x00, // RCCTRL0
0x59, // FSTEST
0x7F, // PTEST
0x3F, // AGCTEST
0x81, // TEST2
0x35, // TEST1
0x09 // TEST0
};
当然我这里只例举了2.4k的速率,其他只要改变宏定义就可以了。
最后调用一个
TI_CC_SPIWriteBurstReg(TI_CCxxx0_IOCFG2, &(RFConfig -> IOCFG2), 47);
函数就把47个寄存器都写进去了,因为这47个寄存器地址都是递增的,所以写个Burst就搞定了,不需要一个一个写那么复杂。