STM32+NRF24L01收发程序

硬件平台:STM32F103+NRF24L01

nrf24l01.h

#ifndef __NRF24L01_H
#define __NRF24L01_H

extern Uchar nrfFlag;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//*********************************************NRF24L01*************************************
extern Uchar nrfWorkState;
extern Uchar g_rf_status;
extern Uchar g_rf_rx_buf[0x30];
//#define RX_DR g_rf_status^6
//#define TX_DS g_rf_status^5
//#define MAX_RT    g_rf_status^4
#define RX_DR   (g_rf_status&0x40)
#define TX_DS   (g_rf_status&0x20)
#define MAX_RT  (g_rf_status&0x10)
//24L01发送接收数据宽度定义
#define TX_ADR_WIDTH    5       //5字节的地址宽度
#define RX_ADR_WIDTH    5       //5字节的地址宽度
#define TX_PLOAD_WIDTH  6   //32字节的用户数据宽度
#define RX_PLOAD_WIDTH  6   //32字节的用户数据宽度

//Uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
//Uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG_NRF        0x00  //读配置寄存器,低5位为寄存器地址
#define WRITE_REG_NRF       0x20  //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD     0x61    // 读取接收数据指令
#define WR_TX_PLOAD     0xA0    // 写待发数据指令
#define FLUSH_TX        0xE1    // 冲洗发送 FIFO指令
#define FLUSH_RX        0xE2    // 冲洗接收 FIFO指令
#define REUSE_TX_PL     0xE3    // 定义重复装载数据指令
#define NOP             0xFF    // 保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA           0x01  // 自动应答功能设置
#define EN_RXADDR       0x02  // 可用信道设置
#define SETUP_AW        0x03  // 收发地址宽度设置
#define SETUP_RETR      0x04  // 自动重发功能设置
#define RF_CH           0x05  // 工作频率设置
#define RF_SETUP        0x06  // 发射速率、功耗功能设置
#define STATUS          0x07  // 状态寄存器

#define MAX_TX          0x10  //达到最大发送次数中断
#define TX_OK           0x20  //TX发送完成中断
#define RX_OK           0x40  //接收到数据中断

#define OBSERVE_TX      0x08  // 发送监测功能
#define CD              0x09  // 地址检测
#define RX_ADDR_P0      0x0A  // 频道0接收数据地址
#define RX_ADDR_P1      0x0B  // 频道1接收数据地址
#define RX_ADDR_P2      0x0C  // 频道2接收数据地址
#define RX_ADDR_P3      0x0D  // 频道3接收数据地址
#define RX_ADDR_P4      0x0E  // 频道4接收数据地址
#define RX_ADDR_P5      0x0F  // 频道5接收数据地址
#define TX_ADDR         0x10  // 发送地址寄存器
#define RX_PW_P0        0x11  // 接收频道0接收数据长度
#define RX_PW_P1        0x12  // 接收频道0接收数据长度
#define RX_PW_P2        0x13  // 接收频道0接收数据长度
#define RX_PW_P3        0x14  // 接收频道0接收数据长度
#define RX_PW_P4        0x15  // 接收频道0接收数据长度
#define RX_PW_P5        0x16  // 接收频道0接收数据长度
#define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
//**************************************************************************************
//////////////////////////////////////////////////////////////////////////////////////////////////////////

extern void NRF_IRQ_Init(void);
extern void NRF24L01_Init(void);//初始化
extern void NRF24L01_RX_Mode(void);//配置为接收模式
extern void NRF24L01_TX_Mode(void);//配置为发送模式
extern Uchar NRF24L01_Write_Buf(Uchar reg, Uchar *pBuf, Uchar Uchars);//写数据区
extern Uchar NRF24L01_Read_Buf(Uchar reg, Uchar *pBuf, Uchar Uchars);//读数据区
extern Uchar NRF24L01_Read_Reg(Uchar reg);          //读寄存器
extern Uchar NRF24L01_Write_Reg(Uchar reg, Uchar value);//写寄存器
extern Uchar NRF24L01_Check(void);//检查24L01是否存在
extern Uchar NRF24L01_TxPacket(Uchar *txbuf);//发送一个包的数据
extern Uchar NRF24L01_RxPacket(Uchar *rxbuf);//接收一个包的数据
extern void NRF24L01_CheckRecvData(void);
#endif

