STM32
直播中

挽你何用

9年用户 842经验值
擅长:电源/新能源 MEMS/传感技术
私信 关注
[问答]

如何采用基于nRF24L01芯片的块两块同等级不同管脚数的STM32进行无线通信呢

如何采用基于nRF24L01芯片的块两块同等级不同管脚数STM32进行无线通信呢?

回帖(4)

李秀荣

2021-12-16 15:09:19
不同型号STM32的无线通信——基于一样的nRF24L01芯片模块


    1、实验目的

  我们主要就是让两个单片机(STM32)进行通信,并且需要采用无线的。传输内容和传输格式可以后期修改,所以最重要的就是实现单片机通信。本次实验采用两家同等级不同管脚数的STM32进行无线通信。
  2、实验硬件

  (1)nRF24L01无线模块 需要两块,一个做接收,另一个做发射。无线模块为什么没用使用WIFI模块或者其他433M等等无线模块?只是为了通信简单,成功率高些。所以本次采用了nRF24L01。
  
(2)洋桃1开发板 一个

  

  

(3)正点原子战舰开V3发板 一个


   注:


  • 我们可以采用两个一样的扳子进行通信,这样子比较容易成功,而且这样两个板子的程序是一样的。
  • 然而我们实验采用的两个不一样管脚的板子,我们在创建工程一定要注意,芯片的选择。虽然都是STM32家的芯片,都是工程创建时,芯片选择不一样,我调试卡的主要就这个原因。希望大家避免也这样。

  
  3、nRF24L01无线模块原理

(1)芯片通信采用的SPI协议
(2)nRF24L01管脚定义
  [tr]管脚管脚[/tr]
2.VCC1.GND
4.CSN3.CE
6.MOSI5.SCK
8.IRQ7.MISO
具体说明:
1.VCC 电源脚
不允许接大于3.3V电源!
2.GND 接地脚
3.CE 芯片的模式控制线
在 CSN 为低的情况下,CE 协同NRF24L01 的CONFIG 寄存器共同决定NRF24L01 的状态(参照NRF24L01 的状态机)。
4.CSN 为芯片的片选线
CSN 为低电平芯片工作
5.SCK 为芯片控制的时钟线(SPI时钟)
6.MOSI 为芯片控制数据线(Master output slave input)
主输出 从输入
7.MISO 芯片控制数据线 (Master input slave output)
master 硕士 主人 船长 slave 从属奴隶 主输入 从输出
8.IRQ 中断信号引脚
中断时变为低电平,即NRF24L01内部发生中断时IRQ 引脚从高电平变为低电平。引脚会在以下三种情况变低:Tx FIFO 发完并且收到ACK(使能ACK情况下)、Rx FIFO 收到数据、达到最大重发次数。

   注:
   
如果想了解SPI原理跟我反馈,专门编写一期的SPI原理,并且用STM32实现SPI通信。

  • nRF24L01的SPI配置原理,感兴趣的可以自行学习。

  
  4、实验代码

  该实验有两大代码,分别是杨桃家的STM32F103C8系列和正点原子STM32F103ZE系列
既然是两种系列,在编写是主要区别就是工程创建,我们下面解释两个main.c函数,其他驱动程序皆可通用.
我们的nRF24L01无线模块通信主要是SPI,下面SPI代码均可以在STM32F103系列使用,主要介绍这个代码.
STM32F103通用代码

  (1)SPI.H程序


#ifndef __SPI_H__
#define __SPI_H__


#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_spi.h"
//#include "main.h"


//SPI引脚定义
#define SPI_CLK_GPIO_PORT                        GPIOB
#define SPI_CLK_GPIO_CLK                        RCC_APB2Periph_GPIOB
#define SPI_CLK_GPIO_PIN                        GPIO_Pin_13


#define SPI_MISO_GPIO_PORT                        GPIOB
#define SPI_MISO_GPIO_CLK                        RCC_APB2Periph_GPIOB
#define SPI_MISO_GPIO_PIN                        GPIO_Pin_14


