logo资料库

零死角玩转stm32-中级篇-2.4G无线(NRF24L01).pdf

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
0、友情提示
9、2.4G无线(NRF24L01+)
9.1 实验描述及工程文件清单
9.2 NRF24L01模块简介
9.3 代码分析
9.4 实验想象
0、友情提示 《零死角玩转 STM32》系列教程由初级篇、中级篇、高级篇、系统篇、 四个部分组成,根据野火 STM32 开发板旧版教程升级而来,且经过重新深入编 写,重新排版,更适合初学者,步步为营,从入门到精通,从裸奔到系统,让 您零死角玩转 STM32。M3 的世界,与野火同行,乐意惬无边。 另外,野火团队历时一年精心打造的《STM32 库开发实战指南》将于今 年 10 月份由机械工业出版社出版,该书的排版更适于纸质书本阅读以及更有利 于查阅资料。内容上会给你带来更多的惊喜。是一本学习 STM32 必备的工具 书。敬请期待! -第 2 页-
9、2.4G 无线(NRF24L01+) 9.1 实验描述及工程文件清单 实验描述 利用 NRF24L01+无线模块,使两块 STM32 开发板实现无线 传输数据。用串口输出实验结果到 pc。 硬件连接 PA4-SPI1-NSS : W25X16-CS PA5-SPI1-SCK : W25X16-CLK PA6-SPI1-MISO : W25X16-DO PA7-SPI1-MOSI : W25X16-DIO 用到的库文件 startup/start_stm32f10x_hd.c CMSIS/core_cm3.c CMSIS/system_stm32f10x.c FWlib/stm32f10x_gpio.c FWlib/stm32f10x_rcc.c FWlib/stm32f10x_usart.c FWlib/stm32f10x_spi.c 用户编写的文件 USER/main.c USER/stm32f10x_it.c USER/usart1.c SPI_NRF.c 野火 STM32 开发板 2.4G 无线模块接口图: -第 3 页-
9.2 NRF24L01 模块简介 本实验采用的无线模块芯片型号为 NRF24L01+,是工作在 2.4~2.5GHz 频段的,具备自动重发功能,6 个数据传输通道,最大无线传输速率为 2Mbits。MCU 可与该芯片通过 SPI 接口访问芯片的寄存器进行配置。 以下是该模块的硬件电路: 截图来自《NRF24l01 模块说明书.pdf》,page3 注意:这个模块的工作电压为 3.3V,实验时请把 vcc 接到板上的 3v3 接 口,超过 3.6v 该模块会烧坏! 引脚说明及本实验中与开发板的连接: Pin Name Description 与开发板相连 Chip Enable Activates RX or TX mode 排针 P5 的 PA2 CE CSN SCK SPI Chip Select SPI Clock 1 2 3 4 5 6 7 排针 P3 的 PA1 排针 P5 的 PA5 排针 P5 的 PA7 MOSI SPI Slave Data Input MISO SPI Slave Data Output, with tri-state option 排针 P5 的 PA6 IRQ VDD Maskable interrupt pin. Active low 排针 P5 的 PA3 Power Supply (+1.9V - +3.6V DC) 电源 3v3 -第 4 页-
8 VSS Ground (0V) 电源 GND 接口 这个例程采用的是 STM32 的 SPI1 接口,但其中的硬件 SPI1-CSN 端口 (用于片选)已经在 2M-FLASH 上采用,所以本实验用一个空闲端口 PA1 用 作无线模块的片选,由软件产生片选信号。 请注意区分这个模块的 CSN 片选信号与 CE 使能信号的功能。 CSN 端口是 SPI 通讯协议中的片选端。多个 SPI 设备可以共用 STM32 的 SCK,MISO,MOSI 端口,不同的设备间就是用 CSN 来区分。 CE 实际是 NRF24L01 的芯片使能端,通过配置 CE 可以使 NRF24L01 进入不同的状态。如下图示: 截图来自:《nRF24L01P(新版无线模块控制 IC).PDF》,page24. 9.3 代码分析 这个实验用到两个代码,主机和从机的代码驱动是一样的,区别只是 main 中函数调用的流程不一样,从机接收模式的时候,相应的主机在发送模式。 附从机流程图: -第 5 页-
下面以的从机的代码为例进行分析。 首先要添加用的库文件,在工程文件夹下 Fwlib 下我们需添加以下库文 件: 1. stm32f10x_gpio.c 2. stm32f10x_rcc.c 3. stm32f10x_usart.c 4. stm32f10x_spi.c 还要在 stm32f10x_conf.h 中把相应的头文件添加进来: 1. 2. 3. 4. #include "stm32f10x_gpio.h" #include "stm32f10x_spi.h" #include "stm32f10x_rcc.h" #include "stm32f10x_usart.h" -第 6 页-
进入 main 函数,边看代码边了解程序的流程: 1. int main(void) 2. { 3. /* 串口 1 初始化 */ 4. USART1_Config(); 5. 6. /*SPI 接口初始化*/ 7. SPI_NRF_Init(); 8. 9. printf("\r\n 这是一个 NRF24L01 无线传输实验 \r\n"); 10. printf("\r\n 这是无线传输 从机端 的反馈信息\r\n"); 11. printf("\r\n 正在检测 NRF 与 MCU 是否正常连接。。。\r\n"); 12. 13. /*检测 NRF 模块与 MCU 的连接*/ 14. status = NRF_Check(); 15. if(status == SUCCESS) 16. printf("\r\n NRF 与 MCU 连接成功\r\n"); 17. else 18. printf("\r\n 正在检测 NRF 与 MCU 是否正常连接。。。\r\n"); 19. 20. while(1) 21. { 22. printf("\r\n 从机端 进入接收模式\r\n"); 23. NRF_RX_Mode(); 24. 25. /*等待接收数据*/ 26. status = NRF_Rx_Dat(rxbuf); 27. 28. /*判断接收状态*/ 29. if(status == RX_DR) 30. { 31. for(i=0;i<4;i++) 32. { 33. printf("\r\n 从机端 接收到 主机端 发送的数据 为:%d \r\n",rxbuf[i]); 34. /*把接收的数据+1 后发送给主机*/ 35. rxbuf[i]+=1; 36. txbuf[i] = rxbuf[i]; 37. } 38. } 39. printf("\r\n 从机端 进入自应答发送模式\r\n"); 40. NRF_TX_Mode(); 41. 42. /*不断重发,直至发送成功*/ 43. do 44. { 45. status = NRF_Tx_Dat(txbuf); 46. }while(status == MAX_RT); 47. } 48. } 报告野火,这个代码错了,没有调用 SystemInit()函数来设置时钟!是的, 大家熟悉的 SystemInit()函数不见了,但这样并没有出错,原因是这个例程的库 是 3.5 版本的!在 3.5 版本的库中 SystemInit()函数在启动文件 startup_stm32f10x_hd.d 中已用汇编语句调用了,设置的时钟为默认的 72M。 所以在 main 函数就不需要再调用啦,当然,再调用一次也是没问题的。 -第 7 页-
关于 USART1_Config()函数,是用来配置串口的,关于这两个函数的具体讲解 可以参考前面的教程,这里不再详述。 接着进入 SPI_NRF_Init()函数是怎样配置 STM32 的 SPI 接口的: 1. void SPI_NRF_Init(void) 2. { 3. SPI_InitTypeDef SPI_InitStructure; 4. GPIO_InitTypeDef GPIO_InitStructure; 5. 6. /*使能 GPIOB,GPIOD,复用功能时钟*/ 7. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE|RCC _APB2Periph_AFIO, ENABLE); 8. 9. /*使能 SPI1 时钟*/ 10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 11. 12. /*配置 SPI_NRF_SPI 的 SCK,MISO,MOSI 引脚,GPIOA^5,GPIOA^6,GPIOA^7 */ 13. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; 14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 15. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能 16. GPIO_Init(GPIOA, &GPIO_InitStructure); 17. 18. /*配置 SPI_NRF_SPI 的 CE 引脚,GPIOA^2 和 SPI_NRF_SPI 的 CSN 引 脚: NSS GPIOA^1*/ 19. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_1; 20. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 21. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 22. GPIO_Init(GPIOA, &GPIO_InitStructure); 23. 24. /*配置 SPI_NRF_SPI 的 IRQ 引脚,GPIOA^3*/ 25. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; 26. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 27. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //上拉输入 28. GPIO_Init(GPIOA, &GPIO_InitStructure); 29. 30. /* 这是自定义的宏,用于拉高 csn 引脚,NRF 进入空闲状态 */ 31. NRF_CSN_HIGH(); 32. 33. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; / /双线全双工 34. SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 主模式 35. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 数据大小 8 位 36. SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // 时钟极性,空闲时为低 37. SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第 1 个边沿有效,上升沿为采样时刻 38. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // NSS 信号由软件产生 39. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //8 分频,9MHz 40. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 高位在前 41. SPI_InitStructure.SPI_CRCPolynomial = 7; 42. SPI_Init(SPI1, &SPI_InitStructure); 43. 44. /* Enable SPI1 */ 45. SPI_Cmd(SPI1, ENABLE); 46. } -第 8 页-
分享到:
收藏