nrf24l01.c

Uchar nrfFlag;
Uchar nrfWorkState;
Uchar g_rf_status;                                                              // RF状态寄存器的值
Uchar g_rf_rx_buf[0x30];

Uchar TX_ADDRESS[TX_ADR_WIDTH]={0x01,0x02,0x03,0x04,0xA5};      // 定义RF接收应用地址
Uchar RX_ADDRESS[TX_ADR_WIDTH]= {0x01,0x02,0x03,0x04,0xA6};         // 定义RF发送工厂地址
Uchar RX_ADDRESS_APP[TX_ADR_WIDTH]= {0x01,0x02,0x03,0x04,0xA6};         // 定义RF接收工厂地址

//SPI写寄存器
//reg:指定寄存器地址
//value:写入的值
extern Uchar NRF24L01_Write_Reg(Uchar reg,Uchar value)
{
    Uchar status;
    SPISemGet();
    //NRF24L01_CSN=0;                 //使能SPI传输
    NRF24L01_CSN_Low();
    status =SPI_FLASH_SendByte(reg);//发送寄存器号
    SPI_FLASH_SendByte(value);      //写入寄存器的值
    //NRF24L01_CSN=1;                 //禁止SPI传输
    NRF24L01_CSN_High();
    SPISemPut();
    return(status);                 //返回状态值
}
//读取SPI寄存器值
//reg:要读的寄存器
extern Uchar NRF24L01_Read_Reg(Uchar reg)
{
    Uchar reg_val;
    SPISemGet();         
    NRF24L01_CSN_Low();  //使能SPI传输
    SPI_FLASH_SendByte(reg);   //发送寄存器号
    reg_val=SPI_FLASH_SendByte(0XFF);//读取寄存器内容
    NRF24L01_CSN_High();  //禁止SPI传输
    SPISemPut();
    return(reg_val);           //返回状态值
}
//在指定位置读出指定长度的数据
//reg:寄存器(位置)
//*pBuf:数据指针
//len:数据长度
//返回值,此次读到的状态寄存器值
extern Uchar NRF24L01_Read_Buf(Uchar reg,Uchar *pBuf,Uchar len)
{
    Uchar status,Uchar_ctr;
    NRF24L01_CSN_Low();  //使能SPI传输
    status=SPI_FLASH_SendByte(reg);//发送寄存器值(位置),并读取状态值
    for(Uchar_ctr=0;Uchar_ctr<len;Uchar_ctr++)pBuf[Uchar_ctr]=SPI_FLASH_SendByte(0XFF);//读出数据
    //NRF24L01_CSN=1;       //关闭SPI传输
    NRF24L01_CSN_High();
    return status;        //返回读到的状态值
}
//在指定位置写指定长度的数据
//reg:寄存器(位置)
//*pBuf:数据指针
//len:数据长度
//返回值,此次读到的状态寄存器值
extern Uchar NRF24L01_Write_Buf(Uchar reg, Uchar *pBuf, Uchar len)
{
    Uchar status,Uchar_ctr;

    NRF24L01_CSN_Low(); //使能SPI传输
    status = SPI_FLASH_SendByte(reg);//发送寄存器值(位置),并读取状态值
    for(Uchar_ctr=0; Uchar_ctr<len; Uchar_ctr++)SPI_FLASH_SendByte(*pBuf++); //写入数据

    NRF24L01_CSN_High();   //关闭SPI传输

    return status;          //返回读到的状态值
}


