⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nrf24l01.c

📁 STM32F RFID通讯源代码(支持双向发送接收)
💻 C
字号:

#include "stm32f10x_lib.h"
#include "arm_comm.h"
#include "nRF24L01.h"
#include "const.h"

#define CSN_TIME      2
#define CE_HIGH_TIME  10000

unsigned char RX_ADDRESS_P0[5]  = {5,6,7,8,9};
unsigned char RX_ADDRESS_P1[5]  = {0,1,2,3,4};
unsigned char TX_ADDRESS[5]     = {5,6,7,8,9};
unsigned char ADDRESS[5];

unsigned char status;

// just simple delay
void sDelay (unsigned long a) { while (--a!=0); }


// Chip Select -> high
void CSN_HIGH (void)  { GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET); }
// Chip Select -> low
void CSN_LOW (void)   { sDelay(CSN_TIME); GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET); }

// Chip enable High
void CE_HIGH(void)    { GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);  sDelay(CE_HIGH_TIME); }
// Chip enable low
void CE_LOW(void)     { GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET); }


// Init SPI0 Interface
void SPI1Init (void) {

  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  // Enable SPI1 and GPIOA clocks
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);

  // Configure SPI1 pins: NSS, SCK, MISO and MOSI
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // Reset SPI Interface
  SPI_DeInit(SPI1);

  // SPI1 configuration
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStructure);

  // Enable SPI1
  SPI_Cmd(SPI1, ENABLE);

  // Chip select - output
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // Chip enable - output
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  // IRQ pin - input
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  // Button B1
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  // Button WAKE-UP
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

   // Led PC12 as output
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init (GPIOC, &GPIO_InitStructure);

  // Set chip select and chip enable
  CSN_HIGH();
  CE_LOW();

}

// Transmit byte via SPI0 chanel
unsigned char  SPI_SendByte(unsigned char data) {

  // Loop while DR register in not emplty
  while(SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);

  // Send byte through the SPI1 peripheral
  SPI_SendData(SPI1, data);	

  // Wait to receive a byte
  while(SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET);

  // Return the byte read from the SPI bus
  return SPI_ReceiveData(SPI1);
}

unsigned char SPI_Send_command_with_ADDR (unsigned char cmd, unsigned char addr, unsigned char data_byte)
{
  unsigned char temp,command = 0;
  command = (cmd << 5) | addr;
  CSN_LOW();
  if (cmd == R_REGISTER)
  {
    if (addr == RX_ADDR_P0 || addr == RX_ADDR_P1 || addr == TX_ADDR)
    {

      status=SPI_SendByte(command);
      for (int k=0;k!=5;k++)
      {
        ADDRESS[k]=SPI_SendByte(NOP);
      }
      CSN_HIGH();
      return status;
    }
    else
    {
      status=SPI_SendByte(command);
      temp=SPI_SendByte(NOP);
      CSN_HIGH();
      return temp;
    }
  }
  if (cmd == W_REGISTER)
  {
    if (addr == RX_ADDR_P0)
    {
      status=SPI_SendByte(command);
      for (int j=0;j!=5;j++)
        {
          temp=RX_ADDRESS_P0[j];
          SPI_SendByte(temp);
        }
      CSN_HIGH();
      return status;
    }

    if (addr == RX_ADDR_P1)
    {
      status=SPI_SendByte(command);
      for (int j=0;j!=5;j++)
        {
          temp=RX_ADDRESS_P1[j];
          SPI_SendByte(temp);
        }
      CSN_HIGH();
      return status;
    }

    if (addr == TX_ADDR)
    {
      status=SPI_SendByte(command);
      for (int j=0;j!=5;j++)
        {
          temp=TX_ADDRESS[j];
          SPI_SendByte(temp);
        }
      CSN_HIGH();
      return status;
    }


    else
    {
      temp=SPI_SendByte(command);
      SPI_SendByte(data_byte);
      CSN_HIGH();
      return temp;
    }
  }

  return 1;
}

unsigned char SPI_Send_command_without_ADDR (unsigned char cmd, unsigned char data_byte)
{
  unsigned char temp = 0;
  CSN_LOW();
  if (cmd == R_RX_PAYLOAD)
  {
    status=SPI_SendByte(cmd);
    temp=SPI_SendByte(NOP);
    CSN_HIGH();
    return temp;
  }
  if (cmd == W_TX_PAYLOAD)
  {
    status=SPI_SendByte(cmd);
    SPI_SendByte(data_byte);
    CSN_HIGH();
    return status;
  }
  status = SPI_SendByte(cmd);
  CSN_HIGH();
  return status;

}

// Setting for nRF chip
void nRFSetting(void) {

  // Init SPI
  SPI1Init();

  // Discard transmision
  CE_LOW();

  // Write CONFIG register (addres - 0x00)
  //00001010 - CRC enable, power-up, RX
  status = SPI_Send_command_with_ADDR(W_REGISTER, CONFIG_REG_ADDR, 0x0B);
  // read
  status = SPI_Send_command_with_ADDR(R_REGISTER, CONFIG_REG_ADDR, NOP);

  // Write RX_ADDR_P0 register -> Set receive address data Pipe0 -> address in RX_ADDRESS_P0 array
  status = SPI_Send_command_with_ADDR(W_REGISTER, RX_ADDR_P0, NOP);
  // read
  status = SPI_Send_command_with_ADDR(R_REGISTER, RX_ADDR_P0, NOP);

  // Write RX_ADDR_P1 register -> Set receive address data Pipe1 -> address in RX_ADDRESS_P1 array
  status = SPI_Send_command_with_ADDR(W_REGISTER, RX_ADDR_P1, NOP);
  // read
  status = SPI_Send_command_with_ADDR(R_REGISTER,RX_ADDR_P1, NOP);

  // Write TX_ADDR register -> Transmit address. Used for a PTX device only. Address in TX_ADDRESS array
  status = SPI_Send_command_with_ADDR(W_REGISTER, TX_ADDR, NOP);
  // read
  status = SPI_Send_command_with_ADDR(R_REGISTER, TX_ADDR, NOP);

  // Write RX_PW_P0 register -> Set number of bytes in RX payload in data pipe0 -> 1 byte
  status = SPI_Send_command_with_ADDR(W_REGISTER, RX_PW_P0, 1);
  // read
  status = SPI_Send_command_with_ADDR(R_REGISTER, RX_PW_P0, NOP);

  // Write RX_PW_P1 register -> Set number of bytes in RX payload in data pipe1 -> 1 byte
  status = SPI_Send_command_with_ADDR(W_REGISTER, RX_PW_P1, 1);
  // read
  status = SPI_Send_command_with_ADDR(R_REGISTER, RX_PW_P1, NOP);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -