242|3

7

帖子

0

TA的资源

一粒金砂(中级)

CC1101芯片如何做到收发一体 既可以发送也可以接收 单独收发是没有问题的 软件SPI [复制链接]

本帖最后由 沉睡毛毛虫 于 2024-11-22 18:10 编辑

#include "config.h"                // Device header

#ifndef __USE_SOFT_SPI_INTERFACE__

/** 硬件SPI */
#define SPI_WAIT_TIMEOUT			((uint16_t)0xFFFF)

/**
  * @brief   :SPI初始化(硬件)
  * @param :无
  * @note  :无
  * @retval:无
  */ 
void drv_spi_init( void )
{
	GPIO_InitTypeDef	SpiGpioInitStructer;
	SPI_InitTypeDef		SpiInitStructer;
	
	/** SPI引脚配置 */
	RCC_APB2PeriphClockCmd(SPI_CLK_GPIO_CLK | SPI_MISO_GPIO_CLK | SPI_MOSI_GPIO_CLK | SPI_NSS_GPIO_CLK, ENABLE );	//打开端口时钟
	
	//SCK MOSI MISO 配置为复用
	SpiGpioInitStructer.GPIO_Speed = GPIO_Speed_10MHz;
	SpiGpioInitStructer.GPIO_Mode = GPIO_Mode_AF_PP;
	
	SpiGpioInitStructer.GPIO_Pin = SPI_CLK_GPIO_PIN;
	GPIO_Init( SPI_CLK_GPIO_PORT, &SpiGpioInitStructer );		//初始化SCK
	
	SpiGpioInitStructer.GPIO_Pin = SPI_MOSI_GPIO_PIN;
	GPIO_Init( SPI_MOSI_GPIO_PORT, &SpiGpioInitStructer );		//初始化MOSI
	
	SpiGpioInitStructer.GPIO_Pin = SPI_MISO_GPIO_PIN;
	GPIO_Init( SPI_MISO_GPIO_PORT, &SpiGpioInitStructer );		//初始化MISO
	
	//NSS配置为推挽输出
	SpiGpioInitStructer.GPIO_Mode = GPIO_Mode_Out_PP;
	SpiGpioInitStructer.GPIO_Pin = SPI_NSS_GPIO_PIN;
	GPIO_Init( SPI_NSS_GPIO_PORT, &SpiGpioInitStructer );		//初始化NSS
	GPIO_SetBits( SPI_NSS_GPIO_PORT, SPI_NSS_GPIO_PIN );		//置高

	/** SPI配置 */
	SPI_I2S_DeInit( SPI_PORT );			//复位SPI
	
	if( SPI1 == SPI_PORT )				
	{
		RCC_APB2PeriphClockCmd( SPI_PORT_CLK, ENABLE );			//SPI1在APB2上,打开相应SPI时钟
	}
	else
	{
		RCC_APB1PeriphClockCmd( SPI_PORT_CLK, ENABLE );			//SPI2 3在APB1上
	}
	
	SPI_Cmd( SPI_PORT, DISABLE );		//关闭SPI外设,配置前关闭
	
	SpiInitStructer.SPI_Direction = SPI_Direction_2Lines_FullDuplex;	//双线全双工
	SpiInitStructer.SPI_Mode = SPI_Mode_Master;							//主机模式
	SpiInitStructer.SPI_CPOL = SPI_CPOL_Low;							//空闲状态为低电平 
	SpiInitStructer.SPI_CPHA = SPI_CPHA_1Edge;							//第一个边沿采集数据
	SpiInitStructer.SPI_DataSize = SPI_DataSize_8b;						//8位数据
	SpiInitStructer.SPI_NSS = SPI_NSS_Soft;								//从机软件管理
	SpiInitStructer.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;	//64分频
	SpiInitStructer.SPI_FirstBit = SPI_FirstBit_MSB;					//最高位先发送
	SpiInitStructer.SPI_CRCPolynomial = 7;								//CRC多项式,默认不使用SPI自带CRC	 
	
	SPI_Init( SPI_PORT, &SpiInitStructer );
	SPI_Cmd( SPI_PORT, ENABLE );
}

/**
  * @brief :SPI收发一个字节
  * @param :
  *			@TxByte: 发送的数据字节
  * @note  :非堵塞式,一旦等待超时,函数会自动退出
  * @retval:接收到的字节
  */
