stm32f103c8 使用cc1101模块

背景

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就搞定了,不需要一个一个写那么复杂。

好的,我可以为您提供一些参考和建议。 首先,您需要了解STM32F103C8T6的GPIO和定时器的使用方法,以及超声波模块的工作原理。超声波模块通常具有两个引脚:一个是触发引脚,用于发送超声波信号;另一个是回波引脚,用于接收超声波信号。 以下是一个简单的程序示例,可用于测量超声波到达物体的距离: ```c #include "stm32f10x.h" #define TRIG_PIN GPIO_Pin_0 #define TRIG_PORT GPIOA #define ECHO_PIN GPIO_Pin_1 #define ECHO_PORT GPIOA void delay_us(uint32_t us) { SysTick->LOAD = us * 9; SysTick->VAL = 0; SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0); SysTick->CTRL = 0; } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); GPIO_InitStructure.GPIO_Pin = TRIG_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(TRIG_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = ECHO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(ECHO_PORT, &GPIO_InitStructure); TIM_DeInit(TIM2); TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM2, &TIM_ICInitStructure); NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM2, ENABLE); TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); while(1) { GPIO_SetBits(TRIG_PORT, TRIG_PIN); delay_us(10); GPIO_ResetBits(TRIG_PORT, TRIG_PIN); while(GPIO_ReadInputDataBit(ECHO_PORT, ECHO_PIN) == RESET); TIM_SetCounter(TIM2, 0); while(GPIO_ReadInputDataBit(ECHO_PORT, ECHO_PIN) == SET); uint16_t pulse_width = TIM_GetCapture2(TIM2); float distance = pulse_width / 58.0; // do something with distance } } void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET) { TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); } } ``` 这段代码将在PA0引脚连接超声波模块的触发引脚,PA1引脚连接超声波模块的回波引脚。当触发引脚输出一个10微秒的高电平脉冲时,超声波模块将发送超声波信号,然后等待回波信号。 在回波信号到达时,将触发TIM2的输入捕获中断,计算回波信号的脉冲宽度,并将其转换为距离(单位为厘米)。您可以根据需要修改代码以处理距离数据。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值