找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2319|回复: 3
打印 上一主题 下一主题
收起左侧

RF24C01在STC15系列单片机中的相互通讯程序

[复制链接]
跳转到指定楼层
楼主
为了单片机之间的通讯,我做了这个程序分为收端和发端,在发送时可以改变信道来分别控制几个单片机,所有收端的信道都可设计在一个信道,反正自己玩时多改变一下就可以试出好多功能来。
  1. /*---------------
  2. 发送端主函数
  3. --------------*/

  4. #include<reg51.h>
  5. #include"2401.h"

  6. #define uint unsigned int
  7. #define uchar unsigned char

  8. sbit KEY1=P1^0;                     //发送按键
  9. sbit KEY2=P1^1;
  10. sbit KEY3=P1^2;
  11. sbit KEY4=P1^3;
  12. sbit beep=P3^3;                     
  13. sbit LED6=P3^5;                     //发送数据时显示灯+接收到数据后的功能实现灯
  14. sbit LED5 = P0^1;
  15. sbit LED4 = P3^4;                //继电器

  16. /*---------------
  17.     延时函数
  18. ------------------*/

  19. void delay_ms(uint z)         
  20. {
  21.     uint y;
  22.     while(z--)
  23.         for(y=110;y>0;y--);
  24. }


  25. /*---------------
  26.     主函数
  27. ------------------*/

  28. void main()
  29. {
  30.      uchar Tx_Buf1[]={1};    //发送的信息1
  31.      uchar Rx_Buf[32];      //接收到的数据暂存器,最多32字节数据  
  32.      init_NRF24L01();        //初始化
  33.      LED6=1;                //初始灯6熄灭   

  34.     while(NRF24L01_Check())                    //检查不到24l01则报警
  35.     {
  36.         beep=0;
  37.         delay_ms(200);
  38.         beep=1;
  39.         delay_ms(200);
  40.     }
  41.     while(1)
  42.     {   
  43.    
  44.         RX_Mode();
  45.         {                  //接收模式
  46.         if(Rx_Buf[0]==1)                               //若接收到对应的数据则实现对应功能
  47.              {
  48.                  Rx_Buf[0]=0;                //清空数据
  49.                  LED5 = ~LED5;
  50.         
  51.                }
  52.          }
  53.         
  54.    
  55.                            
  56.         while(!nRF24L01_RxPacket(Rx_Buf))     //等待接收数据,返回1则接收到数据,在等待接收数据期间,可以随时变成发送模式  
  57.         {
  58.             if(KEY1==0)                         //按了按键1,则变成发送模式,发送对应数据,发送完后变成接收模式
  59.             {   
  60.                 delay_ms(5);//消抖动
  61.                 if(KEY1==0)
  62.                 {
  63.                      while(!KEY1);
  64.                     TX_Mode();                         //发送模式
  65. //                    SPI_WR_Reg(WRITE_REG + EN_RXADDR,1);
  66.                     SPI_WR_Reg(WRITE_REG + RF_CH, 20);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  67.                      
  68.                     CE = 1;
  69.                     Tx_Buf1[0]=1;                    //将1发送过去
  70.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  71.                     LED6=0;
  72.                     delay_ms(300);
  73.                     LED6=1;
  74.                     delay_ms(300);                    //发送后LED1闪一下
  75.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  76.                  }   
  77.              }
  78.              else if(KEY2==0)                     
  79.              {   
  80.                 delay_ms(5);//消抖动
  81.                 if(KEY2==0)
  82.                 {
  83.                      while(!KEY2);
  84.                     TX_Mode();                         //发送模式
  85.                     SPI_WR_Reg(WRITE_REG + RF_CH, 40);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  86.                      
  87.                     CE = 1;
  88.                     Tx_Buf1[0]=2;                    //将2发送过去
  89.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  90.                     LED6=0;
  91.                     delay_ms(300);
  92.                     LED6=1;
  93.                     delay_ms(300);                    
  94.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  95.                  }   
  96.               }
  97.               else if(KEY3==0)                        
  98.               {   
  99.                 delay_ms(5);//消抖动
  100.                 if(KEY3==0)
  101.                 {
  102.                      while(!KEY3);
  103.                     TX_Mode();                         //发送模式
  104.                     SPI_WR_Reg(WRITE_REG + RF_CH, 60);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  105.                      
  106.                     CE = 1;
  107.                     Tx_Buf1[0]=3;                    //将3发送过去
  108.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  109.                     LED6=0;
  110.                     delay_ms(300);
  111.                     LED6=1;
  112.                     delay_ms(300);                    
  113.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  114.                  }   
  115.               }
  116.               else if(KEY4==0)                         //按了按键8,则变成发送模式,发送对应数据,发送完后变成接收模式
  117.               {   
  118.                 delay_ms(5);//消抖动
  119.                 if(KEY4==0)
  120.                 {
  121.                      while(!KEY4);
  122.                     TX_Mode();                         //发送模式
  123.                     SPI_WR_Reg(WRITE_REG + RF_CH, 80);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  124.                      
  125.                     CE = 1;
  126.                     Tx_Buf1[0]=4;                    //将4发送过去
  127.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  128.                     LED6=0;
  129.                     delay_ms(300);
  130.                     LED6=1;
  131.                     delay_ms(300);                    
  132.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  133.                  }   
  134.               }
  135.          }
  136.          if(Rx_Buf[0]==1)                               //若接收到对应的数据则实现对应功能
  137.          {
  138.              Rx_Buf[0]=0;                //清空数据
  139.     //         beep = ~beep;

  140.              //LED5 = ~LED5;
  141.              LED4=0;
  142.               delay_ms(5300);
  143.               LED4=1;
  144.               delay_ms(5300);                //接收到数据 后闪烁      
  145.          }
  146.          else if(Rx_Buf[0]==2)
  147.          {
  148.              Rx_Buf[0] = 0;
  149.             LED5 = ~LED5;
  150.          }
  151.     }
  152. }
  153. /*---------------
  154. 发送端
  155. --------------*/

  156. #include<reg51.h>
  157. #include"2401.h"

  158. #define uint unsigned int
  159. #define uchar unsigned char

  160. sbit KEY1=P1^0;                     //发送按键
  161. sbit KEY2=P1^1;
  162. sbit KEY3=P1^2;
  163. sbit KEY4=P1^3;
  164. sbit beep=P3^3;                     
  165. sbit LED6=P3^5;                     //发送数据时显示灯+接收到数据后的功能实现灯
  166. sbit LED5 = P0^1;
  167. sbit LED4 = P3^4;                //继电器

  168. /*---------------
  169.     延时函数
  170. ------------------*/

  171. void delay_ms(uint z)         
  172. {
  173.     uint y;
  174.     while(z--)
  175.         for(y=110;y>0;y--);
  176. }


  177. /*---------------
  178.     主函数
  179. ------------------*/

  180. void main()
  181. {
  182.      uchar Tx_Buf1[]={1};    //发送的信息1
  183.      uchar Rx_Buf[32];      //接收到的数据暂存器,最多32字节数据  
  184.      init_NRF24L01();        //初始化
  185.      LED6=1;                //初始灯6熄灭   

  186.     while(NRF24L01_Check())                    //检查不到24l01则报警
  187.     {
  188.         beep=0;
  189.         delay_ms(200);
  190.         beep=1;
  191.         delay_ms(200);
  192.     }
  193.     while(1)
  194.     {   
  195.    
  196.         RX_Mode();
  197.         {                  //接收模式
  198.         if(Rx_Buf[0]==1)                               //若接收到对应的数据则实现对应功能
  199.              {
  200.                  Rx_Buf[0]=0;                //清空数据
  201.                  LED5 = ~LED5;
  202.         
  203.                }
  204.          }
  205.         
  206.    
  207.                            
  208.         while(!nRF24L01_RxPacket(Rx_Buf))     //等待接收数据,返回1则接收到数据,在等待接收数据期间,可以随时变成发送模式  
  209.         {
  210.             if(KEY1==0)                         //按了按键1,则变成发送模式,发送对应数据,发送完后变成接收模式
  211.             {   
  212.                 delay_ms(5);//消抖动
  213.                 if(KEY1==0)
  214.                 {
  215.                      while(!KEY1);
  216.                     TX_Mode();                         //发送模式
  217. //                    SPI_WR_Reg(WRITE_REG + EN_RXADDR,1);
  218.                     SPI_WR_Reg(WRITE_REG + RF_CH, 20);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  219.                      
  220.                     CE = 1;
  221.                     Tx_Buf1[0]=1;                    //将1发送过去
  222.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  223.                     LED6=0;
  224.                     delay_ms(300);
  225.                     LED6=1;
  226.                     delay_ms(300);                    //发送后LED1闪一下
  227.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  228.                  }   
  229.              }
  230.              else if(KEY2==0)                     
  231.              {   
  232.                 delay_ms(5);//消抖动
  233.                 if(KEY2==0)
  234.                 {
  235.                      while(!KEY2);
  236.                     TX_Mode();                         //发送模式
  237.                     SPI_WR_Reg(WRITE_REG + RF_CH, 40);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  238.                      
  239.                     CE = 1;
  240.                     Tx_Buf1[0]=2;                    //将2发送过去
  241.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  242.                     LED6=0;
  243.                     delay_ms(300);
  244.                     LED6=1;
  245.                     delay_ms(300);                    
  246.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  247.                  }   
  248.               }
  249.               else if(KEY3==0)                        
  250.               {   
  251.                 delay_ms(5);//消抖动
  252.                 if(KEY3==0)
  253.                 {
  254.                      while(!KEY3);
  255.                     TX_Mode();                         //发送模式
  256.                     SPI_WR_Reg(WRITE_REG + RF_CH, 60);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  257.                      
  258.                     CE = 1;
  259.                     Tx_Buf1[0]=3;                    //将3发送过去
  260.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  261.                     LED6=0;
  262.                     delay_ms(300);
  263.                     LED6=1;
  264.                     delay_ms(300);                    
  265.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  266.                  }   
  267.               }
  268.               else if(KEY4==0)                         //按了按键8,则变成发送模式,发送对应数据,发送完后变成接收模式
  269.               {   
  270.                 delay_ms(5);//消抖动
  271.                 if(KEY4==0)
  272.                 {
  273.                      while(!KEY4);
  274.                     TX_Mode();                         //发送模式
  275.                     SPI_WR_Reg(WRITE_REG + RF_CH, 80);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  276.                      
  277.                     CE = 1;
  278.                     Tx_Buf1[0]=4;                    //将4发送过去
  279.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  280.                     LED6=0;
  281.                     delay_ms(300);
  282.                     LED6=1;
  283.                     delay_ms(300);                    
  284.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  285.                  }   
  286.               }
  287.          }
  288.          if(Rx_Buf[0]==1)                               //若接收到对应的数据则实现对应功能
  289.          {
  290.              Rx_Buf[0]=0;                //清空数据
  291.     //         beep = ~beep;

  292.              //LED5 = ~LED5;
  293.              LED4=0;
  294.               delay_ms(5300);
  295.               LED4=1;
  296.               delay_ms(5300);                //接收到数据 后闪烁      
  297.          }
  298.          else if(Rx_Buf[0]==2)
  299.          {
  300.              Rx_Buf[0] = 0;
  301.             LED5 = ~LED5;
  302.          }
  303.     }
  304. }
  305. /*---------------
  306. 发送端
  307. --------------*/

  308. #include<reg51.h>
  309. #include"2401.h"

  310. #define uint unsigned int
  311. #define uchar unsigned char

  312. sbit KEY1=P1^0;                     //发送按键
  313. sbit KEY2=P1^1;
  314. sbit KEY3=P1^2;
  315. sbit KEY4=P1^3;
  316. sbit beep=P3^3;                     
  317. sbit LED6=P3^5;                     //发送数据时显示灯+接收到数据后的功能实现灯
  318. sbit LED5 = P0^1;
  319. sbit LED4 = P3^4;                //继电器

  320. /*---------------
  321.     延时函数
  322. ------------------*/

  323. void delay_ms(uint z)         
  324. {
  325.     uint y;
  326.     while(z--)
  327.         for(y=110;y>0;y--);
  328. }


  329. /*---------------
  330.     主函数
  331. ------------------*/

  332. void main()
  333. {
  334.      uchar Tx_Buf1[]={1};    //发送的信息1
  335.      uchar Rx_Buf[32];      //接收到的数据暂存器,最多32字节数据  
  336.      init_NRF24L01();        //初始化
  337.      LED6=1;                //初始灯6熄灭   

  338.     while(NRF24L01_Check())                    //检查不到24l01则报警
  339.     {
  340.         beep=0;
  341.         delay_ms(200);
  342.         beep=1;
  343.         delay_ms(200);
  344.     }
  345.     while(1)
  346.     {   
  347.    
  348.         RX_Mode();
  349.         {                  //接收模式
  350.         if(Rx_Buf[0]==1)                               //若接收到对应的数据则实现对应功能
  351.              {
  352.                  Rx_Buf[0]=0;                //清空数据
  353.                  LED5 = ~LED5;
  354.         
  355.                }
  356.          }
  357.         
  358.    
  359.                            
  360.         while(!nRF24L01_RxPacket(Rx_Buf))     //等待接收数据,返回1则接收到数据,在等待接收数据期间,可以随时变成发送模式  
  361.         {
  362.             if(KEY1==0)                         //按了按键1,则变成发送模式,发送对应数据,发送完后变成接收模式
  363.             {   
  364.                 delay_ms(5);//消抖动
  365.                 if(KEY1==0)
  366.                 {
  367.                      while(!KEY1);
  368.                     TX_Mode();                         //发送模式
  369. //                    SPI_WR_Reg(WRITE_REG + EN_RXADDR,1);
  370.                     SPI_WR_Reg(WRITE_REG + RF_CH, 20);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  371.                      
  372.                     CE = 1;
  373.                     Tx_Buf1[0]=1;                    //将1发送过去
  374.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  375.                     LED6=0;
  376.                     delay_ms(300);
  377.                     LED6=1;
  378.                     delay_ms(300);                    //发送后LED1闪一下
  379.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  380.                  }   
  381.              }
  382.              else if(KEY2==0)                     
  383.              {   
  384.                 delay_ms(5);//消抖动
  385.                 if(KEY2==0)
  386.                 {
  387.                      while(!KEY2);
  388.                     TX_Mode();                         //发送模式
  389.                     SPI_WR_Reg(WRITE_REG + RF_CH, 40);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  390.                      
  391.                     CE = 1;
  392.                     Tx_Buf1[0]=2;                    //将2发送过去
  393.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  394.                     LED6=0;
  395.                     delay_ms(300);
  396.                     LED6=1;
  397.                     delay_ms(300);                    
  398.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  399.                  }   
  400.               }
  401.               else if(KEY3==0)                        
  402.               {   
  403.                 delay_ms(5);//消抖动
  404.                 if(KEY3==0)
  405.                 {
  406.                      while(!KEY3);
  407.                     TX_Mode();                         //发送模式
  408.                     SPI_WR_Reg(WRITE_REG + RF_CH, 60);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  409.                      
  410.                     CE = 1;
  411.                     Tx_Buf1[0]=3;                    //将3发送过去
  412.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  413.                     LED6=0;
  414.                     delay_ms(300);
  415.                     LED6=1;
  416.                     delay_ms(300);                    
  417.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  418.                  }   
  419.               }
  420.               else if(KEY4==0)                         //按了按键8,则变成发送模式,发送对应数据,发送完后变成接收模式
  421.               {   
  422.                 delay_ms(5);//消抖动
  423.                 if(KEY4==0)
  424.                 {
  425.                      while(!KEY4);
  426.                     TX_Mode();                         //发送模式
  427.                     SPI_WR_Reg(WRITE_REG + RF_CH, 80);    //经我自已修改了发送频道后,只有频道1能接收,在2401.H里去掉了此句话
  428.                      
  429.                     CE = 1;
  430.                     Tx_Buf1[0]=4;                    //将4发送过去
  431.                     nRF24L01_TxPacket(Tx_Buf1);        //发送命令数据
  432.                     LED6=0;
  433.                     delay_ms(300);
  434.                     LED6=1;
  435.                     delay_ms(300);                    
  436.                     break;                            //退出最近的循环,从而变回接收模式,这句关键
  437.                  }   
  438.               }
  439.          }
  440.          if(Rx_Buf[0]==1)                               //若接收到对应的数据则实现对应功能
  441.          {
  442.              Rx_Buf[0]=0;                //清空数据
  443.     //         beep = ~beep;

  444.              //LED5 = ~LED5;
  445.              LED4=0;
  446.               delay_ms(5300);
  447.               LED4=1;
  448.               delay_ms(5300);                //接收到数据 后闪烁      
  449.          }
  450.          else if(Rx_Buf[0]==2)
  451.          {
  452.              Rx_Buf[0] = 0;
  453.             LED5 = ~LED5;
  454.          }
  455.     }
  456. }

  457. /*配置文件*/

  458. #ifndef __NRF24L01_H__
  459. #define __NRF24L01_H__
  460. #include<reg51.h>
  461. #define uchar unsigned char
  462. #define uint unsigned int
  463. sfr P5 = 0xC8;
  464. sbit    CE        =P5^5;
  465. sbit    CSN        =P2^4;
  466. sbit    SCK        =P2^1;
  467. sbit     MOSI    =P2^3;
  468. sbit     MISO    =P2^2;
  469. sbit    IRQ        =P3^2;


  470. #define TX_ADR_WIDTH    5       // 5 uints TX address width
  471. #define RX_ADR_WIDTH    5       // 5 uints RX address width
  472. #define TX_PLOAD_WIDTH  32      // 32 uints TX payload
  473. #define RX_PLOAD_WIDTH  32      // 32 uints TX payload
  474. uchar  TX_ADDRESS[TX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7};    //本地地址
  475. uchar  RX_ADDRESS[RX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7};    //接收地址


  476. /************************************
  477.         NRF24L01寄存器指令
  478. ************************************/

  479. #define READ_REG        0x00      // 读寄存器指令
  480. #define WRITE_REG       0x20     // 写寄存器指令
  481. #define RD_RX_PLOAD     0x61      // 读取接收数据指令
  482. #define WR_TX_PLOAD     0xA0      // 写待发数据指令
  483. #define FLUSH_TX        0xE1     // 冲洗发送 FIFO指令
  484. #define FLUSH_RX        0xE2      // 冲洗接收 FIFO指令
  485. #define REUSE_TX_PL     0xE3      // 定义重复装载数据指令
  486. #define NOP             0xFF      // 保留


  487. /*************************************
  488.      SPI(nRF24L01)寄存器地址
  489. *************************************/

  490. #define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
  491. #define EN_AA           0x01  // 自动应答功能设置
  492. #define EN_RXADDR       0x02  // 可用信道设置
  493. #define SETUP_AW        0x03  // 收发地址宽度设置
  494. #define SETUP_RETR      0x04  // 自动重发功能设置
  495. #define RF_CH           0x05  // 工作频率设置
  496. #define RF_SETUP        0x06  // 发射速率、功耗功能设置
  497. #define NRFRegSTATUS    0x07  // 状态寄存器
  498. #define OBSERVE_TX      0x08  // 发送监测功能
  499. #define CD              0x09  // 地址检测           
  500. #define RX_ADDR_P0      0x0A  // 频道0接收数据地址
  501. #define RX_ADDR_P1      0x0B  // 频道1接收数据地址
  502. #define RX_ADDR_P2      0x0C  // 频道2接收数据地址
  503. #define RX_ADDR_P3      0x0D  // 频道3接收数据地址
  504. #define RX_ADDR_P4      0x0E  // 频道4接收数据地址
  505. #define RX_ADDR_P5      0x0F  // 频道5接收数据地址
  506. #define TX_ADDR         0x10  // 发送地址寄存器
  507. #define RX_PW_P0        0x11  // 接收频道0接收数据长度
  508. #define RX_PW_P1        0x12  // 接收频道1接收数据长度
  509. #define RX_PW_P2        0x13  // 接收频道2接收数据长度
  510. #define RX_PW_P3        0x14  // 接收频道3接收数据长度
  511. #define RX_PW_P4        0x15  // 接收频道4接收数据长度
  512. #define RX_PW_P5        0x16  // 接收频道5接收数据长度
  513. #define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置


  514. /*---------------------------------
  515.            子函数集
  516. ---------------------------------*/

  517. uchar NRF24SPI_Send_Byte(uchar dat);
  518. uchar SPI_WR_Reg(uchar reg, uchar value);
  519. uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar Len);
  520. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar Len);
  521. uchar nRF24L01_RxPacket(unsigned char* rx_buf);
  522. void nRF24L01_TxPacket(unsigned char * tx_buf);
  523. uchar SPI_RD_Reg(uchar reg);
  524. void init_NRF24L01(void);
  525. void TX_Mode(void);
  526. void RX_Mode(void);
  527. void NRF_Send(void);
  528. uchar NRF24L01_Check(void);


  529. /*----------------------------------------------
  530.         发送一字节[MOSI和MISO数据传递]
  531. ----------------------------------------------*/

  532. uchar NRF24SPI_Send_Byte(uchar dat)
  533. {
  534.       uchar i;
  535.     for (i = 0; i < 8; i++) //output 8-bit
  536.     {
  537.         //写入1位数据
  538.         MOSI=(dat & 0x80);    //output 'uchar', MSB to MOSI
  539.         dat<<= 1;           // shift next bit into MSB..
  540.         
  541.         //读取1位数据
  542.         SCK = 1;                       // Set SCK high..
  543.         if (MISO){
  544.              dat|= 1;
  545.         }else{                         // capture current MISO bit
  546.              dat &= 0xFE;
  547.         }
  548.         SCK = 0;                    // ..then set SCK low again
  549.     }
  550.     return(dat);                    // return read uchar
  551. }
  552. //----------------------------------------------
  553. //延时n个10us
  554. //----------------------------------------------
  555. void Delay_n10us(uint n)   
  556. {
  557.    for(;n>0;n--)
  558.    {
  559.         unsigned char a,b;
  560.      for(b=1;b>0;b--)
  561.          for(a=2;a>0;a--);
  562.    }
  563. }


  564. /*----------------------------------------------
  565.               NRF24L01检测是否存在
  566. ----------------------------------------------*/

  567. uchar NRF24L01_Check(void)
  568. {
  569.     uchar bu[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
  570.     uchar bu1[5];
  571.     uchar i;        
  572.     SPI_Write_Buf(WRITE_REG+TX_ADDR,bu,5);      //写入5个字节的地址.   
  573.     SPI_Read_Buf(TX_ADDR,bu1,5);              //读出写入的地址      
  574.     for(i=0;i<5;i++)if(bu1!=0XA5)break;                       
  575.     if(i!=5)return 1;                               //NRF24L01不在位   
  576.     return 0;                                        //NRF24L01在位
  577. }   


  578. /*----------------------------------------------
  579.             NRF24L01初始化
  580. ----------------------------------------------*/      

  581. void init_NRF24L01(void)
  582. {
  583.     uchar buf[5]={0};
  584.     Delay_n10us(10);
  585.     CE = 0;            // chip enable
  586.     CSN= 0;            // Spi disable
  587.    
  588.     SPI_Read_Buf(TX_ADDR, buf, TX_ADR_WIDTH);//debug 测试原来的本地地址:复位值是:0xE7 0xE7 0xE7 0xE7 0xE7
  589.   
  590. //    SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址   
  591. //    SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址

  592. //   
  593. //    SPI_WR_Reg(WRITE_REG + EN_AA, 0x01);      //  频道0自动    ACK应答允许   
  594. //    SPI_WR_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21  
  595. //    SPI_WR_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 设置自动重发时间和次数:500us + 86us, 10 retrans...
  596. //    SPI_WR_Reg(WRITE_REG + RF_CH, 22);        //   设置信道工作为2.4GHZ,收发必须一致
  597. //    SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
  598. //    SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x07);           //设置发射速率为1MHZ,发射功率为最大值0dB
  599. //  
  600. //  SPI_RD_Reg(WRITE_REG + EN_AA);
  601. //  SPI_RD_Reg(WRITE_REG + EN_RXADDR);
  602. //  SPI_RD_Reg(WRITE_REG + RF_CH);
  603. //  SPI_RD_Reg(WRITE_REG + RX_PW_P0);
  604. //  SPI_RD_Reg(WRITE_REG + RF_SETUP);
  605. }


  606. /*----------------------------------------------
  607.   函数:uchar SPI_Read(uchar reg)
  608.   功能:NRF24L01的SPI时序,读取指定寄存器的内容
  609. ----------------------------------------------*/

  610. uchar SPI_RD_Reg(uchar reg)
  611. {
  612.     uchar reg_val;
  613.     CSN = 0;                            // CSN low, initialize SPI communication...
  614.     NRF24SPI_Send_Byte(reg);            // Select register to read from..
  615.     reg_val = NRF24SPI_Send_Byte(0);    // ..then read registervalue
  616.     CSN = 1;                            // CSN high, terminate SPI communication   
  617.     return(reg_val);                    // return register value
  618. }


  619. /*----------------------------------------------
  620.      函数:uchar SPI_Write(uchar reg)
  621.      功能:NRF24L01的SPI时序,写入指定寄存器的内容
  622. ----------------------------------------------*/

  623. uchar SPI_WR_Reg(uchar reg, uchar value)
  624. {
  625.     uchar status;
  626.     CSN = 0;                               // CSN low, init SPI transaction
  627.     status = NRF24SPI_Send_Byte(reg);    // select register
  628.     NRF24SPI_Send_Byte(value);          // ..and write value to it..
  629.     CSN = 1;                               // CSN high again
  630.     return(status);                        // return nRF24L01 status uchar
  631. }


  632. /*----------------------------------------------
  633.   函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar Len)
  634.   功能: 用于读数据
  635.   参数:reg:为寄存器地址
  636.   pBuf:为待读出数据地址
  637.   uchars:读出数据的个数
  638. ----------------------------------------------*/

  639. uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar Len)
  640. {
  641.     uint status,i;
  642.     CSN = 0;                            // Set CSN low, init SPI tranaction
  643.     status = NRF24SPI_Send_Byte(reg);   // Select register to write to and read status uchar
  644.     for(i=0;i<Len;i++){
  645.          pBuf = NRF24SPI_Send_Byte(0);
  646.     }
  647.     CSN = 1;                          
  648.     return(status);                        // return nRF24L01 status uchar
  649. }


  650. /*----------------------------------------------
  651. 函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar Len)
  652. 功能: 用于写数据
  653. 参数:reg:为寄存器地址
  654. pBuf:为待写入数据地址
  655. uchars:写入数据的个数
  656. ----------------------------------------------*/

  657. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar Len)
  658. {
  659.     uint status,i;
  660.     CSN = 0;                            //SPI使能      
  661.     status = NRF24SPI_Send_Byte(reg);   
  662.     for(i=0; i<Len; i++){
  663.        NRF24SPI_Send_Byte(*pBuf);
  664.          pBuf ++;
  665.     }
  666.     CSN = 1;                               //关闭SPI
  667.     return(status);   
  668. }


  669. /*----------------------------------------------
  670.    函数:void SetRX_Mode(void)
  671.    功能:数据接收配置
  672. ----------------------------------------------*/

  673. void RX_Mode(void)
  674. {
  675.     uchar buf[5]={0};
  676.     CE = 0;
  677.     SPI_Read_Buf(TX_ADDR,buf, TX_ADR_WIDTH);    //debug 测试原来的本地地址:复位值是:0xE7 0xE7 0xE7 0xE7 0xE7
  678.            //SPI_WR_Reg(WRITE_REG + CONFIG, 0x03);//SPI_WR_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC    ,主接收
  679.          //SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);        // 写本地地址   
  680.     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);     // 写接收端地址
  681.     SPI_WR_Reg(WRITE_REG + EN_AA, 0);                      //频道0自动    ACK应答允许   
  682.     SPI_WR_Reg(WRITE_REG + EN_RXADDR,0x01);              //允许接收地址只有频道0,如果需要多频道可以参考Page21  
  683.     SPI_WR_Reg(WRITE_REG + SETUP_RETR,0x1a);             //设置自动重发时间和次数:500us + 86us, 10 retrans...
  684.     SPI_WR_Reg(WRITE_REG + RF_CH, 40);                    //设置信道工作为2.4GHZ,收发必须一致
  685.     SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);     //设置接收数据长度,本次设置为32字节
  686.     SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x0F);               //设置发射速率为2MHZ,发射功率为最大值0dB
  687.     SPI_WR_Reg(WRITE_REG + CONFIG, 0x0F);
  688.     CE = 1;
  689.     Delay_n10us(20); //200us
  690. }




  691. /*----------------------------------------------
  692.   函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
  693.   功能:数据读取后放入rx_buf接收缓冲区中
  694. ----------------------------------------------*/

  695. uchar nRF24L01_RxPacket(unsigned char* rx_buf)
  696. {
  697.     uchar flag=0;
  698.     uchar status;
  699.      
  700.     status=SPI_RD_Reg(NRFRegSTATUS);    //读取状态寄存其来判断数据接收状况
  701.    
  702.     if(status & 0x40)                    //判断是否接收到数据
  703.     {
  704.            CE=0;             //SPI使能
  705.          SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);    // read receive payload from RX_FIFO buffer
  706.          flag =1;                                            //读取数据完成标志
  707.     }
  708.     SPI_WR_Reg(WRITE_REG+NRFRegSTATUS, status);               //接收到数据后RX_DR,TX_DS,MAX_RT都置高为1,通过写1来清楚中断标志
  709.     return flag;
  710. }


  711. /*----------------------------------------------
  712.   函数:void TX_Mode(void)
  713.   功能:数据发送配置
  714. ----------------------------------------------*/

  715. void TX_Mode(void)
  716. {
  717.     CE = 0;
  718.     //SPI_WR_Reg(WRITE_REG + CONFIG, 0x02);   //0x0E         // IRQ收发完成中断响应,16位CRC,主发送
  719.    
  720.     SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址   
  721.     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
  722.     SPI_WR_Reg(WRITE_REG + EN_AA, 0);//0x01);                          //  频道0自动    ACK应答允许   
  723.     SPI_WR_Reg(WRITE_REG + EN_RXADDR,0);// 0x01);                      //  允许接收地址只有频道0,如果需要多频道可以参考Page21  
  724.     SPI_WR_Reg(WRITE_REG + SETUP_RETR, 0);//0x1a);                     // 设置自动重发时间和次数:500us + 86us, 10 retrans...
  725. //    SPI_WR_Reg(WRITE_REG + RF_CH, 40);                                //   设置信道工作为2.4GHZ,收发必须一致
  726.     SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);                 //设置接收数据长度,本次设置为32字节
  727.     SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x0F);                           //设置发射速率为2MHZ,发射功率为最大值0dB

  728.     SPI_WR_Reg(WRITE_REG + CONFIG, 0x0E);
  729. //   CE = 1;
  730. }


  731. /*----------------------------------------------
  732.   函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
  733.   功能:发送tx_buf中数据
  734. ----------------------------------------------*/

  735. void nRF24L01_TxPacket(unsigned char * tx_buf)
  736. {
  737.     CE = 0;            //StandBy I模式   
  738.     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
  739.     SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);              // 装载数据   
  740.     //SPI_WR_Reg(WRITE_REG + CONFIG, 0x0e);            // IRQ收发完成中断响应,16位CRC,主发送
  741.     CE = 1;         //置高CE,激发数据发送
  742. }


  743. ///************************************主函数************************************************************
  744. //void NRF_Send(void)
  745. //{
  746. //  //static uint counter=0;
  747. //  static uchar flag=0;  
  748. //   
  749. //   //TX_Mode();
  750. //   
  751. //   //IntervalTimems(100);
  752. //   if(flag==0)
  753. //   {
  754. //      flag=1;
  755. //      //memcpy(TxBuf, "1234567890abcdefghij", 20);
  756. //      nRF24L01_TxPacket(TxBuf);
  757. //   }
  758. //   else
  759. //   {
  760. //      flag=0;
  761. //      //memcpy(TxBuf, "abcdefghij1234567890", 20);
  762. //      nRF24L01_TxPacket(TxBuf);
  763. //   }
  764. //   
  765. //}


  766. #endif   /*__NRF24L01_H__ */
复制代码

IMG_20190219_183629[1].jpg (4.72 MB, 下载次数: 47)

IMG_20190219_183629[1].jpg

RF24C01模块无线发射接收控制.zip

132.34 KB, 下载次数: 12, 下载积分: 黑币 -5

RF24C01模块的收发端程序

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:424598 发表于 2019-2-20 08:27 | 只看该作者
程序备注得不错,感谢分享
回复

使用道具 举报

板凳
ID:243748 发表于 2019-2-24 11:51 来自手机 | 只看该作者
无线模块怎么接线呢?
回复

使用道具 举报

地板
ID:459370 发表于 2019-2-25 21:15 | 只看该作者
wuxishun 发表于 2019-2-24 11:51
无线模块怎么接线呢?

直接接到ISP接口上,你查看一下程序里申明与你的单片机ISP引脚相同即可。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表