你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【HAL库每天一例】第077例:SPI-NRF24L01无线模块(一对一通...

[复制链接]
haohao663 提问时间:2016-7-29 09:00 /
【HAL库每天一例】系列例程从今天开始持续更新。。。。。
我们将坚持每天至少发布一个基于YS-F1Pro开发板的HAL库例程,
该系列例程将带领大家从零开始使用HAL库,后面会持续添加模块应用例程。
同样的,我们还程序发布基于HAL库的指导文档和视频教程,欢迎持续关注,并提出改进意见。

例程下载:
资料包括程序、相关说明资料以及软件使用截图
百度云链接:https://pan.baidu.com/s/1i574oPv
密码:r3s3

(硬石YS-F1Pro开发板HAL库例程持续更新\2. 软件设计之高级裸机例程(HAL库版本)\YSF1_HAL-111. SPI-NRF24L01无线模块(一对一通信)


/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: 发送端
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:硬石电子社区
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */

【1】例程简介
  nRF24.L01是一款新型单片射频收发器件,工作于2.4 GHz~2.5 GHz ISM频段。内置频率合成器、
功率放大器、晶体振荡器、调制器等功能模块,并融合了增强型ShockBurst技术,其中输出功率和
通信频道可通过程序进行配置。nRF24L01功耗低,在以-6 dBm的功率发射时,工作电流也只有9 mA;
接收时,工作电流只有12.3 mA,多种低功率工作模式(掉电模式和空闲模式)使节能设计更方便。
  
【2】跳线帽情况
******* 为保证例程正常运行,必须  插入  以下跳线帽 **********
丝印编号     IO端口      目标功能引脚        出厂默认设置
  JP1        PA10        TXD(CH340G)          已接入
  JP2        PA9         RXD(CH340G)          已接入
  
******* 为保证例程正常运行,必须  拔掉  以下跳线帽 **********
丝印编号     IO端口      目标功能引脚        出厂默认设置
  JP8        PF9         INTn(W5500)          已接入
  JP9        PF11        SCSn(W5500)          已接入

【3】操作及现象
将NRF24L01模块插入到使用开发板的CN14接口上,拔掉JP8和JP9两个跳线帽。配套的MINI USB线
连接到开发板标示“调试串口”字样的MIMI USB接口(需要安装驱动),在电脑端打开串口调试助手
工具,设置参数为115200 8-N-1。下载完程序之后,在串口调试助手窗口可接收到信息。

/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
CubeMX_1.jpg
CubeMX_2.jpg
CubeMX_3.jpg
CubeMX_4.jpg
CubeMX_5.jpg
CubeMX_6.jpg


bsp_NRF24L01.c文件内容
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: bsp_NRF24L01.c
  4.   * 作    者: 硬石嵌入式开发团队
  5.   * 版    本: V1.0
  6.   * 编写日期: 2015-10-04
  7.   * 功    能: NRF24L01无线模块底层驱动实现
  8.   ******************************************************************************
  9.   * 说明:
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
  11.   *
  12.   * 淘宝:
  13.   * 论坛:http://www.ing10bbs.com
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
  15.   ******************************************************************************
  16.   */

  17. /* 包含头文件 ----------------------------------------------------------------*/
  18. #include "NRF24L01/bsp_NRF24L01.h"

  19. /* 私有类型定义 --------------------------------------------------------------*/
  20. /* 私有宏定义 ----------------------------------------------------------------*/                              
  21. /* 私有变量 ------------------------------------------------------------------*/
  22. SPI_HandleTypeDef hspi_NRF24L01;
  23. const uint8_t TX_ADDRESS[TX_ADR_WIDTH]={0xb0,0x43,0x10,0x10,0x01}; //发送地址
  24. const uint8_t RX_ADDRESS[RX_ADR_WIDTH]={0xb0,0x43,0x10,0x10,0x01};

  25. /* 扩展变量 ------------------------------------------------------------------*/
  26. /* 私有函数原形 --------------------------------------------------------------*/
  27. /* 函数体 --------------------------------------------------------------------*/

  28. /**
  29.   * 函数功能: 串行FLASH初始化
  30.   * 输入参数: huart:串口句柄类型指针
  31.   * 返 回 值: 无
  32.   * 说    明: 该函数被HAL库内部调用
  33. */
  34. void NRF24L01_SPI_Init(void)
  35. {
  36.   hspi_NRF24L01.Instance = NRF24L01_SPIx;
  37.   hspi_NRF24L01.Init.Mode = SPI_MODE_MASTER;
  38.   hspi_NRF24L01.Init.Direction = SPI_DIRECTION_2LINES;
  39.   hspi_NRF24L01.Init.DataSize = SPI_DATASIZE_8BIT;
  40.   hspi_NRF24L01.Init.CLKPolarity = SPI_POLARITY_LOW;
  41.   hspi_NRF24L01.Init.CLKPhase = SPI_PHASE_1EDGE;
  42.   hspi_NRF24L01.Init.NSS = SPI_NSS_SOFT;
  43.   hspi_NRF24L01.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  44.   hspi_NRF24L01.Init.FirstBit = SPI_FIRSTBIT_MSB;
  45.   hspi_NRF24L01.Init.TIMode = SPI_TIMODE_DISABLE;
  46.   hspi_NRF24L01.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  47.   hspi_NRF24L01.Init.CRCPolynomial = 10;
  48.   HAL_SPI_Init(&hspi_NRF24L01);
  49.   __HAL_SPI_ENABLE(&hspi_NRF24L01);
  50. }

  51. /**
  52.   * 函数功能: SPI外设系统级初始化
  53.   * 输入参数: hspi:SPI句柄类型指针
  54.   * 返 回 值: 无
  55.   * 说    明: 该函数被HAL库内部调用
  56.   */
  57. void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
  58. {
  59.   GPIO_InitTypeDef GPIO_InitStruct;
  60.   if(hspi->Instance==NRF24L01_SPIx)
  61.   {
  62.     /* SPI外设时钟使能 */
  63.     NRF24L01_SPIx_RCC_CLK_ENABLE();
  64.     /* GPIO外设时钟使能 */
  65.     NRF24L01_SPI_GPIO_ClK_ENABLE();
  66.     NRF24L01_SPI_CS_CLK_ENABLE();
  67.     NRF24L01_CE_CLK_ENABLE();
  68.     NRF24L01_IRQ_CLK_ENABLE();
  69.    
  70.     /* Disable the Serial Wire Jtag Debug Port SWJ-DP */
  71.     __HAL_AFIO_REMAP_SWJ_DISABLE();
  72.    
  73.     /**SPI3 GPIO Configuration   
  74.     PF11     ------> SPI3_NSS
  75.     PB3      ------> SPI3_SCK
  76.     PB4      ------> SPI3_MISO
  77.     PB5      ------> SPI3_MOSI
  78.     */
  79.     GPIO_InitStruct.Pin = NRF24L01_SPI_SCK_PIN|NRF24L01_SPI_MOSI_PIN;
  80.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  81.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  82.     HAL_GPIO_Init(NRF24L01_SPI_GPIO_PORT, &GPIO_InitStruct);

  83.     GPIO_InitStruct.Pin = NRF24L01_SPI_MISO_PIN;
  84.     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  85.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  86.     HAL_GPIO_Init(NRF24L01_SPI_GPIO_PORT, &GPIO_InitStruct);
  87.    
  88.     HAL_GPIO_WritePin(NRF24L01_SPI_CS_PORT, NRF24L01_SPI_CS_PIN, GPIO_PIN_SET);
  89.     GPIO_InitStruct.Pin = NRF24L01_SPI_CS_PIN;
  90.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  91.     HAL_GPIO_Init(NRF24L01_SPI_CS_PORT, &GPIO_InitStruct);
  92.    
  93.     HAL_GPIO_WritePin(NRF24L01_CE_PORT, NRF24L01_CE_PIN, GPIO_PIN_RESET);
  94.     GPIO_InitStruct.Pin = NRF24L01_CE_PIN;
  95.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  96.     HAL_GPIO_Init(NRF24L01_CE_PORT, &GPIO_InitStruct);
  97.    
  98.     GPIO_InitStruct.Pin = NRF24L01_IRQ_PIN;
  99.     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  100.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  101.     HAL_GPIO_Init(NRF24L01_IRQ_PORT, &GPIO_InitStruct);
  102.   }
  103. }

  104. /**
  105.   * 函数功能: SPI外设系统级反初始化
  106.   * 输入参数: hspi:SPI句柄类型指针
  107.   * 返 回 值: 无
  108.   * 说    明: 该函数被HAL库内部调用
  109.   */
  110. void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
  111. {

  112.   if(hspi->Instance==NRF24L01_SPIx)
  113.   {
  114.     /* SPI外设时钟禁用 */
  115.     NRF24L01_SPIx_RCC_CLK_DISABLE();
  116.   
  117.     /**SPI3 GPIO Configuration   
  118.     PF11     ------> SPI3_NSS
  119.     PB3      ------> SPI3_SCK
  120.     PB4      ------> SPI3_MISO
  121.     PB5      ------> SPI3_MOSI
  122.     */
  123.     HAL_GPIO_DeInit(NRF24L01_SPI_GPIO_PORT, NRF24L01_SPI_SCK_PIN|NRF24L01_SPI_MISO_PIN|NRF24L01_SPI_MOSI_PIN);
  124.     HAL_GPIO_DeInit(NRF24L01_SPI_CS_PORT, NRF24L01_SPI_CS_PIN);
  125.     HAL_GPIO_DeInit(NRF24L01_CE_PORT, NRF24L01_CE_PIN);
  126.     HAL_GPIO_DeInit(NRF24L01_IRQ_PORT, NRF24L01_IRQ_PIN);
  127.   }
  128. }


  129. /**
  130.   * 函数功能: 往串行Flash读取写入一个字节数据并接收一个字节数据
  131.   * 输入参数: byte:待发送数据
  132.   * 返 回 值: uint8_t:接收到的数据
  133.   * 说    明:无
  134.   */
  135. uint8_t SPIx_ReadWriteByte(SPI_HandleTypeDef* hspi,uint8_t byte)
  136. {
  137.   uint8_t d_read,d_send=byte;
  138.   if(HAL_SPI_TransmitReceive(hspi,&d_send,&d_read,1,0xFF)!=HAL_OK)
  139.   {
  140.     d_read=0xFF;
  141.   }
  142.   return d_read;
  143. }

  144. /**
  145.   * 函数功能: 检测24L01是否存在
  146.   * 输入参数: 无
  147.   * 返 回 值: 0,成功;1,失败
  148.   * 说    明:无         
  149.   */
  150. uint8_t NRF24L01_Check(void)
  151. {
  152.         uint8_t buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
  153.         uint8_t i;
  154.   
  155.         NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.        
  156.         NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址  
  157.         for(i=0;i<5;i++)if(buf[i]!=0XA5)break;                                                                    
  158.         if(i!=5)return 1;//检测24L01错误        
  159.         return 0;                 //检测到24L01
  160. }                  

  161. /**
  162.   * 函数功能: SPI写寄存器
  163.   * 输入参数: 无
  164.   * 返 回 值: 无
  165.   * 说    明:reg:指定寄存器地址
  166.   *           
  167.   */
  168. uint8_t NRF24L01_Write_Reg(uint8_t reg,uint8_t value)
  169. {
  170.         uint8_t status;        
  171.   NRF24L01_SPI_CS_ENABLE();                 //使能SPI传输
  172.   status =SPIx_ReadWriteByte(&hspi_NRF24L01,reg);//发送寄存器号
  173.   SPIx_ReadWriteByte(&hspi_NRF24L01,value);      //写入寄存器的值
  174.   NRF24L01_SPI_CS_DISABLE();                 //禁止SPI传输           
  175.   return(status);                               //返回状态值
  176. }

  177. /**
  178.   * 函数功能: 读取SPI寄存器值
  179.   * 输入参数: 无
  180.   * 返 回 值: 无
  181.   * 说    明:reg:要读的寄存器
  182.   *           
  183.   */
  184. uint8_t NRF24L01_Read_Reg(uint8_t reg)
  185. {
  186.         uint8_t reg_val;            
  187.          NRF24L01_SPI_CS_ENABLE();          //使能SPI传输               
  188.   SPIx_ReadWriteByte(&hspi_NRF24L01,reg);   //发送寄存器号
  189.   reg_val=SPIx_ReadWriteByte(&hspi_NRF24L01,0XFF);//读取寄存器内容
  190.   NRF24L01_SPI_CS_DISABLE();          //禁止SPI传输                    
  191.   return(reg_val);           //返回状态值
  192. }        

  193. /**
  194.   * 函数功能: 在指定位置读出指定长度的数据
  195.   * 输入参数: 无
  196.   * 返 回 值: 此次读到的状态寄存器值
  197.   * 说    明:无
  198.   *           
  199.   */
  200. uint8_t NRF24L01_Read_Buf(uint8_t reg,uint8_t *pBuf,uint8_t len)
  201. {
  202.         uint8_t status,uint8_t_ctr;           
  203.   
  204.   NRF24L01_SPI_CS_ENABLE();           //使能SPI传输
  205.   status=SPIx_ReadWriteByte(&hspi_NRF24L01,reg);//发送寄存器值(位置),并读取状态值              
  206.          for(uint8_t_ctr=0;uint8_t_ctr<len;uint8_t_ctr++)
  207.   {
  208.     pBuf[uint8_t_ctr]=SPIx_ReadWriteByte(&hspi_NRF24L01,0XFF);//读出数据
  209.   }
  210.   NRF24L01_SPI_CS_DISABLE();       //关闭SPI传输
  211.   return status;        //返回读到的状态值
  212. }

  213. /**
  214.   * 函数功能: 在指定位置写指定长度的数据
  215.   * 输入参数: 无
  216.   * 返 回 值: 无
  217.   * 说    明:reg:寄存器(位置)  *pBuf:数据指针  len:数据长度
  218.   *           
  219.   */
  220. uint8_t NRF24L01_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t len)
  221. {
  222.         uint8_t status,uint8_t_ctr;            
  223.          NRF24L01_SPI_CS_ENABLE();          //使能SPI传输
  224.   status = SPIx_ReadWriteByte(&hspi_NRF24L01,reg);//发送寄存器值(位置),并读取状态值
  225.   for(uint8_t_ctr=0; uint8_t_ctr<len; uint8_t_ctr++)
  226.   {
  227.     SPIx_ReadWriteByte(&hspi_NRF24L01,*pBuf++); //写入数据         
  228.   }
  229.   NRF24L01_SPI_CS_DISABLE();       //关闭SPI传输
  230.   return status;          //返回读到的状态值
  231. }                                   

  232. /**
  233.   * 函数功能: 启动NRF24L01发送一次数据
  234.   * 输入参数: 无
  235.   * 返 回 值: 发送完成状况
  236.   * 说    明:txbuf:待发送数据首地址
  237.   *           
  238.   */
  239. uint8_t NRF24L01_TxPacket(uint8_t *txbuf)
  240. {
  241.         uint8_t sta;
  242.         NRF24L01_CE_LOW();
  243.   NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF  32个字节
  244.          NRF24L01_CE_HIGH();//启动发送         
  245.   
  246.         while(NRF24L01_IRQ_PIN_READ()!=0);//等待发送完成
  247.   
  248.         sta=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值           
  249.         NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
  250.         if(sta&MAX_TX)//达到最大重发次数
  251.         {
  252.                 NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器
  253.                 return MAX_TX;
  254.         }
  255.         if(sta&TX_OK)//发送完成
  256.         {
  257.                 return TX_OK;
  258.         }
  259.         return 0xff;//其他原因发送失败
  260. }

  261. /**
  262.   * 函数功能:启动NRF24L01接收一次数据
  263.   * 输入参数: 无
  264.   * 返 回 值: 无
  265.   * 说    明:无
  266.   *           
  267.   */
  268. uint8_t NRF24L01_RxPacket(uint8_t *rxbuf)
  269. {
  270.         uint8_t sta;                                                                              
  271.         sta=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值            
  272.         NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
  273.         if(sta&RX_OK)//接收到数据
  274.         {
  275.                 NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
  276.                 NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
  277.                 return 0;
  278.         }           
  279.         return 1;//没收到任何数据
  280. }                                            

  281. /**
  282.   * 函数功能: 该函数初始化NRF24L01到RX模式
  283.   * 输入参数: 无
  284.   * 返 回 值: 无
  285.   * 说    明:无
  286.   *           
  287.   */
  288. void NRF24L01_RX_Mode(void)
  289. {
  290.         NRF24L01_CE_LOW();         
  291.   NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0F);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC
  292.   NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);    //使能通道0的自动应答   
  293.   NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址           
  294.   NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);             //设置RF通信频率                  
  295.   NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
  296.   
  297.   NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度            
  298.    
  299.   NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(uint8_t*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
  300.         
  301.   NRF24L01_CE_HIGH(); //CE为高,进入接收模式
  302.   HAL_Delay(1);
  303. }                                                

  304. /**
  305.   * 函数功能: 该函数初始化NRF24L01到TX模式
  306.   * 输入参数: 无
  307.   * 返 回 值: 无
  308.   * 说    明:无
  309.   *           
  310.   */
  311. void NRF24L01_TX_Mode(void)
  312. {                                                                                                                 
  313.         NRF24L01_CE_LOW();            
  314.   NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(uint8_t*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址
  315.   NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(uint8_t*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK         

  316.   NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);     //使能通道0的自动应答   
  317.   NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址  
  318.   NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0xff);//设置自动重发间隔时间:4000us + 86us;最大自动重发次数:15次
  319.   NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);       //设置RF通道为40
  320.   NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);  //设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
  321.   NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);    //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
  322.         NRF24L01_CE_HIGH();//CE为高,10us后启动发送
  323.   HAL_Delay(1);
  324. }
  325.    
  326. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码
