久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機驅動NRF24L01雙向通信調試通過

[復制鏈接]
跳轉到指定樓層
樓主
ID:79544 發表于 2016-5-1 07:44 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
經過幾個星期的折騰,NRF24L01無線模塊終于調試通過。現在附上程序,我用的是2片不一樣的單片機。程序里有詳細解釋。希望對大家有幫助。程序是來自網絡的感謝作者的無私分享!
  1. /***************************************************
  2. //NRF24L01調試程序,全雙工雙向通信,即兩個模塊兼具收發功能,
  3. 自動高速切換收發模式。
  4. //使用本程序的前提條件是:硬件沒問題。如果能正確運行本程序,
  5. 也能說明你的硬件電路沒問題。
  6. //大家根據實際情況,更改 NRF24L01 各引腳、LED 和 KEY 的宏定義。
  7. //LED燈的狀態由RxBuf[0]來決定,RxBuf[0] == 0,
  8. LED輸出0;RxBuf[0] == 1,LED輸出1;你也可以自行更改規則。
  9. //KEY可以改變TxBuf[0]的值,從而改變另一起模塊RxBuf[0]的值,
  10. 進而改變LED的狀態。
  11. //此程序未用到外部中斷,即不響應IRQ 因此IRQ引腳可以接任意I/O口,
  12. 不必接到外部中斷引腳,不過建議接到外部中斷引腳。
  13. ***************************************************/

  14. /********************************************************
  15.         功   能:甲單片機通過NRF24L01發送數據乙單片機接收
  16.                         通過LED指示。同理乙單片機發送數據甲單片機接收
  17.                         通過LED指示,實現雙機相互通信。
  18.                                 調試通過
  19.         甲單片機:STC12C5608AD
  20.         乙單片機:STC12C5A60S2
  21.         晶    振:11.0592M
  22.         作    者:蘇義江改編自網絡《感謝作者》
  23.         時    間:2016.5.1
  24.         注    釋:如果甲乙單片機是一種型號NRF24L01的端口可以
  25.                         都用一組IO口(例甲單片機用PO口乙單片機也用P0口
  26.                         程序里的IO就不用換啦)
  27. *********************************************************/
  28. #include<reg52.h>
  29. #include<intrins.h>

  30. #define uchar unsigned char
  31. #define uint unsigned int

  32. void delayus(uint us)
  33. {
  34.         for(;us >0;us--)
  35.         {       
  36.                 _nop_();
  37.         }
  38. }

  39. //*****stc12c5608ad** NRF24L01端口定義************//
  40. /*sbit KEY =P2^4;
  41. sbit LED =P2^0;
  42. sbit LED1=P2^1;

  43. sbit CE  =P1^3;
  44. sbit SCK =P1^5;
  45. sbit CSN =P1^2;
  46. sbit MISO=P1^7;
  47. sbit MOSI=P1^4;
  48. sbit IRQ =P1^6;*/

  49. //***stc12c5a60s2**NRF24L01端口定義******************//
  50. sbit KEY =P3^7;
  51. sbit LED =P1^3;
  52. sbit LED1=P1^4;

  53. sbit CE  =P1^6;
  54. sbit SCK =P2^3;
  55. sbit CSN =P2^4;
  56. sbit MISO=P2^1;
  57. sbit MOSI=P2^2;
  58. sbit IRQ =P2^0;
  59. //**********NRF24L01的接收和發送地址***************/
  60. #define TX_ADR_WIDTH    5   // 5個字節的TX地址長度
  61. #define RX_ADR_WIDTH    5   // 5個字節的RX地址長度
  62. #define TX_PLOAD_WIDTH  16  // 16個字節的TX數據長度
  63. #define RX_PLOAD_WIDTH  16  // 16個字節的RX數據長度
  64. uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //本地地址
  65. uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //接收地址
  66. //***************************************NRF24L01寄存器指令**********************************//
  67. #define READ_REG        0x00          // 讀寄存器
  68. #define WRITE_REG       0x20         // 寫寄存器
  69. #define RD_RX_PLOAD     0x61          // 讀取接收數據
  70. #define WR_TX_PLOAD     0xA0          // 寫待發數據
  71. #define FLUSH_TX        0xE1         // 沖洗發送 FIFO
  72. #define FLUSH_RX        0xE2          // 沖洗接收 FIFO
  73. #define REUSE_TX_PL     0xE3          // 定義重復裝載數據
  74. #define NOP             0xFF          // 保留
  75. //*************************************SPI(nRF24L01)寄存器地址*****************************//
  76. #define CONFIG          0x00  // 配置收發狀態,CRC校驗模式以及收發狀態響應方式
  77. #define EN_AA           0x01  // 自動應答功能設置
  78. #define EN_RXADDR       0x02  // 可用信道設置
  79. #define SETUP_AW        0x03  // 收發地址寬度設置
  80. #define SETUP_RETR      0x04  // 自動重發功能設置
  81. #define RF_CH           0x05  // 工作頻率設置
  82. #define RF_SETUP        0x06  // 發射速率、功耗功能設置
  83. #define STATUS          0x07  // 狀態寄存器
  84. #define OBSERVE_TX      0x08  // 發送監測功能
  85. #define CD              0x09  // 地址檢測   
  86. #define RX_ADDR_P0      0x0A  // 頻道0接收數據地址
  87. #define RX_ADDR_P1      0x0B  // 頻道1接收數據地址
  88. #define RX_ADDR_P2      0x0C  // 頻道2接收數據地址
  89. #define RX_ADDR_P3      0x0D  // 頻道3接收數據地址
  90. #define RX_ADDR_P4      0x0E  // 頻道4接收數據地址
  91. #define RX_ADDR_P5      0x0F  // 頻道5接收數據地址
  92. #define TX_ADDR         0x10  // 發送地址寄存器
  93. #define RX_PW_P0        0x11  // 接收頻道0接收數據長度
  94. #define RX_PW_P1        0x12  // 接收頻道0接收數據長度
  95. #define RX_PW_P2        0x13  // 接收頻道0接收數據長度
  96. #define RX_PW_P3        0x14  // 接收頻道0接收數據長度
  97. #define RX_PW_P4        0x15  // 接收頻道0接收數據長度
  98. #define RX_PW_P5        0x16  // 接收頻道0接收數據長度
  99. #define FIFO_STATUS     0x17  // FIFO棧入棧出狀態寄存器設置
  100. void init_NRF24L01();
  101. uchar SPI_RW(uchar num);
  102. uchar SPI_Read(uchar reg);
  103. void SetRX_Mode();
  104. void SetTx_Mode();
  105. uchar SPI_RW_Reg(uchar reg, uchar value);
  106. uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
  107. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
  108. void nRF24L01_RxPacket(uchar *rx_buf);
  109. void nRF24L01_TxPacket(uchar *tx_buf);
  110. //**********狀態標志*****************************//
  111. uchar         bdata sta;
  112. sbit        RX_DR        =sta^6;
  113. sbit        TX_DS        =sta^5;
  114. sbit        MAX_RT        =sta^4;
  115. //***********NRF24L01初始化***************************//
  116. void init_NRF24L01()
  117. {
  118.     delayus(100);
  119.         CE=0;    // 片選使能
  120.         CSN=1;   // SPI使能
  121.         SCK=0;   // SPI時鐘拉低
  122.         SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);   
  123. //寫本地地址       
  124.         SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);
  125. //寫接收端地址
  126.         SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                             
  127. //通道0自動應答        
  128.         SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);                        
  129. //允許接收地址頻道0
  130.         SPI_RW_Reg(WRITE_REG + RF_CH, 0x32);                             
  131. //設置信道工作頻率,收發必須一致
  132.         SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);               
  133. //設置接收數據長度
  134.         SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f);                                    
  135. //設置發射速率為2MHZ,發射功率為最大值0dB       
  136.         SPI_RW_Reg(WRITE_REG + CONFIG, 0x7c);                                                          
  137. //IRQ引腳不顯示中斷 掉電模式  1~16CRC校驗
  138. }
  139. /*******************************************************
  140. /*函數:uint SPI_RW(uint uchar)
  141. /*功能:NRF24L01的SPI寫時序
  142. /*********************************************************/
  143. uchar SPI_RW(uchar num)
  144. {
  145.         uchar bit_ctr;
  146.            for(bit_ctr=0;bit_ctr<8;bit_ctr++)  // output 8-bit
  147.            {
  148.                 MOSI = (num & 0x80);            // output 'uchar', MSB to MOSI
  149.                 num = (num << 1);               // shift next bit into MSB..
  150.                 SCK = 1;                        // Set SCK high..
  151.                 num |= MISO;                               // capture current MISO bit
  152.                 SCK = 0;                                // ..then set SCK low again
  153.            }
  154.     return(num);                                   // return read uchar
  155. }
  156. /**************************************************************
  157. 函數:uchar SPI_Read(uchar reg)
  158. 功能:NRF24L01的SPI時序
  159. *************************************************************/
  160. uchar SPI_Read(uchar reg)
  161. {
  162.         uchar reg_val;
  163.        
  164.         CSN = 0;                // CSN low, initialize SPI communication...
  165.         SPI_RW(reg);            // Select register to read from..
  166.         reg_val = SPI_RW(0);    // ..then read registervalue
  167.         CSN = 1;                // CSN high, terminate SPI communication
  168.        
  169.         return(reg_val);        // return register value
  170. }
  171. /******************************************************************/
  172. /*功能:NRF24L01讀寫寄存器函數
  173. /**************************************************************/
  174. uchar SPI_RW_Reg(uchar reg, uchar value)
  175. {
  176.         uchar status;
  177. CSN = 0;                   // CSN low, init SPI transaction
  178.         status = SPI_RW(reg);      // select register
  179.         SPI_RW(value);             // ..and write value to it..
  180.         CSN = 1;                   // CSN high again
  181.         return(status);            // return nRF24L01 status uchar
  182. }
  183. /****************************************************************/
  184. uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
  185. {
  186.         uchar status,byte_ctr;
  187.         CSN = 0; // Set CSN low, init SPI tranaction
  188.         status = SPI_RW(reg); // Select register to write to and read status byte
  189.         for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
  190.         pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte from nRF24L01
  191.         CSN = 1; // Set CSN high again
  192.         return(status); // return nRF24L01 status byte
  193. }
  194. /************************************************************
  195. /*函數:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  196. /*功能: 用于寫數據:為寄存器地址,pBuf:為待寫入數據地址,
  197. uchars:寫入數據的個數
  198. /*****************************************************************/
  199. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  200. {
  201.         uchar status,uchar_ctr;
  202.        
  203.         CSN = 0;            //SPI使能      
  204.         status = SPI_RW(reg);   
  205.         for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
  206.                 SPI_RW(*pBuf++);
  207.         CSN = 1;           //關閉SPI
  208.         return(status);    //
  209. }
  210. //********** nrf收發程序 **********
  211. void nrf_RxTx(uchar mod_nrf,uchar *buff) //NRF24L01收發程序       
  212. {                       
  213.         static uchar mod_nrf_b;//static 地址不釋放

  214. //******進入發射模式******
  215.         if(mod_nrf == 't')
  216.         {
  217.                 if(mod_nrf_b != 't')
  218.                 {       
  219.                         mod_nrf_b = 't';
  220.                         CE = 0;
  221.                         SPI_RW_Reg(WRITE_REG+STATUS,0xff);        
  222. //清除中斷標志
  223.                         SPI_RW_Reg(FLUSH_TX,0x00);                       
  224. //清除TX_FIFO寄存器
  225.                         SPI_RW_Reg(WRITE_REG + CONFIG,0x7e);
  226. //IRQ引腳不顯示中斷 上電 發射模式  1~16CRC校驗
  227.                         CE = 1;
  228.                         delayus(330);
  229. //從CE = 0 到 CE = 1;即待機模式到收發模式,需要最大130us                  
  230.                 }
  231. //******發送數據******
  232.                 CE = 0;                        //StandBy I模式       
  233.                 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
  234. // 裝載接收端地址
  235.                 SPI_Write_Buf(WR_TX_PLOAD,buff,TX_PLOAD_WIDTH);                          
  236. // 裝載數據
  237.                 CE = 1;                 //置高CE激發數據發送
  238.                 delayus(230);
  239. //從CE = 0 到 CE = 1;即待機模式到收發模式,需要最大130us
  240.                
  241.                 delayus(100);
  242. //給發送數據一點時間         比發送速度較快 延時可以比接收少
  243.                 sta = SPI_Read(STATUS);//讀取狀態寄存器的值
  244.                 SPI_RW_Reg(WRITE_REG+STATUS,sta);//清除對應的中斷
  245.                                                
  246.                 if(TX_DS == 1)//發送成功再清除tx fifo寄存器
  247.                 {       
  248.                         CE = 0;                       
  249.                         SPI_RW_Reg(FLUSH_TX,0x00);
  250. //清除tx fifo寄存器        //********重要*********
  251.                         CE = 1;
  252.                 }                                                               
  253.                                
  254.         }
  255. //******進入接收模式******
  256.         else if(mod_nrf == 'r')//接收模式
  257.         {
  258.                 if(mod_nrf_b != 'r')
  259.                 {
  260.                         mod_nrf_b = 'r';
  261.                         CE = 0;
  262.                         SPI_RW_Reg(WRITE_REG+STATUS,0xff);       
  263. //清除中斷標志
  264.                         SPI_RW_Reg(FLUSH_RX,0x00);                        
  265. //清除RX_FIFO寄存器
  266.                         SPI_RW_Reg(WRITE_REG + CONFIG, 0x7f);
  267. //IRQ引腳不顯示中斷 上電 接收模式   1~16CRC校驗   
  268.                         CE = 1;
  269.                         delayus(230);
  270. //從CE = 0 到 CE = 1;即待機模式到收發模式,需要最大130us
  271.                 }               
  272.                 delayus(1500); //不能少 值可調  給接收數據一點時間
  273.                 sta = SPI_Read(STATUS);
  274.                 SPI_RW_Reg(WRITE_REG+STATUS,sta);   
  275.                 if(RX_DR == 1)   
  276.                 {
  277.                         CE = 0;  
  278.                         SPI_Read_Buf(RD_RX_PLOAD,buff,RX_PLOAD_WIDTH);
  279. //讀取數據 存入數組
  280.                         SPI_RW_Reg(FLUSH_RX,0x00);
  281. //清除rx fifo寄存器        數據不抖動
  282.                         CE = 1;
  283.                 }                 
  284.          }
  285. }
  286. void main()
  287. {
  288.         uchar idata RxBuf[16];        //接收緩存 存入idata區
  289.         uchar idata TxBuf[16];        //發送緩存
  290.         uint t_while = 0;
  291.         uint t_tx = 100;
  292.         uint t_rx = 100;       
  293.         init_NRF24L01();                //nrf24l01初始化       
  294.         RxBuf[0] = 1;
  295.         TxBuf[0] = 0;       
  296.         LED = 1;
  297.         LED1 = 1;
  298.         while(1)
  299.         {
  300.                 t_while = t_tx;
  301.                 while(t_while--)
  302. //一旦發送成功就跳出循環 最多發送t_while次
  303.                 {
  304.                         nrf_RxTx('t',TxBuf);//發送模式
  305.                         if(TX_DS == 1)                //發送成功
  306.                         LED = 0;
  307.                         delayus(2300);
  308.                         LED = 1;
  309.                                 break;                       
  310. //跳出循環進入接收模式
  311.                 }                       
  312.                
  313.                
  314.                 t_while = t_rx ;
  315.                 while(t_while--)                       
  316. //一旦接收成功就跳出循環 最多接收t_while次       
  317.                 {       
  318.                         nrf_RxTx('r',RxBuf);//接收模式
  319.                        
  320.                         if(RX_DR == 1)        //接收成功
  321.                                 LED = 0;
  322.                                 break;        //跳出循環進入發送模式
  323.                 }
  324.                
  325.                 if(RxBuf[0] == 0)
  326.                         LED1= 0;
  327.                 else
  328.                         LED1 = 1;

  329.                 if(KEY == 0)
  330.                 {
  331.                
  332.                         TxBuf[0] = 1;
  333.                 }
  334.                 else
  335.                         TxBuf[0] = 0;                       
  336.                
  337.         }
  338. }
