找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于STM32F429的NRF24L01无线通信源码

[复制链接]
跳转到指定楼层
楼主
ID:470567 发表于 2019-1-19 15:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机源码:
基于STM32F429的NRF24L01无线通信.7z (573.24 KB, 下载次数: 56)

  1. #include "24l01.h"
  2. #include "spi.h"
  3. #include "delay.h"
  4. #include "led.h"

  5. const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址
  6. const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址
  7. //针对NRF24L01修改SPI2驱动
  8. void NRF24L01_SPI_Init(void)
  9. {
  10.     __HAL_SPI_DISABLE(&SPI2_Handler);               //先关闭SPI2
  11.     SPI2_Handler.Init.CLKPolarity=SPI_POLARITY_LOW; //串行同步时钟的空闲状态为低电平
  12.     SPI2_Handler.Init.CLKPhase=SPI_PHASE_1EDGE;     //串行同步时钟的第1个跳变沿(上升或下降)数据被采样
  13.     HAL_SPI_Init(&SPI2_Handler);
  14.     __HAL_SPI_ENABLE(&SPI2_Handler);                //使能SPI2
  15. }
  16. //初始化24L01的IO口
  17. void NRF24L01_Init(void)
  18. {
  19.     GPIO_InitTypeDef GPIO_Initure;
  20.     __HAL_RCC_GPIOG_CLK_ENABLE();   //开启GPIOG时钟
  21.     __HAL_RCC_GPIOI_CLK_ENABLE();   //开启GPIOI时钟
  22.    
  23.     GPIO_Initure.Pin=GPIO_PIN_10|GPIO_PIN_12; //PG10,12
  24.     GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
  25.     GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
  26.     GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
  27.     HAL_GPIO_Init(GPIOG,&GPIO_Initure);     //初始化
  28.      
  29.     GPIO_Initure.Pin=GPIO_PIN_11;           //PI11
  30.     GPIO_Initure.Mode=GPIO_MODE_INPUT;      //输入
  31.     HAL_GPIO_Init(GPIOI,&GPIO_Initure);     //初始化
  32.    
  33.     SPI2_Init();                      //初始化SPI2  
  34.     NRF24L01_SPI_Init();                    //针对NRF的特点修改SPI的设置
  35.    NRF24L01_CE=0;                    //使能24L01
  36.    NRF24L01_CSN=1;                   //SPI片选取消      
  37. }
  38. //检测24L01是否存在
  39. //返回值:0,成功;1,失败
  40. u8 NRF24L01_Check(void)
  41. {
  42. u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
  43. u8 i;
  44. SPI2_SetSpeed(SPI_BAUDRATEPRESCALER_4); //spi速度为11.25Mhz(24L01的最大SPI时钟为10Mhz,这里大一点没关系)      
  45. NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.
  46. NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址  
  47. for(i=0;i<5;i++)if(buf[i]!=0XA5)break;            
  48. if(i!=5)
  49. {
  50.   //LED0=0;
  51.   return 1;
  52. }//检测24L01错误
  53. else
  54. {
  55.   //LED1=0;
  56. return 0;
  57. }  //检测到24L01
  58. }   
  59. //SPI写寄存器
  60. //reg:指定寄存器地址
  61. //value:写入的值
  62. u8 NRF24L01_Write_Reg(u8 reg,u8 value)
  63. {
  64.    u8 status;
  65.     NRF24L01_CSN=0;                 //使能SPI传输
  66.    status =SPI2_ReadWriteByte(reg);//发送寄存器号
  67.    SPI2_ReadWriteByte(value);      //写入寄存器的值
  68.    NRF24L01_CSN=1;                 //禁止SPI传输   
  69.    return(status);             //返回状态值
  70. }
  71. //读取SPI寄存器值
  72. //reg:要读的寄存器
  73. u8 NRF24L01_Read_Reg(u8 reg)
  74. {
  75.    u8 reg_val;     
  76.     NRF24L01_CSN=0;             //使能SPI传输  
  77.    SPI2_ReadWriteByte(reg);    //发送寄存器号
  78.    reg_val=SPI2_ReadWriteByte(0XFF);//读取寄存器内容
  79.    NRF24L01_CSN=1;             //禁止SPI传输      
  80.    return(reg_val);            //返回状态值
  81. }
  82. //在指定位置读出指定长度的数据
  83. //reg:寄存器(位置)
  84. //*pBuf:数据指针
  85. //len:数据长度
  86. //返回值,此次读到的状态寄存器值
  87. u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
  88. {
  89.    u8 status,u8_ctr;        
  90.    NRF24L01_CSN=0;            //使能SPI传输
  91.    status=SPI2_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值      
  92.     for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPI2_ReadWriteByte(0XFF);//读出数据
  93.    NRF24L01_CSN=1;            //关闭SPI传输
  94.    return status;             //返回读到的状态值
  95. }
  96. //在指定位置写指定长度的数据
  97. //reg:寄存器(位置)
  98. //*pBuf:数据指针
  99. //len:数据长度
  100. //返回值,此次读到的状态寄存器值
  101. u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
  102. {
  103.    u8 status,u8_ctr;     
  104.     NRF24L01_CSN=0;             //使能SPI传输
  105.    status = SPI2_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
  106.    for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPI2_ReadWriteByte(*pBuf++); //写入数据  
  107.    NRF24L01_CSN=1;             //关闭SPI传输
  108.    return status;              //返回读到的状态值
  109. }      
  110. //启动NRF24L01发送一次数据
  111. //txbuf:待发送数据首地址
  112. //返回值:发送完成状况
  113. u8 NRF24L01_TxPacket(u8 *txbuf)
  114. {
  115. u8 sta;
  116.   SPI2_SetSpeed(SPI_BAUDRATEPRESCALER_8); //spi速度为6.75Mhz(24L01的最大SPI时钟为10Mhz)   
  117. NRF24L01_CE=0;
  118.    NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF  32个字节
  119.   NRF24L01_CE=1;                         //启动发送   
  120. while(NRF24L01_IRQ!=0);                 //等待发送完成
  121. sta=NRF24L01_Read_Reg(STATUS);          //读取状态寄存器的值   
  122. NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
  123. if(sta&MAX_TX)                          //达到最大重发次数
  124. {
  125.   NRF24L01_Write_Reg(FLUSH_TX,0xff);  //清除TX FIFO寄存器
  126.   return MAX_TX;
  127. }
  128. if(sta&TX_OK)                           //发送完成
  129. {
  130.   return TX_OK;
  131. }
  132. return 0xff;//其他原因发送失败
  133. }
  134. //启动NRF24L01发送一次数据
  135. //txbuf:待发送数据首地址
  136. //返回值:0,接收完成;其他,错误代码
  137. u8 NRF24L01_RxPacket(u8 *rxbuf)
  138. {
  139. u8 sta;               
  140. SPI2_SetSpeed(SPI_BAUDRATEPRESCALER_8); //spi速度为6.75Mhz(24L01的最大SPI时钟为10Mhz)   
  141. sta=NRF24L01_Read_Reg(STATUS);          //读取状态寄存器的值      
  142. NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
  143. if(sta&RX_OK)//接收到数据
  144. {
  145.   NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
  146.   NRF24L01_Write_Reg(FLUSH_RX,0xff);  //清除RX FIFO寄存器
  147.   return 0;
  148. }   
  149. return 1;//没收到任何数据
  150. }         
  151. //该函数初始化NRF24L01到RX模式
  152. //设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR
  153. //当CE变高后,即进入RX模式,并可以接收数据了     
  154. void NRF24L01_RX_Mode(void)
  155. {
  156.    NRF24L01_CE=0;   
  157.    NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
  158.    
  159.    NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);       //使能通道0的自动应答   
  160.    NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);   //使能通道0的接收地址   
  161.    NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);         //设置RF通信频率   
  162.    NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度      
  163.    NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);    //设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
  164.    NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);     //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式
  165.    NRF24L01_CE=1; //CE为高,进入接收模式
  166. }      
  167. //该函数初始化NRF24L01到TX模式
  168. //设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR
  169. //PWR_UP,CRC使能
  170. //当CE变高后,即进入RX模式,并可以接收数据了     
  171. //CE为高大于10us,则启动发送.  
  172. void NRF24L01_TX_Mode(void)
  173. {               
  174. NRF24L01_CE=0;     
  175.   NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址
  176.   NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK   
  177.   NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);     //使能通道0的自动应答   
  178.   NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址  
  179.   NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
  180.   NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);       //设置RF通道为40
  181.   NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);  //设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
  182.   NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);    //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
  183. NRF24L01_CE=1;//CE为高,10us后启动发送
  184. }
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:362795 发表于 2021-3-13 11:18 来自手机 | 只看该作者
我下载看了下SPI,只开了SPI5的PF时钟,SPI2在PB口的时钟不用开吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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