uint8_t drv_spi_read_write_byte( uint8_t TxByte )
{
	uint8_t l_Data = 0;
	uint16_t l_WaitTime = 0;
	
	while( RESET == SPI_I2S_GetFlagStatus( SPI_PORT, SPI_I2S_FLAG_TXE ) )		//等待发送缓冲区为空
	{
		if( SPI_WAIT_TIMEOUT == ++l_WaitTime )
		{
			break;			//如果等待超时则退出
		}
	}
	l_WaitTime = SPI_WAIT_TIMEOUT / 2;		//重新设置接收等待时间(因为SPI的速度很快,正常情况下在发送完成之后会立即收到数据,等待时间不需要过长)
	SPI_PORT->DR = TxByte;	//发送数据
	
	while( RESET == SPI_I2S_GetFlagStatus( SPI_PORT, SPI_I2S_FLAG_RXNE ) )		//等待接收缓冲区非空
	{
		if( SPI_WAIT_TIMEOUT == ++l_WaitTime )
		{
			break;			//如果等待超时则退出
		}
	}
	
	l_Data = (uint8_t)SPI_PORT->DR;		//读取接收数据
	
	return l_Data;		//返回
}

/**
  * @brief :SPI收发字符串
  * @param :
  *			@ReadBuffer: 接收数据缓冲区地址
  *			@WriteBuffer:发送字节缓冲区地址
  *			@Length:字节长度
  * @note  :非堵塞式,一旦等待超时,函数会自动退出
  * @retval:无
  */
void drv_spi_read_write_string( uint8_t* ReadBuffer, uint8_t* WriteBuffer, uint16_t Length )
{
	GPIO_ResetBits( SPI_NSS_GPIO_PORT, SPI_NSS_GPIO_PIN);			//拉低片选
	while( Length-- )
	{
		*ReadBuffer = drv_spi_read_write_byte( *WriteBuffer );		//收发数据
		ReadBuffer++;
		WriteBuffer++;				//读写地址加1
	}
	GPIO_SetBits( SPI_NSS_GPIO_PORT, SPI_NSS_GPIO_PIN);				//拉高片选
}

/** 硬件SPI */
#endif






#ifdef __USE_SOFT_SPI_INTERFACE__

/** 软件SPI */


/**
  * @brief :SPI初始化(软件)
  * @param :无
  * @note  :无
  * @retval:无
  */
void drv_spi_init( void )
{
	GPIO_InitTypeDef	SpiGpioInitStructer;
	
	/** SPI引脚配置 */
	RCC_APB2PeriphClockCmd( SPI_CLK_GPIO_CLK | SPI_MISO_GPIO_CLK | SPI_MOSI_GPIO_CLK | SPI_NSS_GPIO_CLK, ENABLE );	//打开端口时钟
	
	//SCK MOSI NSS配置为推挽输出
	SpiGpioInitStructer.GPIO_Speed = GPIO_Speed_10MHz;
	SpiGpioInitStructer.GPIO_Mode = GPIO_Mode_Out_PP;
	
	SpiGpioInitStructer.GPIO_Pin = SPI_CLK_GPIO_PIN;
	GPIO_Init( SPI_CLK_GPIO_PORT, &SpiGpioInitStructer );		//初始化SCK
	GPIO_ResetBits( SPI_CLK_GPIO_PORT, SPI_CLK_GPIO_PIN);		//初始化状态设置为低
	
	SpiGpioInitStructer.GPIO_Pin = SPI_MOSI_GPIO_PIN;
	GPIO_Init( SPI_MOSI_GPIO_PORT, &SpiGpioInitStructer );		//初始化MOSI
	GPIO_SetBits( SPI_MOSI_GPIO_PORT, SPI_MOSI_GPIO_PIN);		//初始化状态设置为高
	
	SpiGpioInitStructer.GPIO_Pin = SPI_NSS_GPIO_PIN;
	GPIO_Init( SPI_NSS_GPIO_PORT, &SpiGpioInitStructer );		//初始化NSS
	GPIO_SetBits( SPI_NSS_GPIO_PORT, SPI_NSS_GPIO_PIN);			//初始化状态设置为高
	
	//初始化MISO 上拉输入
	SpiGpioInitStructer.GPIO_Mode = GPIO_Mode_IPU;
	SpiGpioInitStructer.GPIO_Pin = SPI_MISO_GPIO_PIN;
	GPIO_Init( SPI_MISO_GPIO_PORT, &SpiGpioInitStructer );		
	GPIO_SetBits( SPI_MISO_GPIO_PORT, SPI_MISO_GPIO_PIN);		//初始化状态设置为高
}

/**
  * @brief :SPI收发一个字节
  * @param :
  *			@TxByte: 发送的数据字节
  * @note  :非堵塞式,一旦等待超时,函数会自动退出
  * @retval:接收到的字节
  */
