STM32F103VET6 2.4G通信模块NRF24L01 GPIO模拟SPI的测试例程

发布者:VelvetDreamer最新更新时间:2017-10-02 来源: eefocus关键字:STM32F103VET6  2.4G  NRF24L01  GPIO  模拟SPI 手机看文章 扫描二维码
随时随地手机看文章

自己画的一块基于STM32F103VET6的开发测试板,留有一个NRF24L01+的通信接口,之前买了一些NRF24L01+的模块打算研究一下用上,淘宝上买的比较便宜,可以用于物联网方面的无线应用吧。


做过NRF905的通信,NRF24L01的也是有些相似。网上教程一大堆,我原理上设计为GPIO模拟SPI,因此我找了个GPIO 模拟SPI通信的例程,改了下,开始出了点问题,后来找到原因并解决,通信正常了。


先说一下问题:


NRF24L01引脚初始化问题,设置了引脚,但是GPIO初始化时,引脚没有对应上,因此程不跑,串口一直打印 找不到NRF24L01模块,因为有一个检测NRF24L01是否存在的函数。


  1. //上电检测NRF24L01是否在位  

  2. //写5个数据然后再读回来进行比较,  

  3. //相同时返回值0,表示在位;  

  4. //否则返回1,表示不在位.    

  5. u8 NRF24L01_Check(void)  

  6. {  

  7.     u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};  

  8.     u8 buf1[5];  

  9.     u8 i;          

  10.     NRF24L01_Write_Buf(SPI_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.      

  11.     NRF24L01_Read_Buf(TX_ADDR,buf1,5);              //读出写入的地址     

  12.     for(i=0;i<5;i++)  

  13.         if(buf1[i]!=0XA5) break;                         

  14.     if(i!=5) return 1;                               //NRF24L01不在位  

  15.           

  16.     return 0;                                       //NRF24L01在位  

  17. }          




写进去:五个字节:0xA5,读出来,全为:0xFF,好像网上也有这样的问题,其实,是NRF24L01没有初始化成功的原因。设置好引脚,初始化GPIO与相应的时钟后,正常了。

因此注意:void Init_NRF24L01(void)  函数,把GPIO引脚设置正确。


NRF24L01的驱动程序如下:


NRF24L01.c


  1. #include "NRF24L01.h"  

  2.   

  3. const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址  

  4. const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //接收地址                          

  5.   

  6.   

  7. void Delay(vu32 nCount)  

  8. {  

  9.   for(; nCount != 0; nCount--);  

  10. }  

  11.   

  12. //初始化NRF24L01IO口  

  13. //CE->PD2,CSN->PD5,SCK->PD3,MOSI->PD6,MISO->PD4,IRQ->PD7  

  14. void Init_NRF24L01(void)  

  15. {  

  16.     //CE->PD2,CSN->PD5,SCK->PD3,MOSI->PD6  

  17.     GPIO_InitTypeDef GPIO_InitStructure;              

  18.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);    //使能GPIO 的时钟  

  19.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_5|GPIO_Pin_3|GPIO_Pin_6;  

  20.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //推挽输出  

  21.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  22.     GPIO_Init(GPIOD, &GPIO_InitStructure);  

  23.   

  24.     CE_H;           //初始化时先拉高  

  25.   CSN_H;                    //初始化时先拉高  

  26.       

  27.     //MISO->PD4,IRQ->PD7  

  28.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_7;  

  29.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     //上拉输入  

  30.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  31.     GPIO_Init(GPIOD, &GPIO_InitStructure);  

  32.           

  33.     IRQ_H;                                      //IRQ置高  

  34.     CE_L;                     //使能NRF24L01  

  35.     CSN_H;                    //SPI片选取消  

  36. }  

  37.   

  38. //模拟SPI读写数据函数  

  39. u8 SPI_ReadWriteByte(u8 TxData)                                          

  40. {         

  41.     u16 bit_ctr;  

  42.     for(bit_ctr=0;bit_ctr<8;bit_ctr++)   

  43.     {  

  44.         if(TxData & 0x80)  

  45.         MOSI_H;           

  46.         else  

  47.         MOSI_L;  

  48.         TxData = (TxData << 1);             

  49.         SCK_H;   

  50.         Delay(0xff);  

  51.         if(READ_MISO)                       

  52.         TxData |= 0x01;                 

  53.         SCK_L;   

  54.         Delay(0xff);                   

  55.     }  

  56.     return(TxData);                               

  57. }  

  58.   

  59. //上电检测NRF24L01是否在位  

  60. //写5个数据然后再读回来进行比较,  

  61. //相同时返回值0,表示在位;  

  62. //否则返回1,表示不在位.    

  63. u8 NRF24L01_Check(void)  

  64. {  

  65.     u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};  

  66.     u8 buf1[5];  

  67.     u8 i;          

  68.     NRF24L01_Write_Buf(SPI_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.      

  69.     NRF24L01_Read_Buf(TX_ADDR,buf1,5);              //读出写入的地址     

  70.     for(i=0;i<5;i++)  

  71.         if(buf1[i]!=0XA5) break;                         

  72.     if(i!=5) return 1;                               //NRF24L01不在位  

  73.           

  74.     return 0;                                       //NRF24L01在位  

  75. }          

  76. //通过SPI写寄存器  

  77. u8 NRF24L01_Write_Reg(u8 reg_addr,u8 data)  

  78. {  

  79.     u8 status;    

  80.     CSN_L;                    //使能SPI传输  

  81.     status =SPI_ReadWriteByte(reg_addr); //发送寄存器号   

  82.     SPI_ReadWriteByte(data);            //写入寄存器的值  

  83.     CSN_H;                    //禁止SPI传输      

  84.     return(status);                      //返回状态值  

  85. }  

  86. //读取SPI寄存器值 ,regaddr:要读的寄存器  

  87. u8 NRF24L01_Read_Reg(u8 reg_addr)  

  88. {  

  89.     u8 reg_val;       

  90.     CSN_L;                //使能SPI传输       

  91.     SPI_ReadWriteByte(reg_addr);     //发送寄存器号  

  92.     reg_val=SPI_ReadWriteByte(0);//读取寄存器内容  

  93.   

  94.     CSN_H;                //禁止SPI传输           

  95.     return(reg_val);                 //返回状态值  

  96. }     

  97. //在指定位置读出指定长度的数据  

  98. //*pBuf:数据指针  

  99. //返回值,此次读到的状态寄存器值   

  100. u8 NRF24L01_Read_Buf(u8 reg_addr,u8 *pBuf,u8 data_len)  

  101. {  

  102.     u8 status,i;             

  103.     CSN_L;                     //使能SPI传输  

  104.     status=SPI_ReadWriteByte(reg_addr);   //发送寄存器值(位置),并读取状态值            

  105.     for(i=0;i

  106.         pBuf[i]=SPI_ReadWriteByte(0);//读出数据  

  107.   

  108.     CSN_H;                     //关闭SPI传输  

  109.     return status;                        //返回读到的状态值  

  110. }  

  111. //在指定位置写指定长度的数据  

  112. //*pBuf:数据指针  

  113. //返回值,此次读到的状态寄存器值  

  114. u8 NRF24L01_Write_Buf(u8 reg_addr, u8 *pBuf, u8 data_len)  

  115. {  

  116.     u8 status,i;          

  117.     CSN_L;                                    //使能SPI传输  

  118.     status = SPI_ReadWriteByte(reg_addr);                //发送寄存器值(位置),并读取状态值  

  119.     for(i=0; i

  120.         SPI_ReadWriteByte(*pBuf++); //写入数据     

  121.     CSN_H;                                    //关闭SPI传输  

  122.     return status;                                       //返回读到的状态值  

  123. }                    

  124. //启动NRF24L01发送一次数据  

  125. //txbuf:待发送数据首地址  

  126. //返回值:发送完成状况  

  127. u8 NRF24L01_TxPacket(u8 *tx_buf)  

  128. {  

  129.     u8 state;     

  130.     CE_L;  

  131.     NRF24L01_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);//写数据到TX BUF  32个字节  

  132.     CE_H;                                     //启动发送         

  133.     while(READ_IRQ != 0);                         //等待发送完成  

  134.     state=NRF24L01_Read_Reg(STATUS);                     //读取状态寄存器的值         

  135.     NRF24L01_Write_Reg(SPI_WRITE_REG+STATUS,state);      //清除TX_DS或MAX_RT中断标志  

  136.     if(state&MAX_TX)                                     //达到最大重发次数  

  137.     {  

  138.         NRF24L01_Write_Reg(FLUSH_TX,0xff);               //清除TX FIFO寄存器   

  139.         return MAX_TX;   

  140.     }  

  141.     if(state&TX_OK)                                      //发送完成  

  142.     {  

  143.         return TX_OK;  

  144.     }  

  145.     return 0xff;                                         //其他原因发送失败  

  146. }  

  147.   

  148. //启动NRF24L01发送一次数据  

  149. //txbuf:待发送数据首地址  

  150. //返回值:0,接收完成;其他,错误代码  

  151. u8 NRF24L01_RxPacket(u8 *rx_buf)  

  152. {  

  153.     u8 state;                                               

  154.     state=NRF24L01_Read_Reg(STATUS);                //读取状态寄存器的值        

  155.     NRF24L01_Write_Reg(SPI_WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志  

  156.     if(state&RX_OK)                                 //接收到数据  

  157.     {  

  158.         NRF24L01_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);//读取数据  

  159.         NRF24L01_Write_Reg(FLUSH_RX,0xff);          //清除RX FIFO寄存器   

  160.         return 0;   

  161.     }        

  162.     return 1;                                      //没收到任何数据  

  163. }  

  164.   

  165. //该函数初始化NRF24L01到RX模式  

  166. //设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR  

  167. //当CE变高后,即进入RX模式,并可以接收数据了            

  168. void RX_Mode(void)  

  169. {  

  170.     CE_L;       

  171.     //写RX节点地址  

  172.     NRF24L01_Write_Buf(SPI_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);  

  173.   

  174.     //使能通道0的自动应答      

  175.     NRF24L01_Write_Reg(SPI_WRITE_REG+EN_AA,0x01);      

  176.     //使能通道0的接收地址       

  177.     NRF24L01_Write_Reg(SPI_WRITE_REG+EN_RXADDR,0x01);  

  178.     //设置RF通信频率          

  179.     NRF24L01_Write_Reg(SPI_WRITE_REG+RF_CH,40);        

  180.     //选择通道0的有效数据宽度        

  181.     NRF24L01_Write_Reg(SPI_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);  

  182.     //设置TX发射参数,0db增益,2Mbps,低噪声增益开启     

  183.     NRF24L01_Write_Reg(SPI_WRITE_REG+RF_SETUP,0x0f);  

  184.     //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,PRIM_RX接收模式   

  185.     NRF24L01_Write_Reg(SPI_WRITE_REG+CONFIG, 0x0f);   

  186.     //CE为高,进入接收模式   

  187.     CE_H;                                  

  188. }             

  189.   

  190. //该函数初始化NRF24L01到TX模式  

  191. //设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,  

  192. //选择RF频道,波特率和LNA HCURR PWR_UP,CRC使能  

  193. //当CE变高后,即进入RX模式,并可以接收数据了            

  194. //CE为高大于10us,则启动发送.    

  195. void TX_Mode(void)  

  196. {                                                          

  197.     CE_L;         

  198.     //写TX节点地址   

  199.     NRF24L01_Write_Buf(SPI_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);      

  200.     //设置TX节点地址,主要为了使能ACK        

  201.     NRF24L01_Write_Buf(SPI_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);   

  202.   

  203.     //使能通道0的自动应答      

  204.     NRF24L01_Write_Reg(SPI_WRITE_REG+EN_AA,0x01);       

  205.     //使能通道0的接收地址    

  206.     NRF24L01_Write_Reg(SPI_WRITE_REG+EN_RXADDR,0x01);   

  207.     //设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次  

  208.     NRF24L01_Write_Reg(SPI_WRITE_REG+SETUP_RETR,0x1a);  

  209.     //设置RF通道为40  

  210.     NRF24L01_Write_Reg(SPI_WRITE_REG+RF_CH,40);         

  211.     //设置TX发射参数,0db增益,2Mbps,低噪声增益开启     

  212.     NRF24L01_Write_Reg(SPI_WRITE_REG+RF_SETUP,0x0f);    

  213.     //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,PRIM_RX发送模式,开启所有中断  

  214.     NRF24L01_Write_Reg(SPI_WRITE_REG+CONFIG,0x0e);      

  215.     // CE为高,10us后启动发送  

  216.     CE_H;                                    

  217. }           




NRF24L01头文件:


  1. #ifndef _NRF24L01_H  

  2. #define _NRF24L01_H  

  3.   

  4. #include "stm32f10x.h"  

  5.   

  6. /****************************************************************************************************/  

  7. //NRF24L01寄存器操作命令  

  8. #define SPI_READ_REG    0x00  //读配置寄存器,低5位为寄存器地址  

  9. #define SPI_WRITE_REG   0x20  //写配置寄存器,低5位为寄存器地址  

  10. #define RD_RX_PLOAD     0x61  //读RX有效数据,1~32字节  

  11. #define WR_TX_PLOAD     0xA0  //写TX有效数据,1~32字节  

  12. #define FLUSH_TX        0xE1  //清除TX FIFO寄存器.发射模式下用  

  13. #define FLUSH_RX        0xE2  //清除RX FIFO寄存器.接收模式下用  

  14. #define REUSE_TX_PL     0xE3  //重新使用上一包数据,CE为高,数据包被不断发送.  

  15. #define NOP             0xFF  //空操作,可以用来读状态寄存器    

  16.    

  17. //SPI(NRF24L01)寄存器地址  

  18. #define CONFIG          0x00  //配置寄存器地址;bit0:1接收模式,0发射模式;bit1:电选择;bit2:CRC模式;bit3:CRC使能;  

  19.                               //bit4:中断MAX_RT(达到最大重发次数中断)使能;bit5:中断TX_DS使能;bit6:中断RX_DR使能  

  20. #define EN_AA           0x01  //使能自动应答功能  bit0~5,对应通道0~5  

  21. #define EN_RXADDR       0x02  //接收地址允许,bit0~5,对应通道0~5  

  22. #define SETUP_AW        0x03  //设置地址宽度(所有数据通道):bit1,0:00,3字节;01,4字节;02,5字节;  

  23. #define SETUP_RETR      0x04  //建立自动重发;bit3:0,自动重发计数器;bit7:4,自动重发延时 250*x+86us  

  24. #define RF_CH           0x05  //RF通道,bit6:0,工作通道频率;  

  25. #define RF_SETUP        0x06  //RF寄存器;bit3:传输速率(0:1Mbps,1:2Mbps);bit2:1,发射功率;bit0:低噪声放大器增益  

  26. #define STATUS          0x07  //状态寄存器;bit0:TX FIFO满标志;bit3:1,接收数据通道号(最大:6);bit4,达到最多次重发  

  27.                               //bit5:数据发送完成中断;bit6:接收数据中断;  

  28. #define MAX_TX          0x10  //达到最大发送次数中断  

  29. #define TX_OK           0x20  //TX发送完成中断  

  30. #define RX_OK           0x40  //接收到数据中断  

  31.   

  32. #define OBSERVE_TX      0x08  //发送检测寄存器,bit7:4,数据包丢失计数器;bit3:0,重发计数器  

  33. #define CD              0x09  //载波检测寄存器,bit0,载波检测;  

  34. #define RX_ADDR_P0      0x0A  //数据通道0接收地址,最大长度5个字节,低字节在前  

  35. #define RX_ADDR_P1      0x0B  //数据通道1接收地址,最大长度5个字节,低字节在前  

  36. #define RX_ADDR_P2      0x0C  //数据通道2接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;  

  37. #define RX_ADDR_P3      0x0D  //数据通道3接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;  

  38. #define RX_ADDR_P4      0x0E  //数据通道4接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;  

  39. #define RX_ADDR_P5      0x0F  //数据通道5接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;  

  40. #define TX_ADDR         0x10  //发送地址(低字节在前),ShockBurstTM模式下,RX_ADDR_P0与此地址相等  

  41. #define RX_PW_P0        0x11  //接收数据通道0有效数据宽度(1~32字节),设置为0则非法  

  42. #define RX_PW_P1        0x12  //接收数据通道1有效数据宽度(1~32字节),设置为0则非法  

  43. #define RX_PW_P2        0x13  //接收数据通道2有效数据宽度(1~32字节),设置为0则非法  

  44. #define RX_PW_P3        0x14  //接收数据通道3有效数据宽度(1~32字节),设置为0则非法  

  45. #define RX_PW_P4        0x15  //接收数据通道4有效数据宽度(1~32字节),设置为0则非法  

  46. #define RX_PW_P5        0x16  //接收数据通道5有效数据宽度(1~32字节),设置为0则非法  

  47. #define FIFO_STATUS     0x17  //FIFO状态寄存器;bit0,RX FIFO寄存器空标志;bit1,RX FIFO满标志;bit2,3,保留  

  48.                               //bit4,TX FIFO空标志;bit5,TX FIFO满标志;bit6,1,循环发送上一数据包.0,不循环;  

  49. /**********************************************************************************************************/  

  50.   

  51. //NRF2401片选信号  

  52. #define         CE_L      GPIO_ResetBits(GPIOD, GPIO_Pin_2)  

  53. #define         CE_H      GPIO_SetBits(GPIOD, GPIO_Pin_2)  

  54.   

  55. //SPI片选信号     

  56. #define         CSN_L     GPIO_ResetBits(GPIOD, GPIO_Pin_5)  

  57. #define         CSN_H     GPIO_SetBits(GPIOD, GPIO_Pin_5)  

  58.   

  59. //SPI时钟  

  60. #define         SCK_L   GPIO_ResetBits(GPIOD , GPIO_Pin_3)  

  61. #define         SCK_H   GPIO_SetBits(GPIOD , GPIO_Pin_3)  

  62.   

  63. //SPI输出  

  64. #define         MOSI_L  GPIO_ResetBits(GPIOD , GPIO_Pin_6)  

  65. #define         MOSI_H  GPIO_SetBits(GPIOD , GPIO_Pin_6)  

  66.   

  67. //SPI输入  

  68. #define         READ_MISO   GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_4)  

  69.      

  70. //IRQ中断脚  

  71. #define         IRQ_L       GPIO_ResetBits(GPIOD,GPIO_Pin_7)   

  72. #define         IRQ_H       GPIO_SetBits(GPIOD,GPIO_Pin_7)  

  73.   

  74. #define         READ_IRQ    GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7)  

  75.   

  76.   

  77. //NRF24L01发送接收数据宽度定义  

  78. #define TX_ADR_WIDTH    5                   //5字节的地址宽度  

  79. #define RX_ADR_WIDTH    5                   //5字节的地址宽度  

  80. #define TX_PLOAD_WIDTH  32                  //20字节的用户数据宽度  

  81. #define RX_PLOAD_WIDTH  32                  //20字节的用户数据宽度  

  82.                                              

  83.   

  84. void Init_NRF24L01(void);                    //NRF24l01初始化  

  85. u8 SPI_ReadWriteByte(u8 TxData) ;                        //模拟SPI通讯函数  

  86. void RX_Mode(void);                          //配置为接收模式  

  87. void TX_Mode(void);                          //配置为发送模式  

  88. u8 NRF24L01_Write_Buf(u8 regaddr, u8 *pBuf, u8 datalen); //写数据区  

  89. u8 NRF24L01_Read_Buf(u8 regaddr, u8 *pBuf, u8 datalen);  //读数据区         

  90. u8 NRF24L01_Read_Reg(u8 regaddr);                        //读寄存器  

  91. u8 NRF24L01_Write_Reg(u8 regaddr, u8 data);              //写寄存器  

  92. u8 NRF24L01_Check(void);                                 //检查NRF24L01是否在位  

  93. u8 NRF24L01_TxPacket(u8 *txbuf);                         //发送一个包的数据  

  94. u8 NRF24L01_RxPacket(u8 *rxbuf);                         //接收一个包的数据  

  95.   

  96. void Delay(vu32 nCount);  

  97. #endif  




接收端的main函数:


  1. /********************        (C) COPYRIGHT 2017        ************************** 

  2.  * 文件名  :main.c 

  3.  * 描述    :NRF24L01+ 的 接收 测试程序   

  4.  * 实验平台:STM32F103VET6 

  5.  * 库版本  :ST3.5.0 

  6.  * 编写日期:2017-04-17 

  7.  * 修改日期:2017-04-17 

  8.  * 作者    : 

  9.  * 2017-04-17 

  10.  * (1)NRF24L01+  接收数据 测试正常! 

  11. **********************************************************************************/  

  12.   

  13. #include "usart1.h"  

  14. #include "led.h"  

  15. #include "tim2.h"  

  16. #include "NRF24L01.h"  

  17. #include "SysTick.h"  

  18.   

  19. /*  

  20.  * 函数名:main 

  21.  * 描述  : "主机"的主函数 

  22.  * 输入  :无 

  23.  * 输出  : 无 

  24.  */  

  25.    

  26. int main(void)  

  27. {      

  28.     uint8_t tmp_buf[6];  

  29.   

  30.     SysTick_Init();  

  31.     USART1_Config(115200);                      /* 初始化USART1 */  

  32.     LED_GPIO_Config();                          /* 运行LED初始化 */  

  33.     TIM2_Config();                                      /* 定时器TIM2初始化 */      

  34.     Init_NRF24L01();  

  35.     printf("STM32F103VET6 NRF24L01 RECV Test!\r\n");  

  36.     printf("2017-04-17\r\n");  

  37.     if(NRF24L01_Check())  

  38.     {  

  39.         printf("NRF24L01 is Not work!\r\n");  

  40.     }  

  41.     RX_Mode();          //只收不发  

  42.   

  43.     while(1)  

  44.     {   

  45.         if(NRF24L01_RxPacket(tmp_buf)==0)       //接收到数据  

  46.         {  

  47.             printf("\r\n RECV Data is:%s\r\n",tmp_buf);  

  48.             LED1(ON);  

  49.             Delay_ms(100);  

  50.         }  

  51.         LED1(OFF);  

  52.     }  

  53. }  

  54. /******************* (C) COPYRIGHT 2017 *****END OF FILE************/  




发送端的main函数:


  1. /********************        (C) COPYRIGHT 2017        ************************** 

  2.  * 文件名  :main.c 

  3.  * 描述    :NRF24L01+ 发送数据测试程序 

  4.  * 实验平台:STM32F103VET6 

  5.  * 库版本  :ST3.5.0 

  6.  * 编写日期:2017-04-17 

  7.  * 修改日期:2017-04-17 

  8.  * 作者    : 

  9.  * 2017-04-17 

  10.  * (1)NRF24L01+ 发送数据 测试正常! 

  11. **********************************************************************************/  

  12.   

  13. #include "usart1.h"  

  14. #include "led.h"  

  15. #include "tim2.h"  

  16. #include "NRF24L01.h"  

  17. #include "SysTick.h"  

  18.   

  19. /*  

  20.  * 函数名:main 

  21.  * 描述  : "主机"的主函数 

  22.  * 输入  :无 

  23.  * 输出  : 无 

  24.  */  

  25.    

  26. int main(void)  

  27. {      

  28.     uint8_t tmp_buf[6] = {0x31,0x32,0x33,0x34,0x35,0x36};  

  29.   

  30.     SysTick_Init();  

  31.     USART1_Config(115200);                      /* 初始化USART1 */  

  32.     LED_GPIO_Config();                          /* 运行LED初始化 */  

  33.     TIM2_Config();                                      /* 定时器TIM2初始化 */      

  34.     Init_NRF24L01();  

  35.     printf("STM32F103VET6 NRF24L01 SEND Test!\r\n");  

  36.     printf("2017-04-17\r\n");  

  37.     if(NRF24L01_Check())  

  38.     {  

  39.         printf("NRF24L01 is Not work!\r\n");  

  40.     }  

  41.     TX_Mode();      //只发不收  

  42.   

  43.     while(1)  

  44.     {   

  45.         if(NRF24L01_TxPacket(tmp_buf)==TX_OK)       // 判断是否发送完成  

  46.         {  

  47.             printf("Send Data:%s\r\n",tmp_buf);  

  48.             LED1(ON);  

  49.             Delay_ms(500);  

  50.             LED1(OFF);  

  51.         }             

  52.         else                                    //发送失败  

  53.         {                                             

  54.             printf("请确定接收端是否正常!\r\n");  

  55.             Delay_ms(500);        

  56.         }  

  57.     }  

  58. }  

  59. /******************* (C) COPYRIGHT 2017 *****END OF FILE************/  





测试的方法:

(1)需要两个开发板来测试,一个用于接收,另一个用于发送。

(2)主要看接收是否正常,正常的话,LED灯会亮一下,并且串口打印收到的数据。

(3)至于通信的协议与数据格式,可以自定义,当然,接收与发送功能可以集一身。


    经过测试,正常。


发送与接收的工程如下:


http://download.csdn.net/detail/tcjy1000/9816507


关键字:STM32F103VET6  2.4G  NRF24L01  GPIO  模拟SPI 引用地址:STM32F103VET6 2.4G通信模块NRF24L01 GPIO模拟SPI的测试例程

上一篇:关于STM32F103 V3.5.0固件库stm32f10x_conf.h文件
下一篇:STM32F103VET6超声波模块HC-SR04 的测试例程

推荐阅读最新更新时间:2024-03-16 15:39

stm32中gpio的学习浅谈
在基本入门熟悉了开发环境后,我开始学习stm32中的gpio口用法,学习的方法还是最直观简便的先控制LED灯。然而stm32中点亮led倒没有51单片机那么简便。有过51单片机学习经验的伙伴们,肯定熟悉下图的代码(51中控制led的程序)。 如果同样方法写在stm32中肯定是不行的了,首先因为stm32中没有51头文件中那样定义好了P0口可以直接进行总线操作,其次stm32中的gpio口默认是输入模式并且还需要打开相关引脚口的时钟。可能很多人会觉得stm32中官方给的固件库可以直接操作寄存器从而控制gpio口,但是我觉得我这样的初学者还是多了解下底层的方法便于更好的理解。要实现stm32点亮一个led灯(即让gpio口输
[单片机]
stm32中<font color='red'>gpio</font>的学习浅谈
STM32入门开发: 介绍SPI总线、读写W25Q64(FLASH)(硬件+模拟时序)
一、环境介绍 编程软件: keil5 操作系统: win10 MCU型号: STM32F103ZET6 STM32编程方式: 寄存器开发 (方便程序移植到其他单片机) SPI总线: STM32本身支持SPI硬件时序,本文示例代码里同时采用模拟时序和硬件时序两种方式读写W25Q64。 模拟时序更加方便移植到其他单片机,更加方便学习理解SPI时序,通用性更高,不分MCU; 硬件时序效率更高,每个MCU配置方法不同,依赖MCU硬件本身支持。 存储器件: 采用华邦W25Q64 flash存储芯片。 W25Q64这类似的Flash存储芯片在单片机里、嵌入式系统里还是比较常见,可以用来存储图片数据、字库数据、音
[单片机]
STM32入门开发: 介绍<font color='red'>SPI</font>总线、读写W25Q64(FLASH)(硬件+<font color='red'>模拟</font>时序)
STM32F429——GPIO
除非特别说明,否则本部分适用于整个 STM32F4xx 系列 七 .通用I/O简介 7.1 GPIO 简介 每个通用 I/O 端口包括 4 个 32 位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR 、GPIOx_PUPDR), 2个32位数据寄存器( GPIOx_IDR 和GPIOx_ODR)、1个32位置位/复位寄存器(GPIOx_BSSR)、1个32位锁定寄存器(GPIOx_LCKR)和 2个32位复用功能选择寄存器(GPIOx_AFRH和GPIOx_AFRL)。 7.2 GPIO工作模式 GPIO可以设置成一下模式 1.输入模式(上拉/下拉/浮空) 在输入模式
[单片机]
linux内核中的GPIO系统之(2):pin control subsystem
一、前言 在linux2.6内核上工作的嵌入式软件工程师在pin control上都会遇到这样的状况: (1)启动一个新的项目后,需要根据硬件平台的设定进行pin control相关的编码。例如:在bootloader中建立一个大的table,描述各个引脚的配置和缺省状态。此外,由于SOC的引脚是可以复用的,因此在各个具体的driver中,也可能会对引脚进行的配置。这些工作都是比较繁琐的工作,需要极大的耐心和细致度。 (2)发现某个driver不能正常工作,辛辛苦苦debug后发现仅仅是因为其他的driver在初始化的过程中修改了引脚的配置,导致自己的driver无法正常工作 (3)即便是主CPU是一样的项目,但是由于外设的不同,
[单片机]
linux内核中的<font color='red'>GPIO</font>系统之(2):pin control subsystem
基于GSM的家庭安全防护系统
    随着电子技术的飞速发展,报警系统已从原来的简单化、局部化向智能化、集成化方向发展。而各种防盗报警系统之间的主要区别在于分机与主机、分机与用户之间进行通讯的方式。手机作为信息爆炸时代的产物已经成为人们日常最为便利的通讯工具。据悉,我国手机用户已达7.4亿,手机使用成本特别是短信息成本逐渐降低。如果能把报警装置以短消息的形式与手机之间建立远程控制,人们会在第一时间收到消息,并做出迅速反应,大大减少悲剧的发生。本文基于此思想设计了一种基于GSM网络的新型家庭安全检测系统,可通过手机实时接收到故障及报警信息。 1 总体结构与工作原理     该系统以广泛使用的GSM网络为通信媒介,用于家庭安防,可实时检测室内气体(燃气,烟雾)浓度以
[嵌入式]
STM32F429I-DISO探索第一篇 --GPIO(2)
上一篇写了GPIO简单的流水灯测试,看着有点单调,习惯了串口调试,板子上没有串口 那就另想办法吧,看着LCD突然有了个想法,为什么不把调试信息输出到LCD上,以前在做2416 WINCE开发的时候就经常这样干非常直观,那说干就干。 STM32F429I-DISO SDK里已经把开发包做好,那就直接拿过来用吧。 #define MESSAGE1 STM32F429I-Discoverry //提示信息 #define MESSAGE1_1 GPIO TEST #define MESSAGE2 LED3 LED4 #define MESSAGE2_1 ^-^ #def
[单片机]
STM32F4xx_GPIO常用设置
1、初始化时钟:   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE, ENABLE); 2、输出设置:   GPIO_InitTypeDef GPIO_InitStructure;   GPIO_StructInit(&GPIO_InitStructure);   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_9;   GPIO_Init
[单片机]
LPC2103之GPIO寄存器
GPIO port 0模式选择寄存器 page23 GPIO0M的bit0为GPIO port 0模式选择。当其为0时,GPIO通过APB地址进行访问(Legacy GPIO),当其为1时,使能高速GPIO port 0,GPIO通过片上存储区访问(Fast GPIO)。 管脚功能选择寄存器 Page67 PINSEL0和PINSEL1 PINSEL0和PINSEL1寄存器控制各个管脚的功能(查看datasheet的Table 62和Table 63)。IO0DIR寄存器的方向控制位仅仅当相应管脚的GPIO功能使能时有效。管脚在其它功能时,CPU自动配置管脚方向。 PINSEL0和PIN
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved