找回密码
 立即注册

QQ登录

只需一步,快速开始

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

关于NRF24L01无线模块实时改变频率?附单片机程序

[复制链接]
跳转到指定楼层
楼主
ID:895128 发表于 2021-4-22 14:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这个程序怎么按键更改无线模块的接受频率啊
也就是 SPI_RW_Reg(WRITE_REG + RF_CH, 40);      中这个40.我想通过按键改成0,20,60,80,这样的

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

  3. typedef unsigned char uchar;
  4. typedef unsigned char uint;
  5. //****************************************NRF24L01端口定义***************************************
  6. sbit  MISO =P1^6;  //nRF24L01引脚定义
  7. sbit  MOSI =P1^5;
  8. sbit  SCK  =P1^7;
  9. sbit  CE   =P1^2;
  10. sbit  CSN  =P1^3;
  11. sbit  IRQ  =P1^4;
  12. //************************************按键***************************************************
  13. sbit        KEY1=P3^5;
  14. sbit        KEY2=P3^4;
  15. //************************************数码管位选*********************************************
  16. sbit        led3=P2^0;
  17. sbit        led2=P2^1;
  18. sbit        led1=P2^2;
  19. sbit        led0=P2^3;
  20. sbit        le1=P1^0;
  21. sbit        le2=P1^1;
  22. //************************************蜂明器***************************************************
  23. sbit         BELL=P3^6;
  24. int n;
  25. uchar num;

  26. //***********************************数码管0-9编码*******************************************
  27. uchar seg[10]={0xC0,0xCF,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};         //0~~9段码
  28. uchar seg1[10]={0x40,0x4F,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};         //0~~9段码
  29. char temp[6];
  30. uchar RxBuf[20]={0};
  31. //*********************************************NRF24L01*************************************
  32. #define TX_ADR_WIDTH    5           // 5 uints TX address width
  33. #define RX_ADR_WIDTH    5           // 5 uints RX address width
  34. #define TX_PLOAD_WIDTH  20          // 20 uints TX payload
  35. #define RX_PLOAD_WIDTH  20          // 20 uints TX payload
  36. uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //本地地址
  37. uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //接收地址
  38. //***************************************NRF24L01寄存器指令*******************************************************
  39. #define READ_REG        0x00          // 读寄存器指令
  40. #define WRITE_REG       0x20         // 写寄存器指令
  41. #define RD_RX_PLOAD     0x61          // 读取接收数据指令
  42. #define WR_TX_PLOAD     0xA0          // 写待发数据指令
  43. #define FLUSH_TX        0xE1         // 冲洗发送 FIFO指令
  44. #define FLUSH_RX        0xE2          // 冲洗接收 FIFO指令
  45. #define REUSE_TX_PL     0xE3          // 定义重复装载数据指令
  46. #define NOP             0xFF          // 保留
  47. //*************************************SPI(nRF24L01)寄存器地址****************************************************
  48. #define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
  49. #define EN_AA           0x01  // 自动应答功能设置
  50. #define EN_RXADDR       0x02  // 可用信道设置
  51. #define SETUP_AW        0x03  // 收发地址宽度设置
  52. #define SETUP_RETR      0x04  // 自动重发功能设置
  53. #define RF_CH           0x05  // 工作频率设置
  54. #define RF_SETUP        0x06  // 发射速率、功耗功能设置
  55. #define STATUS          0x07  // 状态寄存器
  56. #define OBSERVE_TX      0x08  // 发送监测功能
  57. #define CD              0x09  // 地址检测           
  58. #define RX_ADDR_P0      0x0A  // 频道0接收数据地址
  59. #define RX_ADDR_P1      0x0B  // 频道1接收数据地址
  60. #define RX_ADDR_P2      0x0C  // 频道2接收数据地址
  61. #define RX_ADDR_P3      0x0D  // 频道3接收数据地址
  62. #define RX_ADDR_P4      0x0E  // 频道4接收数据地址
  63. #define RX_ADDR_P5      0x0F  // 频道5接收数据地址
  64. #define TX_ADDR         0x10  // 发送地址寄存器
  65. #define RX_PW_P0        0x11  // 接收频道0接收数据长度
  66. #define RX_PW_P1        0x12  // 接收频道0接收数据长度
  67. #define RX_PW_P2        0x13  // 接收频道0接收数据长度
  68. #define RX_PW_P3        0x14  // 接收频道0接收数据长度
  69. #define RX_PW_P4        0x15  // 接收频道0接收数据长度
  70. #define RX_PW_P5        0x16  // 接收频道0接收数据长度
  71. #define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
  72. //**************************************************************************************
  73. void Delay(unsigned int s);
  74. void inerDelay_us(unsigned char n);
  75. void init_NRF24L01(void);
  76. uint SPI_RW(uint uchar);
  77. uchar SPI_Read(uchar reg);
  78. void SetRX_Mode(void);
  79. uint SPI_RW_Reg(uchar reg, uchar value);
  80. uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
  81. uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
  82. unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
  83. void nRF24L01_TxPacket(unsigned char * tx_buf);
  84. //*****************************************长延时*****************************************
  85. void Delay(unsigned int s)
  86. {
  87.         unsigned int i;
  88.         for(i=0; i<s; i++);
  89.         for(i=0; i<s; i++);
  90. }
  91. //******************************************************************************************
  92. uint         bdata sta;   //状态标志
  93. sbit        RX_DR        =sta^6;
  94. sbit        TX_DS        =sta^5;
  95. sbit        MAX_RT        =sta^4;
  96. /******************************************************************************************
  97. /*延时函数
  98. /******************************************************************************************/
  99. void inerDelay_us(unsigned char n)
  100. {
  101.         for(;n>0;n--)
  102.                 _nop_();
  103. }
  104. //****************************************************************************************
  105. /*NRF24L01初始化
  106. //***************************************************************************************/
  107. void init_NRF24L01(void)
  108. {
  109.   inerDelay_us(100);
  110.          CE=0;    // chip enable
  111.          CSN=1;   // Spi disable
  112.          SCK=0;   // Spi clock line init high
  113.         SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址        
  114.         SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
  115.         SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                                                       //  频道0自动        ACK应答允许        
  116.         SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道,可以参考Page21  
  117.   SPI_RW_Reg(WRITE_REG + RF_CH, 40);        //   设置信道工作为2.4GHZ,收发必须一致
  118.         SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32纸?
  119.         SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);                   //设置发射速率为1MHZ,发射功率为最大值0dB

  120. }

  121. /****************************************************************************************************
  122. /*函数:uint SPI_RW(uint uchar)
  123. /*功能:NRF24L01的SPI写时序
  124. /*详细请参考Page19
  125. /****************************************************************************************************/
  126. uint SPI_RW(uint uchar)
  127. {
  128.         uint bit_ctr;
  129.            for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
  130.            {
  131.                 MOSI = (uchar & 0x80);         // output 'uchar', MSB to MOSI
  132.                 uchar = (uchar << 1);           // shift next bit into MSB..
  133.                 SCK = 1;                      // Set SCK high..
  134.                 uchar |= MISO;                         // capture current MISO bit
  135.                 SCK = 0;                              // ..then set SCK low again
  136.            }
  137.     return(uchar);                             // return read uchar
  138. }
  139. /****************************************************************************************************
  140. /*函数:uchar SPI_Read(uchar reg)
  141. /*功能:NRF24L01的SPI时序
  142. /*详细请参考Page19
  143. /****************************************************************************************************/
  144. uchar SPI_Read(uchar reg)
  145. {
  146.         uchar reg_val;
  147.         
  148.         CSN = 0;                // CSN low, initialize SPI communication...
  149.         SPI_RW(reg);            // Select register to read from..
  150.         reg_val = SPI_RW(0);    // ..then read registervalue
  151.         CSN = 1;                // CSN high, terminate SPI communication
  152.         
  153.         return(reg_val);        // return register value
  154. }
  155. /****************************************************************************************************/
  156. /*功能:NRF24L01读写寄存器函数
  157. /****************************************************************************************************/
  158. uint SPI_RW_Reg(uchar reg, uchar value)
  159. {
  160.         uint status;
  161.         
  162.         CSN = 0;                   // CSN low, init SPI transaction
  163.         status = SPI_RW(reg);      // select register
  164.         SPI_RW(value);             // ..and write value to it..
  165.         CSN = 1;                   // CSN high again
  166.         
  167.         return(status);            // return nRF24L01 status uchar
  168. }
  169. /****************************************************************************************************/
  170. /*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
  171. /*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
  172. /****************************************************************************************************/
  173. uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
  174. {
  175.         uint status,uchar_ctr;
  176.         
  177.         CSN = 0;                                    // Set CSN low, init SPI tranaction
  178.         status = SPI_RW(reg);                       // Select register to write to and read status uchar
  179.         
  180.         for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
  181.                 pBuf[uchar_ctr] = SPI_RW(0);    //
  182.         
  183.         CSN = 1;                           
  184.         
  185.         return(status);                    // return nRF24L01 status uchar
  186. }
  187. /*********************************************************************************************************
  188. /*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  189. /*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
  190. /*********************************************************************************************************/
  191. uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  192. {
  193.         uint status,uchar_ctr;
  194.         
  195.         CSN = 0;            //SPI使能      
  196.         status = SPI_RW(reg);   
  197.         for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
  198.                 SPI_RW(*pBuf++);
  199.         CSN = 1;           //关闭SPI
  200.         return(status);    //
  201. }
  202. /****************************************************************************************************/
  203. /*函数:void SetRX_Mode(void)
  204. /*功能:数据接收配置
  205. /****************************************************************************************************/
  206. void SetRX_Mode(void)
  207. {
  208.         CE=0;
  209.         SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);                   // IRQ收发完成中断响应,16位CRC        ,主接收
  210.         CE = 1;
  211.         inerDelay_us(130);
  212. }
  213. /******************************************************************************************************/
  214. /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
  215. /*功能:数据读取后放如rx_buf接收缓冲区中
  216. /******************************************************************************************************/
  217. unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
  218. {
  219.     unsigned char revale=0;
  220.         sta=SPI_Read(STATUS);        // 读取状态寄存其来判断数据接收状况
  221.         if(RX_DR)                                // 判断是否接收到数据
  222.         {
  223.             CE = 0;                        
  224.         SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
  225.                 revale =1;                        //读取数据完成标志
  226.         }
  227.         SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来其清除中断标志
  228.         return revale;
  229. }
  230. /***********************************************************************************************************
  231. /*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
  232. /*功能:发送 tx_buf中数据
  233. /**********************************************************************************************************/
  234. void nRF24L01_TxPacket(unsigned char * tx_buf)
  235. {
  236.         CE=0;                        //StandBy I模式        
  237.         SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
  238.         SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);                          // 装载数据        
  239.         SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);                    // IRQ收发完成中断响应,16位CRC,主发送
  240.         CE=1;                 //置高CE,激发数据发送
  241.         inerDelay_us(10);
  242. }
  243. //***********************************************串口初始化***********************************************
  244. void StartUART( void )        
  245. {                                                  
  246.      SCON = 0x50;
  247.      TMOD = 0x20;
  248.      TH1 = 0xFA;
  249.      TL1 = 0xFA;                        //波特率4800
  250.      PCON = 0x00;
  251.      TR1 = 1;
  252. }
  253. //***********************************************通过串口向PC发送***********************************************
  254. void R_S_Byte(uchar R_Byte)
  255. {        
  256.          SBUF = R_Byte;  
  257.      while( TI == 0 );                                //查询法
  258.            TI = 0;   
  259. }
  260. //***********************************************数码动态扫描显示***********************************************
  261. void disdignit()
  262. {
  263.         P0=0xC6;                          //C
  264.         led0=0;
  265.         Delay(10);
  266.         led0=1;
  267.         P0=seg[temp[1]];          //小数位
  268.         led1=0;
  269.         Delay(10);
  270.         led1=1;
  271.         P0=seg1[temp[5]];    //十位
  272.         led2=0;
  273.         Delay(10);
  274.         led2=1;
  275.         P0=seg[temp[4]];           //个位
  276.         led3=0;
  277.         Delay(10);
  278.         led3=1;
  279. }
  280. //************************************主函数************************************************************
  281. void main(void)
  282. {
  283.         uchar i=0;        
  284.   init_NRF24L01() ;                        //NRF24L01初始化
  285.         StartUART();
  286.         Delay(1);
  287.         BELL=1;

  288.         while(1)
  289.         {
  290. //***********************************************************************************************
  291.         SetRX_Mode();
  292.                    if(nRF24L01_RxPacket(RxBuf))
  293.                 {
  294.                         temp[0]=RxBuf[3];                                                      //符号位
  295.                         temp[2]=((RxBuf[2]<<4)|RxBuf[1]);                        //整数位
  296.                         temp[1]=RxBuf[0];                                                        //小数位
  297.                   temp[4]=RxBuf[2];                                                        //十位
  298.                    temp[5]=RxBuf[1];                                                        //个位
  299.                         disdignit();                //数码管显示温度
  300.                         R_S_Byte('t');     //串口显示温度
  301.                         disdignit();                //数码管显示温度
  302.                         disdignit();                //数码管显示温度
  303.                         R_S_Byte(0x30+temp[4]);     //串口显示温度
  304.                         R_S_Byte(0x30+temp[5]);     //串口显示温度
  305.                         R_S_Byte('.');              //串口显示温度
  306.                         R_S_Byte(0x30+temp[1]);     //串口显示温度
  307.                         disdignit();                //数码管显示温度
  308.                         disdignit();                //数码管显示温度
  309.                         disdignit();                //数码管显示温度
  310.                         for(i=0;i<3;i++)
  311.                         {
  312.                         R_S_Byte(temp[2-i]);     //串口显示温度
  313.                         Delay(60);
  314.                         }
  315.                 }
  316.                         disdignit();                //数码管显示温度
  317.                         
  318.                 if(temp[2]>=0x30)                        //大于30度时报警,0x30转换成10进制为48
  319.                 {
  320.                         
  321.                         BELL=0;                           //打开蜂明器
  322.                         Delay(10);
  323.                 }
  324.                 else
  325.                 {
  326.                         BELL=1;                  //关闭蜂明器
  327.         }        

  328.                
  329.                
  330.                 }
  331. }


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

使用道具 举报

沙发
ID:390416 发表于 2021-4-23 09:45 | 只看该作者
很简单啊  设置一组频率表,如果通信失败 那么就改变频率。发送端的顺时针选频,接收端不断的逆时针选频。两者保持一定的速度差。那么 总会有一个频率碰上的。
回复

使用道具 举报

板凳
ID:895128 发表于 2021-4-27 12:36 | 只看该作者
重点是怎么改变频率,因为频率是一开始就初始化的。
回复

使用道具 举报

地板
ID:490426 发表于 2022-7-20 15:47 | 只看该作者
想问楼主这个能改吗?我改 了就通信不上了,是这样改吗
回复

使用道具 举报

5#
ID:879348 发表于 2022-7-20 15:49 | 只看该作者
改变频道即可,没什么难度的
回复

使用道具 举报

6#
ID:1062022 发表于 2023-2-2 21:44 | 只看该作者
最近入门也在研究这个24L01 正好也用得上这个跳频,只不过我这是单向发送的
SPI_RW_Reg(WRITE_REG + RF_CH, 40); 直接给后面这个信道给一个变量
例如SPI_RW_Reg(WRITE_REG + RF_CH, xindao);
然后在main函数大循环里面写个类似于这样的
if(key1==0)
                        xindao = 60;
if(key1==1)
                        xindao = 40;
我实验了一下是可行的
回复

使用道具 举报

7#
ID:1034262 发表于 2023-2-2 22:55 | 只看该作者
直接给通道值就可以了。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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