找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3694|回復: 3
打印 上一主題 下一主題
收起左側

nRF24L01硬件SPI無線雙向通訊單片機程序

[復制鏈接]
跳轉到指定樓層
#
ID:386826 發(fā)表于 2019-1-10 22:00 | 只看該作者 回帖獎勵 |正序瀏覽 |閱讀模式
stc實例無線雙向通訊代碼
nRF24L01雙向通訊實驗步驟:
1:將TXRX程序下載到兩塊EasySTC15開發(fā)板(開發(fā)板A和開發(fā)板B)中。
2:按下開發(fā)板A上的按鍵S3,可以看到開發(fā)板B上的RGB指示燈中的紅燈狀態(tài)翻轉。
2:按下開發(fā)板B上的按鍵S3,可以看到開發(fā)板A上的RGB指示燈中的紅燈狀態(tài)翻轉。

單片機源程序如下:
  1. /****************************************Copyright (c)****************************************************
  2. **                                       
  3. **                                 
  4. **
  5. **--------------File Info---------------------------------------------------------------------------------
  6. ** File name:                       
  7. ** Last modified Date:         
  8. ** Last Version:                  
  9. ** Descriptions:                                                       
  10. **--------------------------------------------------------------------------------------------------------
  11. ** Created by:                        FiYu
  12. ** Created date:                2016-3-5
  13. ** Version:                            1.0
  14. ** Descriptions:                nRF24L01無線雙向通訊(硬件SPI)                                       
  15. **--------------------------------------------------------------------------------------------------------
  16. ** Modified by:                        FiYu
  17. ** Modified date:               
  18. ** Version:                               
  19. ** Descriptions:               
  20. ** Rechecked by:                       
  21. **********************************************************************************************************/
  22. /****-----參考:宏晶科技的有關資料及程序-------***********/
  23. #include <STC15F2K60S2.h>

  24. #define  uint unsigned int  
  25. #define  uchar unsigned char

  26. //無線收發(fā)地址寬度(字節(jié)數(shù))
  27. #define TX_ADDR_WIDTH 5
  28. #define RX_ADDR_WIDTH 5

  29. //無線收發(fā)數(shù)據(jù)長度(字節(jié)數(shù))
  30. #define TX_PLOAD_WIDTH 1
  31. #define RX_PLOAD_WIDTH 1

  32. #define SPIF 0x80 //SPSTAT.7
  33. #define WCOL 0x40 //SPSTAT.6
  34. #define SSIG 0x80 //SPCTL.7
  35. #define SPEN 0x40 //SPCTL.6
  36. #define DORD 0x20 //SPCTL.5
  37. #define MSTR 0x10 //SPCTL.4
  38. #define CPOL 0x08 //SPCTL.3
  39. #define CPHA 0x04 //SPCTL.2
  40. #define SPDHH 0x00 //CPU_CLK/4
  41. #define SPDH 0x01 //CPU_CLK/8
  42. #define SPDL 0x02 //CPU_CLK/16
  43. #define SPDLL 0x03 //CPU_CLK/32

  44. /****************************************************************************************************/
  45. //NRF24L01寄存器操作命令
  46. #define SPI_READ_REG    0x00  //讀配置寄存器,低5位為寄存器地址
  47. #define SPI_WRITE_REG   0x20  //寫配置寄存器,低5位為寄存器地址
  48. #define RD_RX_PLOAD     0x61  //讀RX有效數(shù)據(jù),1~32字節(jié)
  49. #define WR_TX_PLOAD     0xA0  //寫TX有效數(shù)據(jù),1~32字節(jié)
  50. #define FLUSH_TX        0xE1  //清除TX FIFO寄存器.發(fā)射模式下用
  51. #define FLUSH_RX        0xE2  //清除RX FIFO寄存器.接收模式下用
  52. #define REUSE_TX_PL     0xE3  //重新使用上一包數(shù)據(jù),CE為高,數(shù)據(jù)包被不斷發(fā)送.
  53. #define NOP             0xFF  //空操作,可以用來讀狀態(tài)寄存器         
  54. //SPI(NRF24L01)寄存器地址
  55. #define CONFIG          0x00  //配置寄存器地址;bit0:1接收模式,0發(fā)射模式;bit1:電選擇;bit2:CRC模式;bit3:CRC使能;
  56.                               //bit4:中斷MAX_RT(達到最大重發(fā)次數(shù)中斷)使能;bit5:中斷TX_DS使能;bit6:中斷RX_DR使能
  57. #define EN_AA           0x01  //使能自動應答功能  bit0~5,對應通道0~5
  58. #define EN_RXADDR       0x02  //接收地址允許,bit0~5,對應通道0~5
  59. #define SETUP_AW        0x03  //設置地址寬度(所有數(shù)據(jù)通道):bit1,0:00,3字節(jié);01,4字節(jié);02,5字節(jié);
  60. #define SETUP_RETR      0x04  //建立自動重發(fā);bit3:0,自動重發(fā)計數(shù)器;bit7:4,自動重發(fā)延時 250*x+86us
  61. #define RF_CH           0x05  //RF通道,bit6:0,工作通道頻率;
  62. #define RF_SETUP        0x06  //RF寄存器;bit3:傳輸速率(0:1Mbps,1:2Mbps);bit2:1,發(fā)射功率;bit0:低噪聲放大器增益
  63. #define STATUS          0x07  //狀態(tài)寄存器;bit0:TX FIFO滿標志;bit3:1,接收數(shù)據(jù)通道號(最大:6);bit4,達到最多次重發(fā)
  64.                               //bit5:數(shù)據(jù)發(fā)送完成中斷;bit6:接收數(shù)據(jù)中斷;
  65. #define MAX_TX              0x10    //達到最大發(fā)送次數(shù)中斷
  66. #define TX_OK               0x20    //TX發(fā)送完成中斷
  67. #define RX_OK               0x40    //接收到數(shù)據(jù)中斷

  68. #define OBSERVE_TX      0x08  //發(fā)送檢測寄存器,bit7:4,數(shù)據(jù)包丟失計數(shù)器;bit3:0,重發(fā)計數(shù)器
  69. #define CD              0x09  //載波檢測寄存器,bit0,載波檢測;
  70. #define RX_ADDR_P0      0x0A  //數(shù)據(jù)通道0接收地址,最大長度5個字節(jié),低字節(jié)在前
  71. #define RX_ADDR_P1      0x0B  //數(shù)據(jù)通道1接收地址,最大長度5個字節(jié),低字節(jié)在前
  72. #define RX_ADDR_P2      0x0C  //數(shù)據(jù)通道2接收地址,最低字節(jié)可設置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;
  73. #define RX_ADDR_P3      0x0D  //數(shù)據(jù)通道3接收地址,最低字節(jié)可設置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;
  74. #define RX_ADDR_P4      0x0E  //數(shù)據(jù)通道4接收地址,最低字節(jié)可設置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;
  75. #define RX_ADDR_P5      0x0F  //數(shù)據(jù)通道5接收地址,最低字節(jié)可設置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;
  76. #define TX_ADDR         0x10  //發(fā)送地址(低字節(jié)在前),ShockBurstTM模式下,RX_ADDR_P0與此地址相等
  77. #define RX_PW_P0        0x11  //接收數(shù)據(jù)通道0有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
  78. #define RX_PW_P1        0x12  //接收數(shù)據(jù)通道1有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
  79. #define RX_PW_P2        0x13  //接收數(shù)據(jù)通道2有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
  80. #define RX_PW_P3        0x14  //接收數(shù)據(jù)通道3有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
  81. #define RX_PW_P4        0x15  //接收數(shù)據(jù)通道4有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
  82. #define RX_PW_P5        0x16  //接收數(shù)據(jù)通道5有效數(shù)據(jù)寬度(1~32字節(jié)),設置為0則非法
  83. #define FIFO_STATUS     0x17  //FIFO狀態(tài)寄存器;bit0,RX FIFO寄存器空標志;bit1,RX FIFO滿標志;bit2,3,保留
  84.                               //bit4,TX FIFO空標志;bit5,TX FIFO滿標志;bit6,1,循環(huán)發(fā)送上一數(shù)據(jù)包.0,不循環(huán);
  85.                                                                                                                        
  86. #define CE_LOW        en=0
  87. #define CE_HIGH       en=1
  88. #define CS_LOW        SPI_CS=0
  89. #define CS_HIGH       SPI_CS=1
  90.                                                                                                                        
  91. const uchar TX_ADDRESS[TX_ADDR_WIDTH]={0xE1,0xE2,0xE3,0xE4,0xE5}; //發(fā)送地址
  92. const uchar RX_ADDRESS[RX_ADDR_WIDTH]={0xE1,0xE2,0xE3,0xE4,0xE5}; //接收地址       
  93. uchar  RxPayload[32];   //無線接收緩存
  94. uchar  TxPayload[32];   //無線發(fā)送緩存

  95. /**********************
  96. 引腳別名定義
  97. ***********************/       
  98. sbit IRQ=P3^3;        //中斷
  99. sbit en=P3^2;         //使能控制
  100. sbit SPI_CS=P1^2;     //片選

  101. sbit KEY=P0^4;            //用戶按鍵S3用IO口P04
  102. sbit LED_B=P0^5;   //三色指示燈之藍色LED用IO口P05
  103. sbit LED_R=P0^6;   //三色指示燈之紅色LED用IO口P06
  104. /**************************************
  105. 功能描述:延時函數(shù)
  106. 入口參數(shù):uint x ,該值為1時,延時1ms
  107. 返回值:無
  108. ***************************************/
  109. void delay_ms(uint x)
  110. {  
  111.         uint j,i;   
  112.         for(j=0;j<x;j++)   
  113.         {   
  114.                 for(i=0;i<1100;i++);   
  115.         }  
  116. }

  117. /***************************************************************************
  118. * 描  述 : 初始化SPI
  119. * 入  參 : 無
  120. * 返回值 : 無
  121. **************************************************************************/
  122. void InitSPI(void)
  123. {
  124.   SPDAT = 0; //初始化SPI數(shù)據(jù)
  125.   SPSTAT = SPIF | WCOL; //清除SPI狀態(tài)位
  126.   SPCTL = SPEN | MSTR | SSIG; //主機模式
  127. }

  128. /***************************************************************************
  129. * 描  述 : 模擬SPI讀寫數(shù)據(jù)函數(shù),讀寫一個字節(jié)
  130. * 入  參 : 寫入的數(shù)據(jù)
  131. * 返回值 : 讀取的數(shù)據(jù)
  132. **************************************************************************/
  133. uchar SPI_RW(uchar byte)
  134. {
  135.   SPDAT = byte; //觸發(fā)SPI發(fā)送數(shù)據(jù)
  136.   while (!(SPSTAT & SPIF)); //等待發(fā)送完成
  137.   SPSTAT = SPIF | WCOL; //清除SPI狀態(tài)位
  138.   return SPDAT; //返回SPI數(shù)據(jù)
  139. }

  140. /***************************************************************************
  141. * 描  述 : NRF24L01寄存器寫函數(shù)
  142. * 入  參 : regaddr:要寫的寄存器地址;data:寫入到寄存器的數(shù)據(jù)
  143. * 返回值 : 讀取的狀態(tài)值
  144. **************************************************************************/
  145. uchar NRF24L01_Write_Reg(uchar regaddr,uchar dat)
  146. {
  147.         uchar status;       
  148.        
  149.   CS_LOW;  
  150.         status =SPI_RW(regaddr);
  151.   SPI_RW(dat);             //寫入寄存器的值
  152.   CS_HIGH;              //禁止SPI傳輸       
  153.   return(status);                //返回狀態(tài)值
  154. }

  155. /***************************************************************************
  156. * 描  述 : NRF24L01寄存器讀函數(shù)
  157. * 入  參 : regaddr:要讀取的寄存器地址
  158. * 返回值 : 讀取的寄存器的值
  159. **************************************************************************/
  160. uchar NRF24L01_Read_Reg(uchar regaddr)
  161. {
  162.         uchar reg_val;          
  163.   
  164.         CS_LOW;                          //使能SPI傳輸       
  165.         SPI_RW(regaddr);
  166.         reg_val=SPI_RW(0XFF);
  167.   CS_HIGH;                         //禁止SPI傳輸               
  168.   return(reg_val);                 //返回讀取的值
  169. }       
  170. /***************************************************************************
  171. * 描  述 : 從指定地址讀出指定長度的數(shù)據(jù)
  172. * 入  參 : pBuf:讀出數(shù)據(jù)的存放地址;datlen:讀出的數(shù)據(jù)字節(jié)數(shù)
  173. * 返回值 : 讀取的寄存器的值
  174. **************************************************************************/
  175. uchar NRF24L01_Read_Buf(uchar regaddr,uchar *pBuf,uchar datlen)
  176. {
  177.         uchar status,u8_ctr;               
  178.   CS_LOW;                               //使能SPI傳輸
  179.         status=SPI_RW(regaddr);
  180.         for(u8_ctr=0;u8_ctr<datlen;u8_ctr++)
  181.         {
  182.                 pBuf[u8_ctr]=SPI_RW(0XFF);//讀出數(shù)據(jù)
  183.         }
  184.   CS_HIGH;                              //關閉SPI傳輸

  185.   return status;                        //返回讀到的狀態(tài)值
  186. }
  187. /***************************************************************************
  188. * 描  述 : 向指定地址寫入指定長度的數(shù)據(jù)
  189. * 入  參 : pBuf:讀出數(shù)據(jù)的存放地址;datlen:讀出的數(shù)據(jù)字節(jié)數(shù)
  190. * 返回值 : 讀取的狀態(tài)寄存器值
  191. **************************************************************************/
  192. uchar NRF24L01_Write_Buf(uchar regaddr, uchar *pBuf, uchar datalen)
  193. {
  194.         uchar status,u8_ctr;            
  195.         CS_LOW;                                              //使能SPI傳輸
  196.         status = SPI_RW(regaddr);  
  197. for(u8_ctr=0; u8_ctr<datalen; u8_ctr++)
  198. {
  199.         SPI_RW(*pBuf++); //寫入數(shù)據(jù)               
  200. }
  201.   CS_HIGH;                                             //關閉SPI傳輸
  202.   return status;                                       //返回讀到的狀態(tài)值
  203. }       
  204. /***************************************************************************
  205. * 描  述 : NRF24L01初始化函數(shù),初始化連接NRF24L01模塊的管腳,調用SPI初始化函數(shù)
  206. *          完成和NRF24L01模塊通訊的SPI總線的初始化
  207. * 入  參 : 無
  208. * 返回值 : 無
  209. **************************************************************************/
  210. void Init_NRF24L01(void)
  211. {       
  212.         delay_ms(2);
  213.         LED_B=1;
  214.         CE_LOW;                                         //使能NRF24L01
  215.         CS_HIGH;                                  //SPI片選取消
  216.         InitSPI();
  217. }
  218. /***************************************************************************
  219. * 描  述 : 啟動NRF24L01發(fā)送一次數(shù)據(jù)
  220. * 入  參 : buf:待發(fā)送數(shù)據(jù)首地址
  221. * 返回值 : 發(fā)送完成狀況
  222. **************************************************************************/
  223. uchar NRF24L01_TxPacket(uchar *buf)
  224. {
  225.         uchar state,retVal = 0xff;   
  226.        
  227.         CE_LOW;
  228.         //寫TX節(jié)點地址
  229.         NRF24L01_Write_Reg(SPI_WRITE_REG+CONFIG,0x0e);
  230.   NRF24L01_Write_Buf(SPI_WRITE_REG+TX_ADDR,(uchar*)TX_ADDRESS,TX_ADDR_WIDTH);  
  231.   NRF24L01_Write_Buf(WR_TX_PLOAD,buf,TX_PLOAD_WIDTH);  //寫數(shù)據(jù)到TX BUF
  232.         CE_HIGH;                                             //啟動發(fā)送          
  233.         while(IRQ!=0);                                       //等待發(fā)送完成
  234.         state=NRF24L01_Read_Reg(STATUS);                     //讀取狀態(tài)寄存器的值          
  235.         NRF24L01_Write_Reg(SPI_WRITE_REG+STATUS,state);      //清除TX_DS或MAX_RT中斷標志
  236.         if(state&MAX_TX)                                     //達到最大重發(fā)次數(shù)
  237.         {
  238.                 NRF24L01_Write_Reg(FLUSH_TX,0xff);                 //清除TX FIFO寄存器
  239.                 retVal = MAX_TX;
  240.         }
  241.         if(state&TX_OK)                                      //發(fā)送完成
  242.         {
  243.                 retVal = TX_OK;
  244.         }
  245.         CE_LOW;
  246.         NRF24L01_Write_Reg(SPI_WRITE_REG+CONFIG, 0x0f);
  247.         CE_HIGH;
  248.         return retVal;                                         //其他原因發(fā)送失敗
  249. }
  250. /***************************************************************************
  251. * 描  述 : 啟動NRF24L01讀取一次數(shù)據(jù)
  252. * 入  參 : buf:待發(fā)送數(shù)據(jù)首地址
  253. * 返回值 : RX_OK:接收到數(shù)據(jù);0:未接收到數(shù)據(jù)
  254. **************************************************************************/
  255. uchar NRF24L01_RxPacket(uchar *buf)
  256. {
  257.         uchar state;                    
  258.        
  259.         state=NRF24L01_Read_Reg(STATUS);                //讀取狀態(tài)寄存器的值             
  260.         NRF24L01_Write_Reg(SPI_WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中斷標志
  261.         if(state&RX_OK)                                    //接收到數(shù)據(jù)
  262.         {
  263.                 NRF24L01_Read_Buf(RD_RX_PLOAD,buf,RX_PLOAD_WIDTH);//讀取數(shù)據(jù)
  264.                 NRF24L01_Write_Reg(FLUSH_RX,0xff);            //清除RX FIFO寄存器
  265.                 return RX_OK;
  266.         }          
  267.         return 0;                                           //沒收到任何數(shù)據(jù)
  268. }
  269. /***************************************************************************
  270. * 描  述 : 初始化NRF24L01到RX模式,配置相關參數(shù),CE變高后,即進入RX模式
  271. * 入  參 : 無
  272. * 返回值 : 無
  273. **************************************************************************/
  274. void Set_RxMode(void)
  275. {
  276.         CE_LOW;          
  277.         // Delay_1ms(20);
  278.   //寫RX節(jié)點地址
  279.   NRF24L01_Write_Buf(SPI_WRITE_REG+RX_ADDR_P0,(uchar*)RX_ADDRESS,RX_ADDR_WIDTH);

  280.   //關閉通道0的自動應答   
  281.   NRF24L01_Write_Reg(SPI_WRITE_REG+EN_AA,0x00);   
  282.   //使能通道0的接收地址           
  283.   NRF24L01_Write_Reg(SPI_WRITE_REG+EN_RXADDR,0x01);
  284.   //設置RF通信頻率                  
  285.   NRF24L01_Write_Reg(SPI_WRITE_REG+RF_CH,55);             
  286.   //選擇通道0的有效數(shù)據(jù)寬度             
  287.   NRF24L01_Write_Reg(SPI_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);
  288.   //設置TX發(fā)射參數(shù),0db增益,2Mbps,低噪聲增益開啟   
  289.   NRF24L01_Write_Reg(SPI_WRITE_REG+RF_SETUP,0x26);
  290.   //配置基本工作模式的參數(shù);PWR_UP,EN_CRC,16BIT_CRC,PRIM_RX接收模式
  291.   NRF24L01_Write_Reg(SPI_WRITE_REG+CONFIG, 0x0f);
  292.   //CE為高,進入接收模式
  293.   CE_HIGH;              
  294. }       
  295. /***************************************************************************
  296. * 描  述 : 主函數(shù)
  297. * 入  參 : 無
  298. * 返回值 : 無
  299. **************************************************************************/
  300. int main()            //主函數(shù)
  301. {     
  302. /////////////////////////////////////////////////
  303. //注意: STC15W4K32S4系列的芯片,上電后所有與PWM相關的IO口均為
  304. //      高阻態(tài),需將這些口設置為準雙向口或強推挽模式方可正常使用
  305. //相關IO: P0.6/P0.7/P1.6/P1.7/P2.1/P2.2
  306. //        P2.3/P2.7/P3.7/P4.2/P4.4/P4.5
  307. /////////////////////////////////////////////////
  308.         P0M1 = 0;        P0M0 = 0;        //設置P0.0~P0.7為準雙向口
  309.         P2M1 = 0;        P2M0 = 0;        //設置P2.0~P2.7為準雙向口
  310.         P3M1 = 0;        P3M0 = 0;        //設置P3.0~P3.7為準雙向口
  311.         P4M1 = 0;        P4M0 = 0;        //設置P4.0~P4.7為準雙向口
  312.         P5M1 = 0;        P5M0 = 0;        //設置P5.0~P5.7為準雙向口
  313.        
  314.         Init_NRF24L01();                //初始化
  315.         Set_RxMode();                                                  //配置nRF24L01為發(fā)送模式
  316.        
  317.   while(1)
  318.   {
  319.           if(KEY == 0)//按鍵按下
  320.           {
  321.             delay_ms(10);
  322.             if(KEY== 0)         //延時去抖動   
  323.             {
  324.                     LED_B=0;
  325.                                 while(KEY == 0); //等待按鍵釋放
  326.                                
  327.         TxPayload[0] = 0x5A;
  328.                                 LED_B=1;
  329.                                 if(NRF24L01_TxPacket(TxPayload) == TX_OK)        //如果發(fā)送成功
  330.                     {
  331.                         //無線發(fā)射成功        
  332.                     }
  333.                     else
  334.                     {
  335.             //添加錯誤處理代碼
  336.         }
  337.             }
  338.           }
  339.                 if(NRF24L01_RxPacket(RxPayload) == RX_OK)        //如果接收成功
  340.                 {
  341.       if(RxPayload[0] == 0x5A)               
  342.       {
  343.                                 LED_R=~LED_R;//NRF24L01模塊狀態(tài)指示燈翻轉
  344.                                 RxPayload[0] = 0;
  345.       }                       
  346.                 }
  347.         }
  348. }
復制代碼

所有資料51hei提供下載:
nRF24L01_TxRx(硬件SPI).zip (48.89 KB, 下載次數(shù): 109)



評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

板凳
ID:501909 發(fā)表于 2019-7-9 10:34 | 只看該作者
感謝樓主 分享
回復

使用道具 舉報

沙發(fā)
ID:234782 發(fā)表于 2019-7-9 10:05 | 只看該作者
注釋不怎么好
回復

使用道具 舉報

樓主
ID:243748 發(fā)表于 2019-2-24 12:10 來自手機 | 只看該作者
上個電路圖呀,不懂接線
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表