STM32
直播中

刘浩

7年用户 1050经验值
私信 关注
[问答]

STM32与NRF24L01是怎样通过arduino库进行通信的

STM32与NRF24L01是怎样通过arduino库进行通信的?

回帖(1)

李旭彤

2021-12-16 16:06:43
       关于NRF24L01,arduino有很多库,但是用和32通讯的时候遇到了问题,信道和地址一样也无法通讯,有些库也不知道怎么改信道和地址,所以直接移植了32上的代码。具体代码如下
  
#define uint unsigned int
#define uchar unsigned char

#define TX_ADDR_WITDH 5//发送地址宽度设置为5个字节
#define RX_ADDR_WITDH 5
#define TX_DATA_WITDH 32
#define RX_DATA_WITDH 32
#define R_REGISTER    0x00  // 读寄存器
#define W_REGISTER    0x20  // 写寄存器
#define R_RX_PLOAD    0x61  // 读RX FIFO有效数据,1-32字节,当读数据完成后,数据被清除,应用于接收模式
#define W_TX_PLOAD    0xA0  // 写TX FIFO有效数据,1-32字节,写操作从字节0开始,应用于发射模式
#define FLUSH_TX    0xE1  // 清除TX FIFO寄存器,应用于发射模式
#define FLUSH_RX    0xE2  // 清除RX FIFO寄存器,应用于接收模式
#define REUSE_TX_PL 0xE3  // 重新使用上一包有效数据,当CE为高过程中,数据包被不断的重新发射
#define NOP         0xFF  // 空操作,可以用来读状态寄存器
/******************************************************************
// nRF24L01寄存器地址
*******************************************************************/
#define CONFIG      0x00  // 配置寄存器
#define EN_AA       0x01  // “自动应答”功能寄存器
#define EN_RX_ADDR  0x02  // 接收通道使能寄存器
#define SETUP_AW    0x03  // 地址宽度设置寄存器
#define SETUP_RETR  0x04  // 自动重发设置寄存器
#define RF_CH       0x05  // 射频通道频率设置寄存器
#define RF_SETUP    0x06  // 射频设置寄存器
#define STATUS      0x07  // 状态寄存器
#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  // 数据通道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状态寄存器
//*********************************************************************************
uchar  sta;    // 状态变量
#define RX_DR  (sta & 0x40)  // 接收成功中断标志
#define TX_DS  (sta & 0x20)  // 发射成功中断标志
#define MAX_RT (sta & 0x10)  // 重发溢出中断标志
#define ADC_Mid 2100
int CE = 9;
int CSN = 10;
int IRQ = 8;
//int SCK = 13;
//int MOSI = 11;
//int MISO = 12;  这几个引脚是硬件固定的,无法更改
uchar TX_Addr[]={0x42,0x42,0x42,0x42,0x42};
uchar RX_Addr[]={0x41,0x41,0x41,0x41,0x41};
uchar TX_Buffer[]={0xfe,100,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar RX_Buffer[RX_DATA_WITDH];
char flag=0;
int data_x;
unsigned long df=0;
unsigned long t=0;   
void nRF24L01_Init(void)
{
    delay(2);
    digitalWrite(CE,LOW);
    digitalWrite(CSN,HIGH);
    digitalWrite(SCK,LOW);
//    digitalWrite(MOSI,LOW);
//    digitalWrite(MISO,LOW);
    digitalWrite(IRQ,HIGH);
}

uchar SPI_RW(uchar byte)
{
    uchar i;
    for(i=0;i<8;i++)
    {
        if(byte&0x80)
            digitalWrite(MOSI,HIGH);
        else
            digitalWrite(MOSI,LOW);
        byte<<=1;
        digitalWrite(SCK,HIGH);
        if(digitalRead(MISO))
     //     Serial.println(10);
            byte|=0x01;
        digitalWrite(SCK,LOW);
    }
    return byte;
}

uchar SPI_W_Reg(uchar reg,uchar value)
{
    uchar status;
    digitalWrite(CSN,LOW);
    status=SPI_RW(reg);
    SPI_RW(value);
    digitalWrite(CSN,HIGH);
    return status;
}

uchar SPI_R_byte(uchar reg)
{
    uchar status;
    digitalWrite(CSN,LOW);
    SPI_RW(reg);
    status=SPI_RW(0);
    digitalWrite(CSN,HIGH);
    return status;
}

uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)
{
    uchar reg_value,i;
    digitalWrite(CSN,LOW);
    reg_value=SPI_RW(reg);
    for(i=0;i     {
        Dat_Buffer=SPI_RW(0);
    }
    digitalWrite(CSN,HIGH);
    return reg_value;
}

uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)
{
    uchar reg_value,i;
    digitalWrite(CSN,LOW);
    reg_value=SPI_RW(reg);
    for(i=0;i     {
        SPI_RW(TX_Dat_Buffer);
    }
    digitalWrite(CSN,HIGH);
    return reg_value;   
}


void nRF24L01_Set_TX_Mode(uchar *TX_Data)
{
       digitalWrite(CE,LOW);//待机(写寄存器之前一定要进入待机模式或掉电模式)
       SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);/*写寄存器指令+接收节点地址+地址宽度*/
       SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);/*为了接收设备应答信号,接收通道0地址与发送地址相同*/
       SPI_W_DBuffer(W_TX_PLOAD,TX_Data,TX_DATA_WITDH);/*写有效数据地址+有效数据+有效数据宽度*/
       SPI_W_Reg(W_REGISTER+EN_AA,0x01);/*接收通道0自动应答*/
       SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);/*使能接收通道0*/
       SPI_W_Reg(W_REGISTER+SETUP_RETR,0x1a);/*自动重发延时250US+86US,重发10次*/
       SPI_W_Reg(W_REGISTER+RF_CH,40);/*(2400)MHZ射频通道* 40是信道*/
       SPI_W_Reg(W_REGISTER+RF_SETUP,0x0f);/*1Mbps速率,发射功率:0DBM,低噪声放大器增益*/
       SPI_W_Reg(W_REGISTER+CONFIG,0x0e);/*发送模式,上电,16位CRC校验,CRC使能*/
       digitalWrite(CE,HIGH);
       delay(5);
}


uchar Check_Ack(void)
{
sta=SPI_R_byte(R_REGISTER+STATUS);
if(TX_DS||MAX_RT)
{
SPI_W_Reg(W_REGISTER+STATUS,0xff);
digitalWrite(CSN,LOW);
SPI_RW(FLUSH_TX);
digitalWrite(CSN,HIGH);
return 0;
}
else
return 1;
}


uchar Check_Rec(void)
{
    uchar status;
    sta=SPI_R_byte(R_REGISTER+STATUS);
    if(RX_DR)
   {
    digitalWrite(CE,LOW);
    SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);
    status=1;
    }
    SPI_W_Reg(W_REGISTER+STATUS,0xff);
    return status;
}




void nRF24L01_Set_RX_Mode(void)
{
    digitalWrite(CE,LOW);//待机
    //SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);
    SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,RX_Addr,RX_ADDR_WITDH);
    SPI_W_Reg(W_REGISTER+EN_AA,0x01);//auot ack
    SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);
    //SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0a);
    SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH);
    SPI_W_Reg(W_REGISTER+RF_CH,40);
    SPI_W_Reg(W_REGISTER+RF_SETUP,0x0f);//0db,lna
    SPI_W_Reg(W_REGISTER+CONFIG,0x0f);
     
    digitalWrite(CE,HIGH);
    delay(5);
}

uchar nRF24L01_RX_Data(void)
{
//  uchar i,status;
    sta=SPI_R_byte(R_REGISTER+STATUS);
    if(RX_DR)
    {
        digitalWrite(CE,LOW);
        SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);
        SPI_W_Reg(W_REGISTER+STATUS,0xff);
        digitalWrite(CSN,LOW);
        SPI_RW(FLUSH_RX);
        digitalWrite(CSN,HIGH);
        return 1;
    }
    else
        return 0;
     
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(CE,OUTPUT);
  pinMode(CSN,OUTPUT);
  pinMode(SCK,OUTPUT);
  pinMode(MOSI,OUTPUT);
  pinMode(MISO,INPUT);
}


void loop() {
  // put your main code here, to run repeatedly:
  //Serial.println(10);
  unsigned char i = 0,b=0;
  delay(1);
  nRF24L01_Init();
    while(1)
    {   
        nRF24L01_Set_RX_Mode();
        //delay(4);
        //delayMicroseconds(4);
        if(nRF24L01_RX_Data()) //当接收到数据时
        {


              nRF24L01_Set_TX_Mode(&TX_Buffer[1]);//发送数据
               nRF24L01_Set_RX_Mode();
         
        }
    }
}
举报

更多回帖

×
20
完善资料,
赚取积分