uint8_t drv_spi_read_write_byte( uint8_t TxByte )
{
	uint8_t i = 0, Data = 0;
	
	spi_set_clk_low( );
	
	for( i = 0; i < 8; i++ )			//一个字节8byte需要循环8次
	{
		/** 发送 */
		if( 0x80 == ( TxByte & 0x80 ))
		{
			spi_set_mosi_hight( );		//如果即将要发送的位为 1 则置高IO引脚
		}
		else
		{
			spi_set_mosi_low( );		//如果即将要发送的位为 0 则置低IO引脚
		}
		TxByte <<= 1;					//数据左移一位,先发送的是最高位
		
		spi_set_clk_high( );			//时钟线置高
		__nop( );
		__nop( );
		
		/** 接收 */
		Data <<= 1;						//接收数据左移一位,先接收到的是最高位
		if( 1 == spi_get_miso( ))
		{
			Data |= 0x01;				//如果接收时IO引脚为高则认为接收到 1
		}
		
		spi_set_clk_low( );				//时钟线置低
		__nop( );
		__nop( );
	}
	
	return Data;		//返回接收到的字节
}

/**
  * @brief :SPI收发字符串
  * @param :
  *			@ReadBuffer: 接收数据缓冲区地址
  *			@WriteBuffer:发送字节缓冲区地址
  *			@Length:字节长度
  * @note  :非堵塞式,一旦等待超时,函数会自动退出
  * @retval:无
  */
void drv_spi_read_write_string( uint8_t* ReadBuffer, uint8_t* WriteBuffer, uint16_t Length )
{
	spi_set_nss_low( );			//片选拉低
	
	while( Length-- )
	{
		*ReadBuffer = drv_spi_read_write_byte( *WriteBuffer );		//收发数据
		ReadBuffer++;
		WriteBuffer++;			//读写地址加1
	}
	
	spi_set_nss_high( );		//片选拉高
}


/** 软件SPI */
#endif
#ifndef __SPI_H
#define __SPI_H


//#define 	__CC1101_TX_TEST__							//**@@ 如果测试发送功能则需要定义该宏,如果测试接收则需要屏蔽该宏 **@@//
#define 	__USE_SOFT_SPI_INTERFACE__					//**@@ 如果使用软件SPI则需要定义该宏,反之如果使用硬件SPI则需要屏蔽该宏 **@@//


/** 发送模式定义 */
enum
{
	TX_MODE_1 = 0,		//发送模式1,发送固定的字符串
	TX_MODE_2			//发送模式2,发送串口接收到的数据
};


//SPI引脚定义
#define SPI_CLK_GPIO_PORT			GPIOA                   //PA5
#define SPI_CLK_GPIO_CLK			RCC_APB2Periph_GPIOA
#define SPI_CLK_GPIO_PIN			GPIO_Pin_5

#define SPI_MISO_GPIO_PORT		GPIOA
#define SPI_MISO_GPIO_CLK			RCC_APB2Periph_GPIOA    //PA6
#define SPI_MISO_GPIO_PIN			GPIO_Pin_6

#define SPI_MOSI_GPIO_PORT		GPIOA
#define SPI_MOSI_GPIO_CLK			RCC_APB2Periph_GPIOA    //PA4
#define SPI_MOSI_GPIO_PIN			GPIO_Pin_4

#define SPI_NSS_GPIO_PORT			GPIOB
#define SPI_NSS_GPIO_CLK			RCC_APB2Periph_GPIOB    //PB1
#define SPI_NSS_GPIO_PIN			GPIO_Pin_1


#define spi_set_nss_high( )			SPI_NSS_GPIO_PORT->ODR |= SPI_NSS_GPIO_PIN								//片选置高
#define spi_set_nss_low( )			SPI_NSS_GPIO_PORT->ODR &= (uint32_t)( ~((uint32_t)SPI_NSS_GPIO_PIN ))	//片选置低



#ifdef __USE_SOFT_SPI_INTERFACE__			/** 只有使用软件SPI才需要的封装 */			

#define spi_set_clk_high( )			SPI_CLK_GPIO_PORT->ODR |= SPI_CLK_GPIO_PIN								//时钟置高
#define spi_set_clk_low( )			SPI_CLK_GPIO_PORT->ODR &= (uint32_t)( ~((uint32_t)SPI_CLK_GPIO_PIN ))	//时钟置低

#define spi_set_mosi_hight( )		SPI_MOSI_GPIO_PORT->ODR |= SPI_MOSI_GPIO_PIN							//发送脚置高
#define spi_set_mosi_low( )			SPI_MOSI_GPIO_PORT->ODR &= (uint32_t)( ~((uint32_t)SPI_MOSI_GPIO_PIN ))	//发送脚置低

#define spi_get_miso( )				(( SPI_MISO_GPIO_PORT->IDR & (uint32_t)SPI_MISO_GPIO_PIN) != SPI_MISO_GPIO_PIN ) ? 0 : 1 // 若相应输入位为低则得到0,相应输入位为高则得到1


void drv_spi_init( void );
uint8_t drv_spi_read_write_byte( uint8_t TxByte );
void drv_spi_read_write_string( uint8_t* ReadBuffer, uint8_t* WriteBuffer, uint16_t Length );


