STM32驱动_NRF24L01

文章目录

24l01.c

  24l01.c如下:

#include "24l01.h"
#include "delay.h"

const u8 TX_ADDRESS[TX_ADR_WIDTH] = {
    
    0xE7, 0xE7, 0xE7, 0xE7, 0xE7}; /* 本地地址 */
const u8 RX_ADDRESS[RX_ADR_WIDTH] = {
    
    0xE7, 0xE7, 0xE7, 0xE7, 0xE7}; /* 接收地址 */

#define MOSI_H GPIO_SetBits(GPIOA,   GPIO_Pin_0)
#define MOSI_L GPIO_ResetBits(GPIOA, GPIO_Pin_0)
#define SCLK_H GPIO_SetBits(GPIOA,   GPIO_Pin_1)
#define SCLK_L GPIO_ResetBits(GPIOA, GPIO_Pin_1)
#define MISO   GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)

#define NRF24L01_IRQ     (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3))
#define Set_NRF24L01_CE  {
      
      GPIO_SetBits(GPIOA, GPIO_Pin_4);}
#define Clr_NRF24L01_CE  {
      
      GPIO_ResetBits(GPIOA, GPIO_Pin_4);}
#define Set_NRF24L01_CSN {
      
      GPIO_SetBits(GPIOA, GPIO_Pin_5);}
#define Clr_NRF24L01_CSN {
      
      GPIO_ResetBits(GPIOA, GPIO_Pin_5);}

u8 SPI_ReadWriteByte ( u8 dt ) {
    
    
    u8 i;
    u8 temp = 0;

    for ( i = 8; i > 0; i-- ) {
    
    
        if ( dt & 0x80 ) {
    
    
            MOSI_H;
        } else {
    
    
            MOSI_L;
        }

        dt <<= 1;
        SCLK_H;
        temp <<= 1;

        if ( MISO ) {
    
    
            temp++;
        }

        SCLK_L;
    }

    return temp;
}

void NRF24L01_Init ( void ) {
    
    
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOA, ENABLE );
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init ( GPIOA, &GPIO_InitStructure );
    GPIO_SetBits ( GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 );
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init ( GPIOA, &GPIO_InitStructure );
    Clr_NRF24L01_CE;
    Set_NRF24L01_CSN;
}

u8 NRF24L01_Check ( void ) {
    
    
    u8 buf[5] = {
    
    0XA5, 0XA5, 0XA5, 0XA5, 0XA5};
    u8 i;
    NRF24L01_Write_Buf ( NRF24L01_WRITE_REG + TX_ADDR, buf, 5 ); /* 写入5个字节的地址 */
    NRF24L01_Read_Buf ( TX_ADDR, buf, 5 ); /* 读出写入的地址 */

    for ( i = 0; i < 5; i++ )
        if ( buf[i] != 0XA5 ) {
    
    
            break;
        }

    if ( i != 5 ) {
    
    
        return 1; /* 检测24L01错误 */
    }

    return 0; /* 检测到24L01 */
}

u8 NRF24L01_Write_Reg ( u8 reg, u8 value ) {
    
    
    u8 status;
    Clr_NRF24L01_CSN; /* 使能SPI传输 */
    status = SPI_ReadWriteByte ( reg ); /* 发送寄存器号 */
    SPI_ReadWriteByte ( value ); /* 写入寄存器的值 */
    Set_NRF24L01_CSN; /* 禁止SPI传输 */
    return ( status ); /* 返回状态值 */
}

u8 NRF24L01_Read_Reg ( u8 reg ) {
    
    
    u8 reg_val;
    Clr_NRF24L01_CSN; /* 使能SPI传输 */
    SPI_ReadWriteByte ( reg ); /* 发送寄存器号 */
    reg_val = SPI_ReadWriteByte ( 0XFF ); /* 读取寄存器内容 */
    Set_NRF24L01_CSN; /* 禁止SPI传输 */
    return ( reg_val ); /* 返回状态值 */
}

u8 NRF24L01_Read_Buf ( u8 reg, u8 *pBuf, u8 len ) {
    
    
    u8 status, u8_ctr;
    Clr_NRF24L01_CSN; /* 使能SPI传输 */
    status = SPI_ReadWriteByte ( reg ); /* 发送寄存器值(位置),并读取状态值 */

    for ( u8_ctr = 0; u8_ctr < len; u8_ctr++ ) {
    
    
        pBuf[u8_ctr] = SPI_ReadWriteByte ( 0XFF ); /* 读出数据 */
    }

    Set_NRF24L01_CSN; /* 关闭SPI传输 */
    return status; /* 返回读到的状态值 */
}