//检测24L01是否存在
//返回值:0,成功;1,失败
extern Uchar NRF24L01_Check(void)
{
    Uchar buf[TX_ADR_WIDTH];

    //NRF24L01_Write_Buf(WRITE_REG_NRF+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);//写入5个字节的地址.
#ifdef  NRF_MODE_SEND
    NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址
#else
    NRF24L01_Read_Buf(RX_ADDR_P0,buf,5); //读出写入的地址
#endif
//  DEBUGBUFFER("NRF24L01_Check", buf, 5);
#ifdef  NRF_MODE_SEND
    if (Buffercmp(TX_ADDRESS, buf, RX_ADR_WIDTH) == PASSED)
#else
    if (Buffercmp(RX_ADDRESS, buf, RX_ADR_WIDTH) == PASSED)
#endif
    {
        nrfWorkState = 1;
        return 1;//检测24L01错误
    }

    nrfWorkState = 0;
    return 0;        //检测到24L01
}

//启动NRF24L01发送一次数据
//txbuf:待发送数据首地址
//返回值:发送完成状况
extern Uchar NRF24L01_TxPacket(Uchar *txbuf)
{
    NRF24L01_Write_Reg(FLUSH_TX,0); // 清除TX的FIFO
    NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF  32个字节

    return 0;//其他原因发送失败
}
//启动NRF24L01发送一次数据
//txbuf:待发送数据首地址
//返回值:0,接收完成;其他,错误代码
extern Uchar NRF24L01_RxPacket(Uchar *rxbuf)
{
    Uchar state = 0;

    state=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值
    NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,state); //清除TX_DS或MAX_RT中断标志

    if(state&RX_OK)//接收到数据
    {
        NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
        NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
        return 0;
    }

    return 1;//没收到任何数据
}
//该函数初始化NRF24L01到RX模式
//设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR
//当CE变高后,即进入RX模式,并可以接收数据了
extern void NRF24L01_RX_Mode(void)
{
    NRF24L01_CE_Low();
    NRF24L01_Write_Reg(WRITE_REG_NRF + CONFIG, 0x0f);       // 上电, CRC为2 bytes,接收模式,允许RX_DR产生中断
    NRF24L01_CE_High();
}
//该函数初始化NRF24L01到TX模式
//设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR
//PWR_UP,CRC使能
//当CE变高后,即进入RX模式,并可以接收数据了
//CE为高大于10us,则启动发送.
extern void NRF24L01_TX_Mode(void)
{
    NRF24L01_CE_Low();
    //设置接收包数据长度
    NRF24L01_Write_Reg(WRITE_REG_NRF + RX_PW_P0, TX_PLOAD_WIDTH);   // PIPE0 接收数据包长度
    NRF24L01_Write_Reg(WRITE_REG_NRF+CONFIG,0x0e);    //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
    NRF24L01_CE_High();
}

extern void NRF24L01_CheckRecvData(void)
{
    Uchar buf[0x40];

    if(NRF24L01_RxPacket(buf)==0)//一旦接收到信息,则显示出来.
    {
        DEBUGBUFFER("NRF24L01 RECV", buf, 32);
    }
}