#else									/** 只有使用硬件SPI时会使用 */


//SPI接口定义
#define SPI_PORT					  SPI2						//SPI接口
#define SPI_PORT_CLK				RCC_APB1Periph_SPI2			//SPI时钟


void drv_spi_init( void );
uint8_t drv_spi_read_write_byte(uint8_t TxByte );
void drv_spi_read_write_string(uint8_t* ReadBuffer,uint8_t* WriteBuffer, uint16_t Length );

#endif



#endif

/**
  ******************************************************************************
  * @author  泽耀科技 ASHINING
  * @version V3.0
  * @date    2016-10-08
  * @brief   NRF24L01配置C文件
  ******************************************************************************
  * @attention
  *
  * 官网	:	http://www.ashining.com
  * 淘宝	:	https://shop105912646.taobao.com
  * 阿里巴巴:	https://cdzeyao.1688.com
  ******************************************************************************
  */
  
  
  
#include "config.h"

//10, 7, 5, 0, -5, -10, -15, -20, dbm output power, 0x12 == -30dbm
//const uint8_t PaTabel[ ] = { 0xc0, 0xC8, 0x84, 0x60, 0x68, 0x34, 0x1D, 0x0E};
const uint8_t PaTabel[ ] = { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
static const uint8_t CC1101InitData[ 22 ][ 2 ]= 
{
  { CC1101_IOCFG0,      0x06 },
  { CC1101_FIFOTHR,     0x47 },
  { CC1101_PKTCTRL0,    0x05 },
  { CC1101_CHANNR,      0x96 },	//430M
  { CC1101_FSCTRL1,     0x06 },
  { CC1101_FREQ2,       0x0F },
  { CC1101_FREQ1,       0x62 },
  { CC1101_FREQ0,       0x76 },
  { CC1101_MDMCFG4,     0xF6 },
  { CC1101_MDMCFG3,     0x43 },
  { CC1101_MDMCFG2,     0x13 },
  { CC1101_DEVIATN,     0x15 },
  { 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_MCSM1,       0x3B },
};


/**
  * @brief :CC1101写命令
  * @param :
  *			@Command:命令
  * @note  :无
  * @retval:无
  */
void CC1101_Write_Cmd( uint8_t Command )
{
    CC1101_SET_CSN_LOW( );					//SPI片选,本工程中该函数都是用作SPI片选
	
    drv_spi_read_write_byte( Command );		//写命令
	
    CC1101_SET_CSN_HIGH( );					//SPI取消片选,本工程中该函数都是用作取消SPI片选					
}

/**
  * @brief :CC1101写寄存器
  * @param :
  *			@Addr:地址
  *			@WriteValue:写入的数据字节
  * @note  :无
  * @retval:无
  */
void CC1101_Write_Reg( uint8_t Addr, uint8_t WriteValue )
{
	CC1101_SET_CSN_LOW( );					
	
    drv_spi_read_write_byte( Addr );		//写地址
    drv_spi_read_write_byte( WriteValue );	//写数据
	
    CC1101_SET_CSN_HIGH( );					
}

/**
  * @brief :CC1101连续写寄存器
  * @param :
  *			@Addr:地址
  *			@pWriteBuff:写入的数据串首地址
  *			@WriteSize:写入的数据个数
  * @note  :无
  * @retval:无
  */
void CC1101_Write_Multi_Reg( uint8_t Addr, uint8_t *pWriteBuff, uint8_t WriteSize )
{
    uint8_t i;
	
    CC1101_SET_CSN_LOW( );					
	
    drv_spi_read_write_byte( Addr | WRITE_BURST );	//连续写命令 及首地址
    for( i = 0; i < WriteSize; i ++ )
    {
        drv_spi_read_write_byte( *( pWriteBuff + i ) );	//连续写入数据
    }
	
    CC1101_SET_CSN_HIGH( );					
}

/**
  * @brief :CC1101读寄存器
  * @param :
  *			@Addr:地址
  * @note  :无
  * @retval:寄存器值
  */
uint8_t CC1101_Read_Reg( uint8_t Addr )
{
    uint8_t l_RegValue = 0;
	
    CC1101_SET_CSN_LOW( );
	
    drv_spi_read_write_byte( Addr | READ_SINGLE );	//单独读命令 及地址
    l_RegValue = drv_spi_read_write_byte( 0xFF );	//读取寄存器
	
    CC1101_SET_CSN_HIGH( );
	
    return l_RegValue;
}

/**
  * @brief :CC1101读一个寄存器状态
  * @param :
  *			@Addr:地址
  * @note  :无
  * @retval:寄存器状态
  */
uint8_t CC1101_Read_Status( uint8_t Addr )
{
    uint8_t l_RegStatus = 0;
	
    CC1101_SET_CSN_LOW( );
	
    drv_spi_read_write_byte( Addr | READ_BURST );	//连续读命令 及地址
    l_RegStatus = drv_spi_read_write_byte( 0xFF );	//读取状态
	
    CC1101_SET_CSN_HIGH( );
	
    return l_RegStatus;
}

/**
  * @brief :CC1101连续读寄存器
  * @param :
  *			@Addr:地址
  *			@pReadBuff:读取数据存放首地址
  *			@ReadSize:读取数据的个数
  * @note  :无
  * @retval:无
  */
void CC1101_Read_Multi_Reg( uint8_t Addr, uint8_t *pReadBuff, uint8_t ReadSize )
{
    uint8_t i = 0, j = 0;
	
    CC1101_SET_CSN_LOW( );
	
    drv_spi_read_write_byte( Addr | READ_BURST);	//连续读命令 及首地址
    for( i = 0; i < ReadSize; i ++ )
    {
        for( j = 0; j < 20; j ++ );
        *( pReadBuff + i ) = drv_spi_read_write_byte( 0xFF );	//连续读取数据
    }
	
    CC1101_SET_CSN_HIGH( );
}

/**
  * @brief :CC1101发送接收模式设置
  * @param :
  *			@Mode:TX_MODE,发送模式 RX_MODE,接收模式
  * @note  :无
  * @retval:寄存器状态
  */
void CC1101_Set_Mode( CC1101_ModeType Mode )
{
    if( Mode == TX_MODE )			//发送模式
    {
        CC1101_Write_Reg(CC1101_IOCFG0,0x46);
        CC1101_Write_Cmd(CC1101_STX );		
    }
    else if(Mode== RX_MODE)		//接收模式
    {
        CC1101_Write_Reg(CC1101_IOCFG0,0x46);
        CC1101_Write_Cmd(CC1101_SRX );
    }
	
	while(0!=CC1101_GET_GDO0_STATUS( ));		//等待发送 或 接收开始
}

/**
  * @brief :CC1101进入空闲模式
  * @param :无
  * @note  :无
  * @retval:无
  */ 
void CC1101_Set_Idle_Mode( void )
{
    CC1101_Write_Cmd( CC1101_SIDLE );
}

/**
  * @brief :CC1101初始化WOR功能
  * @param :无
  * @note  :无
  * @retval:无
  */ 
void C1101_WOR_Init( void )
{
    CC1101_Write_Reg(CC1101_MCSM0,0x18);		
    CC1101_Write_Reg(CC1101_WORCTRL,0x78); 
    CC1101_Write_Reg(CC1101_MCSM2,0x00);
    CC1101_Write_Reg(CC1101_WOREVT1,0x8C);
    CC1101_Write_Reg(CC1101_WOREVT0,0xA0);
	CC1101_Write_Cmd( CC1101_SWORRST );		//写入WOR命令
}

/**
  * @brief :CC1101设置地址
  * @param :
  *			@Address:设置的设备地址值
  *			@AddressMode:地址检测模式
  * @note  :无
  * @retval:无
  */
void CC1101_Set_Address( uint8_t Address, CC1101_AddrModeType AddressMode)
{
    uint8_t btmp = 0;
	
	btmp = CC1101_Read_Reg( CC1101_PKTCTRL1 ) & ~0x03;	//读取CC1101_PKTCTRL1寄存器初始值
    CC1101_Write_Reg( CC1101_ADDR, Address );			//设置设备地址
	
    if( AddressMode == BROAD_ALL )     { }				//不检测地址
    else if( AddressMode == BROAD_NO  )
	{ 
		btmp |= 0x01;									//检测地址 但是不带广播
	}
    else if( AddressMode == BROAD_0   )
	{ 
		btmp |= 0x02;									//0x00为广播
	}
    else if( AddressMode == BROAD_0AND255 ) 
	{
		btmp |= 0x03; 									//0x00 0xFF为广播
	} 

	CC1101_Write_Reg( CC1101_PKTCTRL1, btmp);			//写入地址模式	
}

/**
  * @brief :CC1101设置同步字段
  * @param :无
  * @note  :无
  * @retval:无
  */
void CC1101_Set_Sync( uint16_t Sync )
{
    CC1101_Write_Reg( CC1101_SYNC1, 0xFF & ( Sync >> 8 ) );
    CC1101_Write_Reg( CC1101_SYNC0, 0xFF & Sync ); 	//写入同步字段 16Bit
}

/**
  * @brief :CC1101清空发送缓冲区
  * @param :无
  * @note  :无
  * @retval:无
  */ 
void CC1101_Clear_TxBuffer( void )
{
    CC1101_Set_Idle_Mode( );					//首先进入IDLE模式
    CC1101_Write_Cmd(CC1101_SFTX);			//写入清发送缓冲区命令		
}

/**
  * @brief :CC1101清空接收缓冲区
  * @param :无
  * @note  :无
  * @retval:无
  */
void CC1101_Clear_RxBuffer( void )
{
    CC1101_Set_Idle_Mode();				   //首先进入IDLE模式
    CC1101_Write_Cmd(CC1101_SFRX );			//写入清接收缓冲区命令
}

/**
  * @brief :CC1101发送数据包
  * @param :
  *			@pTxBuff:发送数据缓冲区
  *			@TxSize:发送数据长度
  *			@DataMode:数据模式
  * @note  :无
  * @retval:无
  */ 
void CC1101_Tx_Packet(uint8_t *pTxBuff, uint8_t TxSize, CC1101_TxDataModeType DataMode )
{
    uint8_t Address;
	uint16_t l_RxWaitTimeout = 0;
	
    if( DataMode == BROADCAST )             
	{
		Address = 0; 
	}
    else if( DataMode == ADDRESS_CHECK )    
	{ 
		Address = CC1101_Read_Reg( CC1101_ADDR ); 
	}

    CC1101_Clear_TxBuffer( );
    
    if(( CC1101_Read_Reg(CC1101_PKTCTRL1) & 0x03 ) != 0 )	
    {
        CC1101_Write_Reg(CC1101_TXFIFO,TxSize + 1 );		
        CC1101_Write_Reg(CC1101_TXFIFO,Address );			//写入长度和地址 由于多一个字节地址此时长度应该加1
    }
    else
    {
        CC1101_Write_Reg( CC1101_TXFIFO, TxSize );			//只写长度 不带地址
    }

    CC1101_Write_Multi_Reg( CC1101_TXFIFO, pTxBuff, TxSize );	//写入数据
    CC1101_Set_Mode(TX_MODE);								//发送模式
	
	while( 0 == CC1101_GET_GDO0_STATUS( ))		//等待发送完成
	{
		delay_ms( 1 );
		if(1000 == l_RxWaitTimeout++ )
		{
			l_RxWaitTimeout = 0;
			CC1101_Init( );
			break; 
		} 
	}
	
}

/**
  * @brief :CC1101读取接收到的字节数
  * @param :无
  * @note  :无
  * @retval:接收到的数据个数
  */
uint8_t CC1101_Get_RxCounter( void )
{
    return ( CC1101_Read_Status( CC1101_RXBYTES ) & BYTES_IN_RXFIFO );	
}

/**
  * @brief :CC1101接收数据包
  * @param :
  *			@RxBuff:发送数据缓冲区
  * @note  :无
  * @retval:接收到的字节数,0表示无数据
  */
uint8_t CC1101_Rx_Packet(uint8_t *RxBuff )
{
	uint8_t l_PktLen = 0;
    uint8_t l_Status[ 2 ] = { 0 };
	uint16_t l_RxWaitTimeout = 0;

	while(0==CC1101_GET_GDO0_STATUS( ))		//等待接收完成
	{
		delay_ms(1);
		if( 3000 == l_RxWaitTimeout++ )
		{
			l_RxWaitTimeout = 0;
			CC1101_Init( );
			break; 
		} 
	}

    if(0!= CC1101_Get_RxCounter( ))
    {
        l_PktLen = CC1101_Read_Reg( CC1101_RXFIFO );           // 获取长度信息
		
		if( ( CC1101_Read_Reg( CC1101_PKTCTRL1 ) & 0x03 ) != 0 )
        {
           CC1101_Read_Reg( CC1101_RXFIFO );					//如果数据包中包含地址信息 ,则读取地址信息
        }
        if( l_PktLen == 0 )           
		{
			return 0;			//无数据
		}
        else 
		{
			l_PktLen--; 		//减去一个地址字节
		}
        CC1101_Read_Multi_Reg( CC1101_RXFIFO, RxBuff, l_PktLen ); 	//读取数据
        CC1101_Read_Multi_Reg( CC1101_RXFIFO, l_Status, 2 );		//读取数据包最后两个额外字节,后一个为CRC标志位

        CC1101_Clear_RxBuffer( );

        if( l_Status[ 1 ] & CRC_OK )
		{   
			return l_PktLen; 
		}
        else
		{   
			return 0; 
		}
    }
    else   
	{  
		return 0; 
	}                              
}

/**
  * @brief :CC1101复位
  * @param :无
  * @note  :无
  * @retval:无
  */
void CC1101_Reset( void )
{
	CC1101_SET_CSN_HIGH( );
	CC1101_SET_CSN_LOW( );
	CC1101_SET_CSN_HIGH( );
	delay_us(40);				
	CC1101_Write_Cmd(CC1101_SRES);
}

/**
  * @brief :CC1101引脚初始化
  * @param :无
  * @note  :无
  * @retval:无
  */ 
void CC1101_Gpio_Init( void )
{
	GPIO_InitTypeDef	GpioInitStructer;
	
	//使能口线时钟
	RCC_APB2PeriphClockCmd(CC1101_GDO0_GPIO_CLK|CC1101_GDO2_GPIO_CLK, ENABLE );	//打开端口时钟
	
	//GDO0 GDO2配置为上拉输入
	GpioInitStructer.GPIO_Speed = GPIO_Speed_10MHz;	
	GpioInitStructer.GPIO_Mode = GPIO_Mode_IPU;							
	GpioInitStructer.GPIO_Pin = CC1101_GDO0_GPIO_PIN;		
	GPIO_Init( CC1101_GDO0_GPIO_PORT, &GpioInitStructer );	
	
	GpioInitStructer.GPIO_Pin = CC1101_GDO2_GPIO_PIN;		
	GPIO_Init( CC1101_GDO2_GPIO_PORT, &GpioInitStructer );
}

/**
  * @brief :CC1101初始化
  * @param :无
  * @note  :无
  * @retval:无
  */
void CC1101_Init( void )
{
	uint8_t i = 0;

	CC1101_Gpio_Init( );		//引脚初始化
	CC1101_Reset( );    		//模块复位

	for( i = 0; i < 22; i++ )
	{
		CC1101_Write_Reg( CC1101InitData[0], CC1101InitData[1] );	//写入配置参数
	}
	CC1101_Set_Address( 0x05, BROAD_0AND255 );		//写入设备地址 和地址模式
	CC1101_Set_Sync( 0x8799 );						//写入同步字段
	CC1101_Write_Reg(CC1101_MDMCFG1, 0x72 );			//调制解调器配置

	CC1101_Write_Multi_Reg(CC1101_PATABLE,(uint8_t*)PaTabel,8);	
}
/**
  ******************************************************************************
  * @author  泽耀科技 ASHINING
  * @version V3.0
  * @date    2016-10-08
  * @brief   NRF24L01配置H文件
  ******************************************************************************
  * @attention
  *
  * 官网	:	http://www.ashining.com
  * 淘宝	:	https://shop105912646.taobao.com
  * 阿里巴巴:	https://cdzeyao.1688.com
  ******************************************************************************
  */
  
  
#ifndef __CC1101_H__
#define __CC1101_H__



#define PA_TABLE 						{0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}

/** CC1101硬件接口定义 */
#define CC1101_GDO0_GPIO_PORT			GPIOB                  //PB0
#define CC1101_GDO0_GPIO_CLK			RCC_APB2Periph_GPIOB
#define CC1101_GDO0_GPIO_PIN			GPIO_Pin_0

#define CC1101_GDO2_GPIO_PORT			GPIOA                  //PA7
#define CC1101_GDO2_GPIO_CLK			RCC_APB2Periph_GPIOA
#define CC1101_GDO2_GPIO_PIN			GPIO_Pin_7

#define CC1101_CSN_GPIO_PORT			SPI_NSS_GPIO_PORT			 //PB1
#define CC1101_CSN_GPIO_CLK				SPI_NSS_GPIO_CLK
#define CC1101_CSN_GPIO_PIN				SPI_NSS_GPIO_PIN



/** 口线操作函数定义 */
#define CC1101_SET_CSN_HIGH( )			spi_set_nss_high( )
#define CC1101_SET_CSN_LOW( )			spi_set_nss_low( )

#define CC1101_GET_GDO0_STATUS( )		(( CC1101_GDO0_GPIO_PORT->IDR & (uint32_t)CC1101_GDO0_GPIO_PIN) != CC1101_GDO0_GPIO_PIN ) ? 0 : 1	//GDO0状态
#define CC1101_GET_GDO2_STATUS( )		(( CC1101_GDO2_GPIO_PORT->IDR & (uint32_t)CC1101_GDO2_GPIO_PIN) != CC1101_GDO2_GPIO_PIN ) ? 0 : 1	//GDO2状态

/** 枚举量定义 */
typedef enum 
{ 
	TX_MODE, 
	RX_MODE 
}CC1101_ModeType;

typedef enum 
{ 
	BROAD_ALL, 
	BROAD_NO, 
	BROAD_0, 
	BROAD_0AND255 
}CC1101_AddrModeType;

typedef enum 
{ 
	BROADCAST, 
	ADDRESS_CHECK
} CC1101_TxDataModeType;


void CC1101_Write_Cmd( uint8_t Command );
void CC1101_Write_Reg( uint8_t Addr, uint8_t WriteValue );
void CC1101_Write_Multi_Reg( uint8_t Addr, uint8_t *pWriteBuff, uint8_t WriteSize );
uint8_t CC1101_Read_Reg( uint8_t Addr );
void CC1101_Read_Multi_Reg( uint8_t Addr, uint8_t *pReadBuff, uint8_t ReadSize );
uint8_t CC1101_Read_Status( uint8_t Addr );
void CC1101_Set_Mode( CC1101_ModeType Mode );
void CC1101_Set_Idle_Mode( void );
void C1101_WOR_Init( void );
void CC1101_Set_Address( uint8_t Address, CC1101_AddrModeType AddressMode);
void CC1101_Set_Sync( uint16_t Sync );
void CC1101_Clear_TxBuffer( void );
void CC1101_Clear_RxBuffer( void );
void CC1101_Tx_Packet( uint8_t *pTxBuff, uint8_t TxSize, CC1101_TxDataModeType DataMode );
uint8_t CC1101_Get_RxCounter( void );
uint8_t CC1101_Rx_Packet( uint8_t *RxBuff );
void CC1101_Reset( void );
void CC1101_Init( void );
void CC1101_Gpio_Init( void );

#endif

/**
  ******************************************************************************
  * @author  泽耀科技 ASHINING
  * @version V3.0
  * @date    2016-10-08
  * @brief   CC1101寄存器 命令定义H文件
  ******************************************************************************
  * @attention
  *
  * 官网    :    http://www.ashining.com
  * 淘宝    :    https://shop105912646.taobao.com
  * 阿里巴巴:    https://cdzeyao.1688.com
  ******************************************************************************
  */



#ifndef __DRV_CC1101_REG_H__
#define __DRV_CC1101_REG_H__


/** CC1101寄存器定义 */

#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 INT8U
#define CC1101_SYNC0        0x05        // Sync word, low INT8U
#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 INT8U
#define CC1101_FREQ1        0x0E        // Frequency control word, middle INT8U
#define CC1101_FREQ0        0x0F        // Frequency control word, low INT8U
#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 INT8U Event 0 timeout
#define CC1101_WOREVT0      0x1F        // Low INT8U 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

// 命令
#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
                                        // INT8Us 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



/*********************************************************************************
*    模块名称 : 
*    文件名称 : 
*    版    本 : V1.0
*    说    明 : 
*
*    修改记录 :
*                  日期        作者           说明
*    Copyright (C), 2020-2030, 
*
***********************************************************************************/
////////////////////////////////////////////////////////////////////
//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//           佛祖保佑       永无BUG     永不修改                  //
////////////////////////////////////////////////////////////////////

/* USER CODE END Header 
编写说明:                
******************************************************************************/
/*******************************************************************************
//更新日志


********************************************************************************/
#include "config.h"
const char *g_Ashining = "88888888";
uint8_t g_RF24L01RxBuffer[ 32 ] = { 0 }; 

 int main(void)
 {    
        u16 i=0;
        delay_init();                                        //初始化  
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);      //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        
        TIM_Init();                                          //初始化
        KEY_Init();                                          //初始化
        LED_Init();
     
        uart_init(115200);                                   //9位数据 TXD上传上位机指令
        uart2_init(115200);                                  //8位数据 RXD上位机指令
       
        //SPI初始化
        drv_spi_init( );

        //CC1101初始化
        //CC1101_Init( );
        for( i = 0; i < 6; i++ )
        {
            led_red_flashing( );
            led_green_flashing( );
            delay_ms(500);
        }

        while(1)
        {   
            
//          CC1101_Tx_Packet((uint8_t *)g_Ashining,8,ADDRESS_CHECK );        //模式1发送固定字符,1S一包
//            delay_ms(500);
//            delay_ms(500);    
//            led_red_flashing( );

//            CC1101_Clear_RxBuffer( );
//            CC1101_Set_Mode(RX_MODE );
//            i = CC1101_Rx_Packet(g_RF24L01RxBuffer);        //接收字节
//            if(0!=i)
//            {
//                led_green_flashing( );
//                uart_send_string(g_RF24L01RxBuffer,i);    //输出接收到的字节
//            }
    
        }
 }

 
 
 
 
 

 
 
 
 

 

此帖出自stm32/stm8论坛

最新回复

半双工的,也就是说同一时间,要么是发射,要么是接收。发射和接收不能同时进行。。   详情 回复 发表于 2024-11-24 13:12

回复
举报

6636

帖子

0

TA的资源

五彩晶圆(高级)

硬件连接需要注意的是,根据任务需求要将CC1101的引脚连接到主设备的不同管脚上。这包括MISO(主设备输入/从设备输出)、MOSI(主设备输出/从设备输入)、SCLK(时钟)和CS(片选)等信号线。

此帖出自stm32/stm8论坛

回复

2971

帖子

0

TA的资源

五彩晶圆(中级)

半双工的,也就是说同一时间,要么是发射,要么是接收。发射和接收不能同时进行。。

此帖出自stm32/stm8论坛

回复

7

帖子

0

TA的资源

一粒金砂(中级)

谢谢 搞懂了

此帖出自stm32/stm8论坛

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表