#define SPI_MOSI_GPIO_PORT                        GPIOB
#define SPI_MOSI_GPIO_CLK                        RCC_APB2Periph_GPIOB
#define SPI_MOSI_GPIO_PIN                        GPIO_Pin_15


#define SPI_NSS_GPIO_PORT                        GPIOB
#define SPI_NSS_GPIO_CLK                        RCC_APB2Periph_GPIOG
#define SPI_NSS_GPIO_PIN                        GPIO_Pin_12


#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 ))        //片选置低


//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


(2)SPI.C程序


#include "spi.h"


/** 硬件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;        //32分频
        SpiInitStructer.SPI_FirstBit = SPI_FirstBit_MSB;                                        //最高位先发送
        SpiInitStructer.SPI_CRCPolynomial = 7;                                                                //CRC多项式,默认不使用SPI自带CRC         
       
        SPI_Init( SPI_PORT, &SpiInitStructer );
        SPI_Cmd( SPI_PORT, ENABLE );
}
举报

李刚

2021-12-16 15:09:19
不同型号STM32的无线通信——基于一样的nRF24L01芯片模块


    1、实验目的

  我们主要就是让两个单片机(STM32)进行通信,并且需要采用无线的。传输内容和传输格式可以后期修改,所以最重要的就是实现单片机通信。本次实验采用两家同等级不同管脚数的STM32进行无线通信。
  2、实验硬件

  (1)nRF24L01无线模块 需要两块,一个做接收,另一个做发射。无线模块为什么没用使用WIFI模块或者其他433M等等无线模块?只是为了通信简单,成功率高些。所以本次采用了nRF24L01。
  
(2)洋桃1开发板 一个

  

  

(3)正点原子战舰开V3发板 一个


   注:


  • 我们可以采用两个一样的扳子进行通信,这样子比较容易成功,而且这样两个板子的程序是一样的。
  • 然而我们实验采用的两个不一样管脚的板子,我们在创建工程一定要注意,芯片的选择。虽然都是STM32家的芯片,都是工程创建时,芯片选择不一样,我调试卡的主要就这个原因。希望大家避免也这样。

  
  3、nRF24L01无线模块原理

(1)芯片通信采用的SPI协议
(2)nRF24L01管脚定义
  [tr]管脚管脚[/tr]
2.VCC1.GND
4.CSN3.CE
6.MOSI5.SCK
8.IRQ7.MISO
具体说明:
1.VCC 电源脚
不允许接大于3.3V电源!
2.GND 接地脚
3.CE 芯片的模式控制线
在 CSN 为低的情况下,CE 协同NRF24L01 的CONFIG 寄存器共同决定NRF24L01 的状态(参照NRF24L01 的状态机)。
4.CSN 为芯片的片选线
CSN 为低电平芯片工作
5.SCK 为芯片控制的时钟线(SPI时钟)
6.MOSI 为芯片控制数据线(Master output slave input)
主输出 从输入
7.MISO 芯片控制数据线 (Master input slave output)
master 硕士 主人 船长 slave 从属奴隶 主输入 从输出
8.IRQ 中断信号引脚
中断时变为低电平,即NRF24L01内部发生中断时IRQ 引脚从高电平变为低电平。引脚会在以下三种情况变低:Tx FIFO 发完并且收到ACK(使能ACK情况下)、Rx FIFO 收到数据、达到最大重发次数。

   注:
   
如果想了解SPI原理跟我反馈,专门编写一期的SPI原理,并且用STM32实现SPI通信。

  • nRF24L01的SPI配置原理,感兴趣的可以自行学习。

  
  4、实验代码

  该实验有两大代码,分别是杨桃家的STM32F103C8系列和正点原子STM32F103ZE系列
既然是两种系列,在编写是主要区别就是工程创建,我们下面解释两个main.c函数,其他驱动程序皆可通用.
我们的nRF24L01无线模块通信主要是SPI,下面SPI代码均可以在STM32F103系列使用,主要介绍这个代码.
STM32F103通用代码

  (1)SPI.H程序


#ifndef __SPI_H__
#define __SPI_H__


#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_spi.h"
//#include "main.h"


//SPI引脚定义
#define SPI_CLK_GPIO_PORT                        GPIOB
#define SPI_CLK_GPIO_CLK                        RCC_APB2Periph_GPIOB
#define SPI_CLK_GPIO_PIN                        GPIO_Pin_13


#define SPI_MISO_GPIO_PORT                        GPIOB
#define SPI_MISO_GPIO_CLK                        RCC_APB2Periph_GPIOB
#define SPI_MISO_GPIO_PIN                        GPIO_Pin_14


#define SPI_MOSI_GPIO_PORT                        GPIOB
#define SPI_MOSI_GPIO_CLK                        RCC_APB2Periph_GPIOB
#define SPI_MOSI_GPIO_PIN                        GPIO_Pin_15


#define SPI_NSS_GPIO_PORT                        GPIOB
#define SPI_NSS_GPIO_CLK                        RCC_APB2Periph_GPIOG
#define SPI_NSS_GPIO_PIN                        GPIO_Pin_12


#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 ))        //片选置低


//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


(2)SPI.C程序


#include "spi.h"


/** 硬件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;        //32分频
        SpiInitStructer.SPI_FirstBit = SPI_FirstBit_MSB;                                        //最高位先发送
        SpiInitStructer.SPI_CRCPolynomial = 7;                                                                //CRC多项式,默认不使用SPI自带CRC         
       
        SPI_Init( SPI_PORT, &SpiInitStructer );
        SPI_Cmd( SPI_PORT, ENABLE );
}
举报

张红玲

2021-12-16 15:09:53
/**
  * @brief :设置通信速度
  * @param :
  * @Speed:速度
  * @note  :无
  * @retval:无
  */
