×
单片机 > 单片机程序设计 > 详情

PIC16f1937 nRF24L01

发布时间:2020-05-16 发布时间:
|
以下是NRF24L01的测试程序

功能:主机按一下按键,发送一次数据,对应的LED指示灯会闪一下;从机接收到信号后对应的LED指示灯会闪一下;

HOST:

//#include
#include
//const rom unsigned int CONFIG=0x0101;
#define uint8 unsigned char
#define uint16 unsigned int


__CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_OFF&MCLRE_ON&CP_OFF
         &BOREN_OFF&CLKOUTEN_OFF&IESO_OFF&FCMEN_OFF);
__CONFIG(WRT_OFF&VCAPEN_OFF&PLLEN_OFF&STVREN_OFF&BORV_19&LVP_OFF);
#define CSN  RE1
#define IRQ  RE0
#define CE   RE2
#define MOSI RC4
#define MISO RC5
#define SCK  RC3
#define BACK_LED RC1
#define KEY  RB7


#define TX_ADR_WIDTH   5
#define RX_ADR_WIDTH   5
#define RX_PLOAD_WIDTH 32
#define TX_PLOAD_WIDTH 32
uint8 TX_ADDRESS[TX_ADR_WIDTH]={0X34,0X43,0X10,0X10,0X01};
uint8 RX_ADDRESS[RX_ADR_WIDTH]={0X34,0X43,0X10,0X10,0X01};
uint8 Tx_Buf[TX_PLOAD_WIDTH]={0xff,0xee,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,
                               0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb
                             ,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xee,0xff};

uint8 sta=0;//NRF24L01状态

/***********************寄存器指令***********************/
#define READ_REG      0X00    //读寄存器指令
#define WRITE_REG     0X20    //写寄存器指令
#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    //保留
/***********************寄存器地址***********************/
#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 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栈入栈出状态寄存器设置
#define MAX_RT        0X10    //MAX_RTD在第5位|
#define TX_DS         0X20    //TX_DS在第6位  | 在读回STATUS时与其相与,就知道该位是否为1
#define RX_DR         0X40    //RX_DR在第7位  |

 

void delay(uint16 us)
{
    while(us--);
}

/*****************************************************************/

void SpiInit()
{
     TRISC=0X20;//设置RC3/SCK,RC5/SDO为输出
     ANSELE=0X00;
     TRISE=0X01;//IRQ为输入,CE,CSN为输出
     //SSPSTAT=0XC0;
     //SSPCON3=0X00;
     //SSPCON1=0X20;     //CKE=1,CKP=0;主模式,时钟为FOSC/4
     //GIE=1;
     //PEIE=1;
     CSN=1;
}
/*uint8 SPI_RW(uint8 data)//通过SPI写一个字节
{     uint8 status;
      CSN=0;
      SSPBUF=data;
      while(!BF);//当SSPBUF被读取后BF清0
      status=SSPBUF;
      SSPIF=0;
      CSN=1;
      return(status);
}*/
uint8 SPI_RW(uint8 byte)
{
 uint8  bit_ctr; 
 //DI();
    for(bit_ctr=0;bit_ctr<8;bit_ctr++)    // output 8-bit
    {
     if(byte & 0x80) 
      MOSI = 1;
     else 
      MOSI = 0;
     byte = (byte << 1);             // shift next bit into MSB..
     SCK = 1;                   // Set nRF24L01_SCK high..
     if(MISO) byte |= 1;
                NOP();NOP();NOP();NOP();
     SCK = 0;              // ..then set nRF24L01_SCK low again
                NOP();NOP();NOP();NOP();
    }
    //EI();
    return(byte);                 // return read byte
}
/*uint8 SPI_Read()   //通过SPI读一个字节
{
      CSN=0;
      SSPBUF=0X00;//读一个字节前必需先写入一个字节
      while(!BF);
      CSN=1;
      return(SSPBUF);
}*/
uint8 SPI_Read(uint8 reg)
{
      uint8 reg_val;
      CSN=0;
      SPI_RW(reg);
      reg_val=SPI_RW(0);
      CSN=1;
      return(reg_val);
}
uint8 SPI_RW_Reg(uint8 reg,uint8 value)//向寄存器写一个字节,同时返回状态字
{
      uint8 status;
      CSN=0;
      status=SPI_RW(reg);
      SPI_RW(value);
      CSN=1;
      return(status);
}
uint8 SPI_Write_Buf(uint8 reg,uint8 *pBuf,uint8 bytes)//向寄存器写入一个字符串
{
      uint8 status,byte_ctr;
      CSN=0;
      status=SPI_RW(reg);
      for(byte_ctr=0;byte_ctr       {
            SPI_RW(*pBuf++);
      }
      CSN=1;
      return(status);
}
/***************************以上为SPI通讯程序**********************************/
/******************************************************************************/
//发送模式代码
void TX_MODE(void)
{
     CE=0;
     SPI_RW_Reg(FLUSH_TX,0X00);
     SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
     SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
     SPI_RW_Reg(WRITE_REG+EN_AA,0X01);
     SPI_RW_Reg(WRITE_REG+EN_RXADDR,0X01);
     SPI_RW_Reg(WRITE_REG+SETUP_RETR,0X00);//禁止重发
     SPI_RW_Reg(WRITE_REG+RF_CH,40);
     SPI_RW_Reg(WRITE_REG+RF_SETUP,0X07);
     SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);
     SPI_RW_Reg(WRITE_REG+CONFIG,0X0e);
     CE=1;
     delay(50000);
}
void Transmit(uint8 *tx_buf)
{
     CE=0;
     SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
     SPI_RW_Reg(FLUSH_TX,0X00);
     SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);
     SPI_RW_Reg(WRITE_REG+CONFIG,0X0E);
     CE=1;
     delay(100);
}
void main()
{
     uint8 back=100;
     OSCCON=0X60;
     delay(100);
     //TRISA=0X00;
     SpiInit();
     TRISB=0X80;
     KEY=1;
     CE=0;
     CSN=1;
     SCK=0;
     IRQ=1;
     BACK_LED=0;
     //delay(50000);
  /* while(1)
   {  //back=0x02;
     CE=0;
     SPI_RW_Reg(WRITE_REG+EN_AA,0X03);
     back=SPI_Read(EN_AA);
     if(back==0x03)
     {
           BACK_LED=1;
     }
     else
     {
           BACK_LED=0;
     }
     delay(50000);
   }*/ 
     TX_MODE();
     Transmit(Tx_Buf);
     delay(50000);
     sta=SPI_Read(READ_REG+STATUS);
      SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
     CE=0;
     while(1)
     {
          if(KEY==0)
          {
              delay(1000);
              if(KEY==0)
              {
                  while(KEY==0);
                  BACK_LED=1;
                  delay(50000);
                  BACK_LED=0;
                  //TX_MODE();
                  Transmit(Tx_Buf);
                  delay(50000);
                  sta=SPI_Read(READ_REG+STATUS);
                  SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
                  CE=0;
              }
          }
     }
     /*{
         
          delay(100);
          sta=SPI_Read(READ_REG+STATUS);
          if(sta&TX_DS)
          {
                BACK_LED=1;
                delay(1000);
                SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
          }
          if(sta&MAX_RT)
          {
                BACK_LED=0;
                delay(1000);
                SPI_RW_Reg(WRITE_REG+STATUS,sta);//STATUS清0
          }
          delay(50000);
          BACK_LED=0;
          delay(50000);
          
     }*/
}

 

 

SLAVE:

//#include
#include
#define uint8 unsigned char
#define uint16 unsigned int

__CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_OFF&MCLRE_ON&CP_OFF
         &BOREN_OFF&CLKOUTEN_OFF&IESO_OFF&FCMEN_OFF);
__CONFIG(WRT_OFF&VCAPEN_OFF&PLLEN_OFF&STVREN_OFF&BORV_19&LVP_OFF);
#define CSN  RE1
#define IRQ  RE0
#define CE   RE2
#define MOSI RC4
#define MISO RC5
#define SCK  RC3
#define BACK_LED RC1


#define TX_ADR_WIDTH   5
#define RX_ADR_WIDTH   5
#define RX_PLOAD_WIDTH 32
#define TX_PLOAD_WIDTH 32
uint8 TX_ADDRESS[TX_ADR_WIDTH]={0X34,0X43,0X10,0X10,0X01};
uint8 RX_ADDRESS[RX_ADR_WIDTH]={0X34,0X43,0X10,0X10,0X01};
uint8 Tx_Buf[TX_PLOAD_WIDTH]={0xff,0xee,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,
                               0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb
                             ,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xee,0xff};
uint8 Rx_Buf[RX_PLOAD_WIDTH];

uint8 sta=0;//NRF24L01状态

/***********************寄存器指令***********************/
#define READ_REG      0X00    //读寄存器指令
#define WRITE_REG     0X20    //写寄存器指令
#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    //保留
/***********************寄存器地址***********************/
#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 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栈入栈出状态寄存器设置
#define MAX_RT        0X10    //MAX_RTD在第5位|
#define TX_DS         0X20    //TX_DS在第6位  | 在读回STATUS时与其相与,就知道该位是否为1
#define RX_DR         0X40    //RX_DR在第7位  |

 

void delay(uint16 us)//延时函数
{
    while(us--);
}

/*****************************************************************/