//初始化24L01的IO口
extern void NRF24L01_Init(void)
{
#ifdef NRF_MODE_SEND
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin  = PIN_NRF24L01_IRQ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //IRQ 输入
    GPIO_Init(PORT_NRF24L01_IRQ, &GPIO_InitStructure);
#else
    NRF_IRQ_Init();
#endif
    //NRF24L01_CE=0;            //使能24L01
//  NRF24L01_CSN=1;         //SPI片选取消
    NRF24L01_CE_Low();
    NRF24L01_CSN_High();

    NRF24L01_Write_Buf(WRITE_REG_NRF + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);  // 设置发射地址及长度
    NRF24L01_Write_Buf(WRITE_REG_NRF + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);   // 设置接收地址及长度
    NRF24L01_Write_Buf(WRITE_REG_NRF + RX_ADDR_P1, RX_ADDRESS_APP, RX_ADR_WIDTH);   // 设置接收地址及长度


    //SPI_Write_Reg(WRITE_REG + EN_AA, 0x01);                           // 启动自动应答功能
    NRF24L01_Write_Reg(WRITE_REG_NRF+ EN_AA, 0x00);                             // 关闭自动应答功能

    //SPI_Write_Reg(WRITE_REG + EN_RXADDR, 0x01);                       // PIPE0接收数据
    NRF24L01_Write_Reg(WRITE_REG_NRF + EN_RXADDR, 0x03);                        // PIPE0,PIPE1接收数据

    //SPI_Write_Reg(WRITE_REG + SETUP_RETR, 0x1a);                      // 自动重传10次
    NRF24L01_Write_Reg(WRITE_REG_NRF + SETUP_RETR, 0x00);                       // 禁止重传

    NRF24L01_Write_Reg(WRITE_REG_NRF + RF_CH, 40);                              // RF频率2440MHz
    //SPI_Write_Reg(WRITE_REG + RF_SETUP, 0x0f);                        // 发射功率0dBm, 传输速率2Mbps,
    NRF24L01_Write_Reg(WRITE_REG_NRF + RF_SETUP, 0x27);                         // 发射功率0dBm, 传输速率250kbps,

    NRF24L01_Write_Reg(WRITE_REG_NRF + RX_PW_P0, TX_PLOAD_WIDTH);               // PIPE0 接收数据包长度
    NRF24L01_Write_Reg(WRITE_REG_NRF + RX_PW_P1, TX_PLOAD_WIDTH);               // PIPE1 接收数据包长度

}

extern void NRF_IRQ_Init(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* Connect EXTI Line to GPIO Pin */
    GPIO_EXTILineConfig(PORT_SRC_NRF_IRQ, PIN_SRC_NRF_IRQ);

    /* Configure EXTI line */
    EXTI_InitStructure.EXTI_Line = EXTI_LINE_NRF_IRQ;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /* Enable and set EXTI Interrupt to the highest priority */
    NVIC_InitStructure.NVIC_IRQChannel = EXIT_IRQN_NRF_IRQ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    EXTI_ClearITPendingBit(EXTI_LINE_NRF_IRQ);
//  EXTI_GenerateSWInterrupt(EXTI_LINE_PFO);    // test
}

extern void EXTI1_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_LINE_NRF_IRQ) != RESET)
    {
        EXTI_ClearITPendingBit(EXTI_LINE_NRF_IRQ);
        if (!nrfFlag)
        {
            nrfFlag = 1;
        }

        g_rf_status=NRF24L01_Read_Reg(STATUS);                                  // 读出状态值

        if(RX_DR){
            NRF24L01_Read_Buf(RD_RX_PLOAD,g_rf_rx_buf,RX_PLOAD_WIDTH);          // 读出FIFO的数据
            NRF24L01_Write_Reg(FLUSH_RX,0);                                     // 清除RX的FIFO
        }

        NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,0x70);                              // 清除所有中断标志

    }
}

1.做主机时初始化相关流程

NRF24L01_Init();
NRF24L01_TX_Mode();

发送数据

u8 recvData[TX_PLOAD_WIDTH]={数据};
NRF24L01_TxPacket(recvData); 

2.做从机时初始化相关流程

NRF24L01_Init();
NRF24L01_RX_Mode();

每收到一次有效数据发生一次中断

g_rf_status=NRF24L01_Read_Reg(STATUS);                                  // 读出状态值

        if(RX_DR){
            NRF24L01_Read_Buf(RD_RX_PLOAD,g_rf_rx_buf,RX_PLOAD_WIDTH);          // 读出FIFO的数据
            NRF24L01_Write_Reg(FLUSH_RX,0);                                     // 清除RX的FIFO
            //DEBUGBUFFER("NRF", g_rf_rx_buf, TX_PLOAD_WIDTH);
        }

        NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,0x70);  
  • 25
    点赞
  • 140
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值