void NRF24L01_Set_Speed( nRf24l01SpeedType Speed )
{
uint8_t btmp = 0;

btmp = NRF24L01_Read_Reg( RF_SETUP );
btmp &= ~( ( 1<<5 ) | ( 1<<3 ) );

if( Speed == SPEED_250K ) //250K
{
btmp |= ( 1<<5 );
}
else if( Speed == SPEED_1M )   //1M
{
    btmp &= ~( ( 1<<5 ) | ( 1<<3 ) );
}
else if( Speed == SPEED_2M )   //2M
{
btmp |= ( 1<<3 );
}


NRF24L01_Write_Reg( RF_SETUP, btmp );
}


/**
  * @brief :设置功率
  * @param :
  * @Speed:速度
  * @note  :无
  * @retval:无
  */
void NRF24L01_Set_Power( nRf24l01PowerType Power )
{
    uint8_t btmp;

btmp = NRF24L01_Read_Reg( RF_SETUP ) & ~0x07;
    switch( Power )
    {
        case POWER_F18DBM:
            btmp |= PWR_18DB;
            break;
        case POWER_F12DBM:
            btmp |= PWR_12DB;
            break;
        case POWER_F6DBM:
            btmp |= PWR_6DB;
            break;
        case POWER_0DBM:
            btmp |= PWR_0DB;
            break;
        default:
            break;
    }
    NRF24L01_Write_Reg( RF_SETUP, btmp );
}


/**
  * @brief :设置频率
  * @param :
  * @FreqPoint:频率设置参数
  * @note  :值不大于127
  * @retval:无
  */
void RF24LL01_Write_Hopping_Point( uint8_t FreqPoint )
{
    NRF24L01_Write_Reg(  RF_CH, FreqPoint & 0x7F );
}


/**
  * @brief :NRF24L01检测
  * @param :无
  * @note  :无
  * @retval:无
  */