串口调试助手截图.jpg

收藏 1 评论16 发布时间:2016-7-29 09:00

举报

16个回答
stary666 回答时间:2016-7-29 10:46:51
HenryChen 回答时间:2016-11-9 17:18:11
感谢楼主分享
回答时间:2016-11-9 22:24:29
感谢,先收藏了
andypanfan 回答时间:2016-11-10 09:06:46
感谢分享
peter001 回答时间:2016-11-19 01:02:22
楼主费心,支持
jackten 回答时间:2016-11-27 21:28:48
谢谢楼主分享
xiaoye82 回答时间:2016-12-2 17:03:38
感谢分享
zhangdaijin 回答时间:2016-12-2 17:10:21
谢谢分享啊
逍遥李 回答时间:2017-8-14 10:17:27
楼主链接已失效,是否可以更新一下?
haohao663 回答时间:2017-8-18 09:16:06
链接:https://pan.baidu.com/s/1nvtZhVV 密码:416v 硬石科技开源资料网盘下载链接(2017-08-03更新).pdf (530.23 KB, 下载次数: 9)
莫~ 回答时间:2018-5-5 17:31:37
谢谢分享
joneing 回答时间:2018-6-4 14:02:42

楼主链接已失效,是否可以更新一下?
haohao663 回答时间:2018-6-5 18:29:52
joneing 回答时间:2018-6-6 11:37:07
回复挣金币下载帮顶
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版