u8 NRF24L01_Write_Buf ( u8 reg, u8 *pBuf, u8 len ) {
    
    
    u8 status, u8_ctr;
    Clr_NRF24L01_CSN; /* 使能SPI传输 */
    status = SPI_ReadWriteByte ( reg ); /* 发送寄存器值(位置),并读取状态值 */

    for ( u8_ctr = 0; u8_ctr < len; u8_ctr++ ) {
    
    
        SPI_ReadWriteByte ( *pBuf++ ); /* 写入数据 */
    }

    Set_NRF24L01_CSN; /* 关闭SPI传输 */
    return status; /* 返回读到的状态值 */
}

u8 NRF24L01_TxPacket ( u8 *txbuf ) {
    
    
    u8 sta;
    delay_ms ( 50 );
    Clr_NRF24L01_CE;
    delay_ms ( 50 );
    NRF24L01_Write_Buf ( NRF24L01_WR_TX_PLOAD, txbuf, TX_PLOAD_WIDTH ); /*写数据到“TX BUF”(32个字节) */
    Set_NRF24L01_CE; /* 启动发送 */

    while ( NRF24L01_IRQ != 0 ); /* 等待发送完成 */

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

    if ( sta & MAX_TX ) {
    
     /* 达到最大重发次数 */
        NRF24L01_Write_Reg ( NRF24L01_FLUSH_TX, 0xff ); /* 清除“TX FIFO”寄存器 */
        return MAX_TX;
    }

    if ( sta & TX_OK ) {
    
     /* 发送完成 */
        return TX_OK;
    }

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

u8 NRF24L01_RxPacket ( u8 *rxbuf ) {
    
     /* 启动NRF24L01发送一次数据 */
    u8 sta;
    sta = NRF24L01_Read_Reg ( STATUS ); /* 读取状态寄存器的值 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + STATUS, sta ); /* 清除TX_DS或MAX_RT中断标志 */

    if ( sta & RX_OK ) {
    
     /* 接收到数据 */
        NRF24L01_Read_Buf ( NRF24L01_RD_RX_PLOAD, rxbuf, RX_PLOAD_WIDTH ); /* 读取数据 */
        NRF24L01_Write_Reg ( NRF24L01_FLUSH_RX, 0xff ); /* 清除“RX FIFO”寄存器 */
        return 0;
    }

    return 1; /* 没收到任何数据 */
}

void RX_Mode ( void ) {
    
     /* 初始化NRF24L01到RX模式 */
    Clr_NRF24L01_CE;
    NRF24L01_Write_Buf ( NRF24L01_WRITE_REG + RX_ADDR_P0, ( u8 * ) RX_ADDRESS, RX_ADR_WIDTH ); /* 写RX节点地址 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + EN_AA, 0x00 ); /* 使能通道0的自动应答 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + EN_RXADDR, 0x01 ); /* 使能通道0的接收地址 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + RF_CH, 40 ); /* 设置RF通信频率 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH ); /* 选择通道0的有效数据宽度 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + RF_SETUP, 0x0f ); /* 设置TX发射参数,0db增益,2Mbps,低噪声增益开启 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + CONFIG, 0x0f ); /* 配置基本工作模式的参数:PWR_UP、EN_CRC、16BIT_CRC和接收模式 */
    Set_NRF24L01_CE; /* CE为高时,进入接收模式 */
}

void TX_Mode ( void ) {
    
     /* 初始化NRF24L01到TX模式 */
    Clr_NRF24L01_CE;
    NRF24L01_Write_Buf ( NRF24L01_WRITE_REG + TX_ADDR, ( u8 * ) TX_ADDRESS, TX_ADR_WIDTH ); /* 写TX节点地址 */
    NRF24L01_Write_Buf ( NRF24L01_WRITE_REG + RX_ADDR_P0, ( u8 * ) RX_ADDRESS, RX_ADR_WIDTH ); /* 设置TX节点地址,主要为了使能ACK */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + EN_AA, 0x00 ); /* 使能通道0的自动应答 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + EN_RXADDR, 0x00 ); /* 使能通道0的接收地址 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + SETUP_RETR, 0x00 ); /* 设置自动重发间隔时间 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + RF_CH, 40 ); /* 设置RF通道为40 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + RF_SETUP, 0x0f ); /* 设置TX发射参数,0db增益,2Mbps,低噪声增益开启 */
    NRF24L01_Write_Reg ( NRF24L01_WRITE_REG + CONFIG, 0x0e ); /* 配置基本工作模式的参数:PWR_UP、EN_CRC、16BIT_CRC、接收模式和开启所有中断 */
    Set_NRF24L01_CE; /* CE为高时,10us后启动发送 */
}

24l01.h

  24l01.h如下:

#ifndef __24L01_H
#define __24L01_H
#include "sys.h"