/*void SpiInit()
{
     TRISC=0XD7;//设置RC3/SCK,RC5/SDO为输出
     TRISE=0X01;//IRQ为输入,CE,CSN为输出
     SSPSTAT=0XC0;
     SSPCON3=0X00;
     SSPCON1=0X20;     //CKE=1,CKP=0;主模式,时钟为FOSC/4
     GIE=1;
     PEIE=1;
     CSN=1;
}
uint8 SPI_RW(uint8 data)//通过SPI写一个字节
{     uint8 status;
      CSN=0;
      SSPBUF=data;
      while(!BF);//当SSPBUF被读取后BF清0
      status=SSPBUF;
      SSPIF=0;
      CSN=1;
      return(status);
}*/
void SpiInit()
{
     TRISC=0X20;//设置RC3/SCK,RC5/SDO为输出
     ANSELE=0X00;
     TRISE=0X01;//IRQ为输入,CE,CSN为输出
     //SSPSTAT=0XC0;
     //SSPCON3=0X00;
     //SSPCON1=0X20;     //CKE=1,CKP=0;主模式,时钟为FOSC/4
     //GIE=1;
     //PEIE=1;
     CSN=1;
}

uint8 SPI_RW(uint8 byte)
{
 uint8  bit_ctr; 
 //DI();
    for(bit_ctr=0;bit_ctr<8;bit_ctr++)    // output 8-bit
    {
     if(byte & 0x80) 
      MOSI = 1;
     else 
      MOSI = 0;
     byte = (byte << 1);             // shift next bit into MSB..
     SCK = 1;                   // Set nRF24L01_SCK high..
     if(MISO) byte |= 1;
                NOP();NOP();NOP();NOP();
     SCK = 0;              // ..then set nRF24L01_SCK low again
                NOP();NOP();NOP();NOP();
    }
    //EI();
    return(byte);           
}
/*uint8 SPI_Read()   //通过SPI读一个字节
{
      CSN=0;
      SSPBUF=0X00;//读一个字节前必需先写入一个字节
      while(!BF);
      CSN=1;
      return(SSPBUF);
}*/
uint8 SPI_Read(uint8 reg)
{
      uint8 reg_val;
      CSN=0;
      SPI_RW(reg);
      reg_val=SPI_RW(0);
      CSN=1;
      return(reg_val);
}
uint8 SPI_RW_Reg(uint8 reg,uint8 value)//向寄存器写一个字节,同时返回状态字
{
      uint8 status;
      CSN=0;
      status=SPI_RW(reg);
      SPI_RW(value);
      CSN=1;
      return(status);
}
uint8 SPI_Write_Buf(uint8 reg,uint8 *pBuf,uint8 bytes)//向寄存器写入一个字符串
{
      uint8 status,byte_ctr;
      CSN=0;
      status=SPI_RW(reg);
      for(byte_ctr=0;byte_ctr       {
            SPI_RW(*pBuf++);
      }
      CSN=1;
      return(status);
}
/***************************以上为SPI通讯程序**********************************/
/******************************************************************************/
//接收模式代码
void RX_MODE(void)
{
     CE=0;
     SPI_RW_Reg(FLUSH_TX,0X00);
     //SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
     SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
     SPI_RW_Reg(WRITE_REG+EN_AA,0X01);
     SPI_RW_Reg(WRITE_REG+EN_RXADDR,0X01);
     //SPI_RW_Reg(WRITE_REG+SETUP_RETR,0X1a);
     SPI_RW_Reg(WRITE_REG+RF_CH,40);
     SPI_RW_Reg(WRITE_REG+RF_SETUP,0X07);
     SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);
     SPI_RW_Reg(WRITE_REG+CONFIG,0X0f);
     CE=1;
     delay(50000);
}
uint8 SPI_Read_Buf(uint8 reg,uint8 *pBuf,uint8 uchars)
{
     uint8 status,uchar_ctr;
     CSN=0;
     status=SPI_RW(reg);
     for(uchar_ctr=0;uchar_ctr      {
          pBuf[uchar_ctr]=SPI_RW(0);
     }
     CSN=1;
     return(status);
}
uint8 nRF24l01_RxPacket(uint8 *rx_buf)
{
     uint8 revale=0;
     sta=SPI_Read(STATUS);
     if(sta&RX_DR)
     {
           SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);
           revale=1;
     }
     SPI_RW_Reg(WRITE_REG+STATUS,sta);
     return(revale);
}
void main()
{
     uint8 recv=0;
     //delay(1);
     //TRISA=0X00;
     OSCCON=0X60;//set clock 
     delay(100);
     SpiInit();
     CE=0;
     CSN=1;
     SCK=0;
     IRQ=1;
     BACK_LED=0;
     RX_MODE();
     while(1)
     {
          if(nRF24l01_RxPacket(Rx_Buf))
          {
               //PORTA=0XFE;
               BACK_LED=1;
               delay(50000);
               BACK_LED=0;
               delay(30);
          }
     }
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR单片机中RC电容触摸的感应原理解析