void NRF24L01_check( void )
{
uint8_t i;
uint8_t buf[5]={ 0XA5, 0XA5, 0XA5, 0XA5, 0XA5 };
uint8_t read_buf[ 5 ] = { 0 };

while( 1 )
{
NRF24L01_Write_Buf( TX_ADDR, buf, 5 ); //写入5个字节的地址
NRF24L01_Read_Buf( TX_ADDR, read_buf, 5 ); //读出写入的地址  
for( i = 0; i < 5; i++ )
{
if( buf[ i ] != read_buf[ i ] )
{
break;
}
}

if( 5 == i )
{
break;
}
else
{
//drv_uart_tx_bytes( (uint8_t *)g_ErrorString, 26 );
// OLED_ShowString(0,3,(uint8_t *)g_ErrorString,8);
}
delay_ms(1500);
}
}


/**
  * @brief :设置模式
  * @param :
  * @Mode:模式发送模式或接收模式
  * @note  :无
  * @retval:无
  */
void RF24L01_Set_Mode( nRf24l01ModeType Mode )
{
    uint8_t controlreg = 0;
controlreg = NRF24L01_Read_Reg( CONFIG );

    if( Mode == MODE_TX )      
{
controlreg &= ~( 1<< PRIM_RX );
}
    else
{
if( Mode == MODE_RX )  
{
controlreg |= ( 1<< PRIM_RX );
}
}


    NRF24L01_Write_Reg( CONFIG, controlreg );
}


/**
  * @brief :NRF24L01发送一次数据
  * @param :
  * @txbuf:待发送数据首地址
  * @Length:发送数据长度
  * @note  :无
  * @retval:
  * MAX_TX:达到最大重发次数
  * TX_OK:发送完成
  * 0xFF:其他原因
  */
uint8_t NRF24L01_TxPacket( uint8_t *txbuf, uint8_t Length )
{
uint8_t l_Status = 0;
uint16_t l_MsTimes = 0;

RF24L01_SET_CS_LOW( ); //片选
drv_spi_read_write_byte( FLUSH_TX );
RF24L01_SET_CS_HIGH( );

RF24L01_SET_CE_LOW( );
NRF24L01_Write_Buf( WR_TX_PLOAD, txbuf, Length ); //写数据到TX BUF 32字节  TX_PLOAD_WIDTH
RF24L01_SET_CE_HIGH( ); //启动发送
while( 0 != RF24L01_GET_IRQ_STATUS( ))
{
delay_ms( 1 );
if( 500 == l_MsTimes++ ) //500ms还没有发送成功,重新初始化设备
{
NRF24L01_Gpio_Init( );
RF24L01_Init( );
RF24L01_Set_Mode( MODE_TX );
break;
}
}
l_Status = NRF24L01_Read_Reg(STATUS); //读状态寄存器
NRF24L01_Write_Reg( STATUS, l_Status ); //清除TX_DS或MAX_RT中断标志

if( l_Status & MAX_TX ) //达到最大重发次数
{
NRF24L01_Write_Reg( FLUSH_TX,0xff ); //清除TX FIFO寄存器
return MAX_TX;
}
if( l_Status & TX_OK ) //发送完成
{
return TX_OK;
}

return 0xFF; //其他原因发送失败
}


/**
  * @brief :NRF24L01接收数据
  * @param :
  * @rxbuf:接收数据存放地址
  * @note  :无
  * @retval:接收的数据个数
  */
uint8_t NRF24L01_RxPacket( uint8_t *rxbuf )
{
uint8_t l_Status = 0, l_RxLength = 0, l_100MsTimes = 0;

RF24L01_SET_CS_LOW( ); //片选
drv_spi_read_write_byte( FLUSH_RX );
RF24L01_SET_CS_HIGH( );

while( 0 != RF24L01_GET_IRQ_STATUS( ))
{
delay_ms( 100 );

if( 30 == l_100MsTimes++ ) //3s没接收过数据,重新初始化模块
{
NRF24L01_Gpio_Init( );
RF24L01_Init( );
RF24L01_Set_Mode( MODE_RX );
break;
}
}

l_Status = NRF24L01_Read_Reg( STATUS ); //读状态寄存器
NRF24L01_Write_Reg( STATUS,l_Status ); //清中断标志
if( l_Status & RX_OK) //接收到数据
{
l_RxLength = NRF24L01_Read_Reg( R_RX_PL_WID ); //读取接收到的数据个数
NRF24L01_Read_Buf( RD_RX_PLOAD,rxbuf,l_RxLength ); //接收到数据
NRF24L01_Write_Reg( FLUSH_RX,0xff ); //清除RX FIFO
return l_RxLength;
}

return 0; //没有收到数据
}