/* NRF24L01寄存器操作命令 */
#define NRF24L01_READ_REG    0x00 /* 读配置寄存器,低5位为寄存器地址 */
#define NRF24L01_WRITE_REG   0x20 /* 写配置寄存器,低5位为寄存器地址 */
#define NRF24L01_RD_RX_PLOAD 0x61 /* 读RX有效数据,1至32字节 */
#define NRF24L01_WR_TX_PLOAD 0xA0 /* 写TX有效数据,1至32字节 */
#define NRF24L01_FLUSH_TX    0xE1 /* 清除“TX FIFO”寄存器,发射模式下用 */
#define NRF24L01_FLUSH_RX    0xE2 /* 清除“RX FIFO”寄存器,接收模式下用 */
#define NRF24L01_REUSE_TX_PL 0xE3 /* 重新使用上一包数据,当CE为高时,数据包被不断发送 */
#define NRF24L01_NOP         0xFF /* 空操作,可以用来读状态寄存器 */

/* SPI(NRF24L01)寄存器地址 */
#define CONFIG      0x00 /* 配置寄存器地址 */
#define EN_AA       0x01 /* 使能自动应答功能 */
#define EN_RXADDR   0x02 /* 接收地址允许 */
#define SETUP_AW    0x03 /* 设置地址宽度(所有数据通道) */
#define SETUP_RETR  0x04 /* 建立自动重发 */
#define RF_CH       0x05 /* RF通道 */
#define RF_SETUP    0x06 /* RF寄存器 */
#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 /* 发送地址(低字节在前),在ShockBurstTM模式下,RX_ADDR_P0与此地址相等 */
#define RX_PW_P0    0x11 /* 接收数据通道0有效数据宽度 */
#define RX_PW_P1    0x12 /* 接收数据通道1有效数据宽度 */
#define RX_PW_P2    0x13 /* 接收数据通道2有效数据宽度 */
#define RX_PW_P3    0x14 /* 接收数据通道3有效数据宽度 */
#define RX_PW_P4    0x15 /* 接收数据通道4有效数据宽度 */
#define RX_PW_P5    0x16 /* 接收数据通道5有效数据宽度 */
#define FIFO_STATUS 0x17 /* FIFO状态寄存器 */

/* 24L01发送接收数据宽度定义 */
#define TX_ADR_WIDTH    5  /* 5字节的地址宽度 */
#define RX_ADR_WIDTH    5  /* 5字节的地址宽度 */
#define TX_PLOAD_WIDTH  32 /* 20字节的用户数据宽度 */
#define RX_PLOAD_WIDTH  32 /* 20字节的用户数据宽度 */

void NRF24L01_SPI_Init ( void );
void NRF24L01_Init ( void );
void RX_Mode ( void );
void TX_Mode ( void );
u8 NRF24L01_Write_Buf ( u8 reg, u8 *pBuf, u8 u8s );
u8 NRF24L01_Read_Buf ( u8 reg, u8 *pBuf, u8 u8s );
u8 NRF24L01_Read_Reg ( u8 reg );
u8 NRF24L01_Write_Reg ( u8 reg, u8 value );
u8 NRF24L01_Check ( void );
u8 NRF24L01_TxPacket ( u8 *txbuf );
u8 NRF24L01_RxPacket ( u8 *rxbuf );
#endif

main.c

  main.c如下:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "24l01.h"

#define SEND_MESSAGE 1

#if SEND_MESSAGE

int main ( void ) {
    
    
    u8 Tx_Buf[32];
    SystemInit();
    delay_init ( 72 );
    NVIC_Configuration();
    uart_init ( 9600 );
    LED_Init();
    NRF24L01_Init();

    while ( NRF24L01_Check() ) {
    
    
        LED0 = !LED0;
        delay_ms ( 200 );
    }

    TX_Mode();
    Tx_Buf[1] = 1;

    while ( 1 ) {
    
    
        NRF24L01_TxPacket ( Tx_Buf );
        LED1 = ~LED1;
        delay_ms ( 200 );
    }
}

#else

int main ( void ) {
    
    
    u8 Rx_Buf[32];
    SystemInit();
    delay_init ( 72 );
    NVIC_Configuration();
    uart_init ( 9600 );
    LED_Init();
    NRF24L01_Init();

    while ( NRF24L01_Check() ) {
    
    
        LED1 = !LED1;
        delay_ms ( 500 );
    }

    RX_Mode();

    while ( 1 ) {
    
    
        NRF24L01_RxPacket ( Rx_Buf );

        if ( Rx_Buf[1] == 1 ) {
    
    
            LED0 = !LED0;
            delay_ms ( 300 );
        }

        Rx_Buf[1] = 0;
        delay_ms ( 500 );
    }
}

#endif

猜你喜欢

转载自blog.csdn.net/fukangwei_lite/article/details/121047902