復制代碼


評分

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

查看全部評分

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

使用道具 舉報

沙發
ID:284472 發表于 2018-3-8 00:54 | 只看該作者
很棒很有用nice
回復

使用道具 舉報

無效樓層,該帖已經被刪除
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美a区| 日韩手机在线看片 | 福利视频一区 | 国产在线一区二 | 国产精品自产av一区二区三区 | 欧美日韩三级在线观看 | 中文区中文字幕免费看 | 日韩一级黄色毛片 | 91免费小视频 | 婷婷在线视频 | 日韩欧美精品 | 久久一 | 国产精品一区久久久久 | 91精品久久久久久久久中文字幕 | 国产精品视频不卡 | 午夜电影在线播放 | 色必久久 | 精品一区二区三区免费视频 | 一区二区三区精品视频 | 青草青草久热精品视频在线观看 | 亚洲精品aⅴ | 韩国精品在线观看 | 中文字幕亚洲视频 | 欧美一区二区激情三区 | 亚洲九九色 | 国产分类视频 | 天天操天天天干 | 色在线免费视频 | 激情小视频 | 久久精品二区 | 91精品国产91久久久久久吃药 | 久久精品视频一区二区 | 成人在线视频免费观看 | 国产三级大片 | 天堂久久av | 天天插天天操 | 国产美女久久 | 亚洲精品在线视频 | 美女爽到呻吟久久久久 | 99精品网 | 国产在线一区二区三区 |