/**
  * @brief :RF24L01引脚初始化
  * @param :无
  * @note  :无
  * @retval:无
  */
void NRF24L01_Gpio_Init( void )
{
GPIO_InitTypeDef RF24L01_GpioInitStructer;

RCC_APB2PeriphClockCmd( RF24L01_CE_GPIO_CLK | RF24L01_IRQ_GPIO_CLK, ENABLE ); //?? CE IRQ????  CS SCK MISO MOSI?SPI?????

//??CE?? ????
RF24L01_GpioInitStructer.GPIO_Mode = GPIO_Mode_Out_PP;
RF24L01_GpioInitStructer.GPIO_Speed = GPIO_Speed_10MHz;
RF24L01_GpioInitStructer.GPIO_Pin = RF24L01_CE_GPIO_PIN;
GPIO_Init( RF24L01_CE_GPIO_PORT, &RF24L01_GpioInitStructer );
//??
GPIO_SetBits( RF24L01_CE_GPIO_PORT, RF24L01_CE_GPIO_PIN);

//??IRQ?? ????
RF24L01_GpioInitStructer.GPIO_Mode = GPIO_Mode_IPU;
RF24L01_GpioInitStructer.GPIO_Speed = GPIO_Speed_10MHz;
RF24L01_GpioInitStructer.GPIO_Pin = RF24L01_IRQ_GPIO_PIN;
GPIO_Init( RF24L01_IRQ_GPIO_PORT, &RF24L01_GpioInitStructer );
//??
GPIO_SetBits( RF24L01_IRQ_GPIO_PORT, RF24L01_IRQ_GPIO_PIN);

RF24L01_SET_CE_LOW( ); //??24L01
RF24L01_SET_CS_HIGH( ); //??SPI??
}


/**
  * @brief :RF24L01模块初始化
  * @param :无
  * @note  :无
  * @retval:无
  */
void RF24L01_Init( void )
{
    uint8_t addr[5] = {INIT_ADDR};


    RF24L01_SET_CE_HIGH( );
    NRF24L01_Clear_IRQ_Flag( IRQ_ALL );
#if DYNAMIC_PACKET == 1


    NRF24L01_Write_Reg( DYNPD, ( 1 << 0 ) );  //使能通道1动态数据长度
    NRF24L01_Write_Reg( FEATRUE, 0x07 );
    NRF24L01_Read_Reg( DYNPD );
    NRF24L01_Read_Reg( FEATRUE );

#elif DYNAMIC_PACKET == 0
   
    L01_WriteSingleReg( L01REG_RX_PW_P0, FIXED_PACKET_LEN ); //固定数据长度

#endif //DYNAMIC_PACKET


    NRF24L01_Write_Reg( CONFIG, /*( 1<                                       ( 1 << EN_CRC ) |     //使能CRC 1个字节
                                      ( 1 << PWR_UP ) );    //开启设备
    NRF24L01_Write_Reg( EN_AA, ( 1 << ENAA_P0 ) );    //通道0自动应答
    NRF24L01_Write_Reg( EN_RXADDR, ( 1 << ERX_P0 ) ); //通道0接收
    NRF24L01_Write_Reg( SETUP_AW, AW_5BYTES );      //地址宽度 5个字节
    NRF24L01_Write_Reg( SETUP_RETR, ARD_4000US |
                        ( REPEAT_CNT & 0x0F ) );          //重复等待时间 250us
    NRF24L01_Write_Reg( RF_CH, 60 );              //初始化通道
    NRF24L01_Write_Reg( RF_SETUP, 0x26 );


    NRF24L01_Set_TxAddr( &addr[0], 5 );                      //设置TX地址
    NRF24L01_Set_RxAddr( 0, &addr[0], 5 );                   //设置RX地址
}
正点原子发射程序

  (1)MAIN.C程序


#include "sys.h"
#include "delay.h"
#include "key.h"
#include "RF24L01.h" //导入nRF24L01头文件
#include "spi.h"     //导入spi头文件


//全局数组变量
uint8_t *content = "ADCB";
uint8_t UART_BUFFER[ 10 ] = { '0','1','2','3','4','5','6','7','8','9'};


int main(void)
{   
delay_init();       //延时函数初始化   
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
LED_Init();    //初始化与LED连接的硬件接口
KEY_Init(); //按键初始化     

drv_spi_init( );
NRF24L01_Gpio_Init( );     //RF24L01引脚初始化
NRF24L01_check( );  //检测nRF24L01
    RF24L01_Init( );

while(1)
{
RF24L01_Set_Mode( MODE_TX ); //发送模式
NRF24L01_TxPacket( content , 4 ); //模式1发送固定字符,1S一包
delay_ms( 1000 );
NRF24L01_TxPacket( UART_BUFFER, 10 ); //模式1发送固定字符,1S一包
delay_ms( 1000 );
}
}
举报

丁欣如

2021-12-16 15:10:04
杨桃电子接收程序

  (1)MAIN.C程序


/*********************************************************************************************
程序名称: nRF24接收函数——基于洋桃1号开发板
编写时间: 2019年9月23日
硬件支持: STM32F103C8   外部晶振8MHz RCC函数设置主频72MHz   


修改日志:  
1——2019年9月23日              修改为nRF24L01接收函数
2——2019年9月23日 21:32       添加了数组清空函数


说明:
# 移植到不同的单片机MCU,也需要用相应的外框,不能直接用同一个工程!!!
# 本模板加载了STM32F103内部的RCC时钟设置,并加入了利用滴答定时器的延时函数。
# 可根据自己的需要增加或删减。


“本工程”适用芯片: STM32f103C8系列

线路连接:  RF24L01:  VCC        3.3V
          GND        GND
            CE         A0
IRQ        A1
                        CSN        B12
SCK        B13
MOSI       B15
MISO       B14
*********************************************************************************************/
#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "oled0561.h"
#include "delay.h"
#include "spi.h"
#include "RF24L01.h"
#include "string.h"


//声明一个数组,用来接收数据
u8 RF24L01RxBuffer[64]={0};


int main (void){//主程序
uint8_t j;


delay_ms(100); //上电时等待其他器件就绪
RCC_Configuration(); //系统时钟初始化


I2C_Configuration();//I2C初始化


OLED0561_Init(); //OLED初始化


OLED_DISPLAY_8x16_BUFFER(0,"   nRF24_RX "); //显示字符串


drv_spi_init( );
NRF24L01_Gpio_Init( );     //RF24L01引脚初始化
NRF24L01_check( );  //检测nRF24L01
    RF24L01_Init( );


RF24L01_Set_Mode( MODE_RX ); //接收模式
delay_ms(1000);


while(1)
{
j = NRF24L01_RxPacket( RF24L01RxBuffer ); //接收字节
if( 0 != j )
{
OLED_DISPLAY_8x16_BUFFER(2,"          ");//清空第二屏幕显示
OLED_DISPLAY_8x16_BUFFER(2,RF24L01RxBuffer); //显示接收数据
memset(RF24L01RxBuffer,0,sizeof(RF24L01RxBuffer));//***清空数组内容**百度找资源*
}
}
}
  5、实验现象


实验现象,就是在杨桃开发板上的OLED屏幕上面显示接收到的数据,正点原子开发板每秒接发送一组数据.
  
举报

更多回帖

发帖
×
20
完善资料,
赚取积分