标题: nRF24L01一键遥控接收端LED灯与蜂鸣器响 [打印本页]

作者: 772295547    时间: 2018-5-1 14:54
标题: nRF24L01一键遥控接收端LED灯与蜂鸣器响
基于51单片机的nrf24l01一键遥控LED灯

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>

  3. #define uchar unsigned char
  4. #define uint unsigned int

  5. sbit beep=P3^7;

  6. //****************************NRF24L01端 口 定 义 **************************
  7. sbit CE    =P2^0; //芯片使能
  8. sbit CSN   =P2^1; //片选信号
  9. sbit SCK   =P2^2; //串行时钟信号
  10. sbit MOSI  =P2^3; //主收从发
  11. sbit MISO  =P2^4; //主发从收
  12. sbit IRQ   =P2^5; //中断查询

  13. //*****************************************延时函数***************************************//
  14. void delayus(uint us)
  15. {
  16.         for(;us >0;us--)
  17.         {        
  18.                 _nop_();
  19.         }
  20. }


  21. //*****************************NRF24L01的接收和发送地址***************************************//
  22. #define TX_ADR_WIDTH    5   // 5个字节的TX地址长度
  23. #define RX_ADR_WIDTH    5   // 5个字节的RX地址长度
  24. #define TX_PLOAD_WIDTH  16  // ?个字节的TX数据长度
  25. #define RX_PLOAD_WIDTH  16  // ?个字节的RX数据长度
  26. uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //本地地址
  27. uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //接收地址
  28. //***************************************NRF24L01寄存器指令**********************************//
  29. #define READ_REG        0x00          // 读寄存器
  30. #define WRITE_REG       0x20         // 写寄存器
  31. #define RD_RX_PLOAD     0x61          // 读取接收数据
  32. #define WR_TX_PLOAD     0xA0          // 写待发数据
  33. #define FLUSH_TX        0xE1         // 冲洗发送 FIFO
  34. #define FLUSH_RX        0xE2          // 冲洗接收 FIFO
  35. #define REUSE_TX_PL     0xE3          // 定义重复装载数据
  36. #define NOP             0xFF          // 保留
  37. //*************************************SPI(nRF24L01)寄存器地址*****************************//
  38. #define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
  39. #define EN_AA           0x01  // 自动应答功能设置
  40. #define EN_RXADDR       0x02  // 可用信道设置
  41. #define SETUP_AW        0x03  // 收发地址宽度设置
  42. #define SETUP_RETR      0x04  // 自动重发功能设置
  43. #define RF_CH           0x05  // 工作频率设置
  44. #define RF_SETUP        0x06  // 发射速率、功耗功能设置
  45. #define STATUS          0x07  // 状态寄存器
  46. #define OBSERVE_TX      0x08  // 发送监测功能
  47. #define CD              0x09  // 地址检测           
  48. #define RX_ADDR_P0      0x0A  // 频道0接收数据地址
  49. #define RX_ADDR_P1      0x0B  // 频道1接收数据地址
  50. #define RX_ADDR_P2      0x0C  // 频道2接收数据地址
  51. #define RX_ADDR_P3      0x0D  // 频道3接收数据地址
  52. #define RX_ADDR_P4      0x0E  // 频道4接收数据地址
  53. #define RX_ADDR_P5      0x0F  // 频道5接收数据地址
  54. #define TX_ADDR         0x10  // 发送地址寄存器
  55. #define RX_PW_P0        0x11  // 接收频道0接收数据长度
  56. #define RX_PW_P1        0x12  // 接收频道0接收数据长度
  57. #define RX_PW_P2        0x13  // 接收频道0接收数据长度
  58. #define RX_PW_P3        0x14  // 接收频道0接收数据长度
  59. #define RX_PW_P4        0x15  // 接收频道0接收数据长度
  60. #define RX_PW_P5        0x16  // 接收频道0接收数据长度
  61. #define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
  62. void init_NRF24L01();
  63. uchar SPI_RW(uchar num);
  64. uchar SPI_Read(uchar reg);
  65. void SetRX_Mode();
  66. void SetTx_Mode();
  67. uchar SPI_RW_Reg(uchar reg, uchar value);
  68. uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
  69. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
  70. void nRF24L01_RxPacket(uchar *rx_buf);
  71. void nRF24L01_TxPacket(uchar *tx_buf);

  72. //****************************************状态标志****************************************//
  73. uchar         bdata sta;
  74. sbit        RX_DR        =sta^6;
  75. sbit        TX_DS        =sta^5;
  76. sbit        MAX_RT        =sta^4;
  77. //********************************NRF24L01初始化******************************************//
  78. void init_NRF24L01()
  79. {
  80.     delayus(100);
  81.          CE=0;    // 片选使能
  82.          CSN=1;   // SPI使能
  83.          SCK=0;   // SPI时钟拉低
  84.         SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    //写本地地址        
  85.         SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); //写接收端地址
  86.         SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                             //通道0自动应答         
  87.         SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);                         //允许接收地址频道0
  88.         SPI_RW_Reg(WRITE_REG + RF_CH, 0x32);                             //设置信道工作频率,收发必须一致
  89.         SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);                //设置接收数据长度
  90.         SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f);                                    //设置发射速率为2MHZ,发射功率为最大值0dB        
  91.         SPI_RW_Reg(WRITE_REG + CONFIG, 0x7c);                                                          //IRQ引脚不显示中断 掉电模式  1~16CRC校验
  92. }
  93. /****************************************************************************************************
  94. /*函数:uint SPI_RW(uint uchar)
  95. /*功能:NRF24L01的SPI写时序
  96. /****************************************************************************************************/
  97. uchar SPI_RW(uchar num)
  98. {
  99.         uchar bit_ctr;
  100.            for(bit_ctr=0;bit_ctr<8;bit_ctr++)  // output 8-bit
  101.            {
  102.                 MOSI = (num & 0x80);            // output 'uchar', MSB to MOSI
  103.                 num = (num << 1);               // shift next bit into MSB..
  104.                 SCK = 1;                        // Set SCK high..
  105.                 num |= MISO;                               // capture current MISO bit
  106.                 SCK = 0;                                // ..then set SCK low again
  107.            }
  108.     return(num);                                   // return read uchar
  109. }
  110. /****************************************************************************************************
  111. 函数:uchar SPI_Read(uchar reg)
  112. 功能:NRF24L01的SPI时序
  113. ****************************************************************************************************/
  114. uchar SPI_Read(uchar reg)
  115. {
  116.         uchar reg_val;
  117.         
  118.         CSN = 0;                // CSN low, initialize SPI communication...
  119.         SPI_RW(reg);            // Select register to read from..
  120.         reg_val = SPI_RW(0);    // ..then read registervalue
  121.         CSN = 1;                // CSN high, terminate SPI communication
  122.         
  123.         return(reg_val);        // return register value
  124. }
  125. /****************************************************************************************************/
  126. /*功能:NRF24L01读写寄存器函数
  127. /****************************************************************************************************/
  128. uchar SPI_RW_Reg(uchar reg, uchar value)
  129. {
  130.         uchar status;
  131.         CSN = 0;                   // CSN low, init SPI transaction
  132.         status = SPI_RW(reg);      // select register
  133.         SPI_RW(value);             // ..and write value to it..
  134.         CSN = 1;                   // CSN high again
  135.         return(status);            // return nRF24L01 status uchar
  136. }
  137. /****************************************************************************************************/
  138. uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
  139. {
  140.         uchar status,byte_ctr;
  141.         CSN = 0; // Set CSN low, init SPI tranaction
  142.         status = SPI_RW(reg); // Select register to write to and read status byte
  143.         for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
  144.         pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte from nRF24L01
  145.         CSN = 1; // Set CSN high again
  146.         return(status); // return nRF24L01 status byte
  147. }
  148. /*********************************************************************************************************
  149. /*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  150. /*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
  151. /*********************************************************************************************************/
  152. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  153. {
  154.         uchar status,uchar_ctr;
  155.         
  156.         CSN = 0;            //SPI使能      
  157.         status = SPI_RW(reg);   
  158.         for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
  159.                 SPI_RW(*pBuf++);
  160.         CSN = 1;           //关闭SPI
  161.         return(status);    //
  162. }
  163. //********** nrf收发程序 **********
  164. void nrf_RxTx(uchar mod_nrf,uchar *buff) //NRF24L01收发程序        
  165. {                        
  166.         static uchar mod_nrf_b;

  167. //******进入发射模式******
  168.         if(mod_nrf == 't')
  169.         {
  170.                 if(mod_nrf_b != 't')
  171.                 {        
  172.                         mod_nrf_b = 't';
  173.                         CE = 0;
  174.                         SPI_RW_Reg(WRITE_REG+STATUS,0xff);         //清除中断标志
  175.                         SPI_RW_Reg(FLUSH_TX,0x00);                        //清除TX_FIFO寄存器
  176.                         SPI_RW_Reg(WRITE_REG + CONFIG,0x7e);//IRQ引脚不显示中断 上电 发射模式  1~16CRC校验
  177.                         CE = 1;
  178.                         delayus(130);//从CE = 0 到 CE = 1;即待机模式到收发模式,需要最大130us                  
  179.                 }
  180.                
  181. //******发送数据******
  182.                 CE = 0;                        //StandBy I模式        
  183.                 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
  184.                 SPI_Write_Buf(WR_TX_PLOAD,buff,TX_PLOAD_WIDTH);                          // 装载数据
  185.                 CE = 1;                 //置高CE激发数据发送
  186.                 delayus(130);//从CE = 0 到 CE = 1;即待机模式到收发模式,需要最大130us
  187.                
  188.                 delayus(100); //给发送数据一点时间         比发送速度较快 延时可以比接收少
  189.                 sta = SPI_Read(STATUS);//读取状态寄存器的值
  190.                 SPI_RW_Reg(WRITE_REG+STATUS,sta);//清除对应的中断
  191.                                                 
  192.                 if(TX_DS == 1)//发送成功再清除tx fifo寄存器
  193.                 {        
  194.                         CE = 0;                        
  195.                         SPI_RW_Reg(FLUSH_TX,0x00); //清除tx fifo寄存器        //********重要*********
  196.                         CE = 1;
  197.                 }                                                               
  198.                                 
  199.         }
  200. //******进入接收模式******
  201.         else if(mod_nrf == 'r')//接收模式
  202.         {
  203.                 if(mod_nrf_b != 'r')
  204.                 {
  205.                         mod_nrf_b = 'r';
  206.                         CE = 0;
  207.                         SPI_RW_Reg(WRITE_REG+STATUS,0xff);        //清除中断标志
  208.                         SPI_RW_Reg(FLUSH_RX,0x00);                         //清除RX_FIFO寄存器
  209.                         SPI_RW_Reg(WRITE_REG + CONFIG, 0x7f);//IRQ引脚不显示中断 上电 接收模式   1~16CRC校验   
  210.                         CE = 1;
  211.                         delayus(130);//从CE = 0 到 CE = 1;即待机模式到收发模式,需要最大130us
  212.                 }               
  213.                 delayus(500); //不能少 值可调  给接收数据一点时间
  214.                 sta = SPI_Read(STATUS);
  215.                 SPI_RW_Reg(WRITE_REG+STATUS,sta);   
  216.                 if(RX_DR == 1)   
  217.                 {
  218.                         CE = 0;  
  219.                         SPI_Read_Buf(RD_RX_PLOAD,buff,RX_PLOAD_WIDTH);//读取数据 存入数组
  220.                         SPI_RW_Reg(FLUSH_RX,0x00);//清除rx fifo寄存器        数据不抖动
  221.                         CE = 1;
  222.                 }                  
  223.          }
  224. }



  225. void main()
  226. {
  227.         uchar idata RxBuf[16];        //接收缓存 存入idata区
  228.         uchar idata TxBuf[16];        //发送缓存
  229.         uint t_while = 0;
  230.         uint t_tx = 100;
  231.         uint t_rx = 100;

  232.         init_NRF24L01();                //nrf24l01初始化
  233.         
  234.         RxBuf[0] = 0;
  235.         TxBuf[0] = 1;
  236.         
  237.         while(1)
  238.         {        
  239.                 t_while = t_rx ;
  240.                 while(t_while--)                        //一旦接收成功就跳出循环 最多接收t_while次        
  241.                 {        
  242.                         nrf_RxTx('r',RxBuf);        //接收模式
  243.                         
  244.                         if(RX_DR == 1)                        //接收成功
  245.                                 break;                                //跳出循环进入发送模式
  246.                 }
  247.                
  248.                 if(RxBuf[0] == 0x10)               
  249.                 {
  250.                         beep=0;
  251.                         
  252.                 }
  253.                 else
  254.                 {
  255.                         beep=1;
  256.                 }
  257.         }
  258. }
复制代码

所有资料51hei提供下载:
nRF24L01一键遥控接收端蜂鸣器响.zip (51.74 KB, 下载次数: 53)



作者: 763900682    时间: 2019-5-8 22:10
接收端怎么工作的

作者: 763900682    时间: 2019-5-11 16:21
有原理图吗




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1