1、

Similar documents
嵌入式系統期中報告

乙太網路 : 簡介 : 乙太網路 (Ethernet) 是一種電腦區域網路組網技術 IEEE 制定的 IEEE 標準給出了乙太網路的技術標準 它規定了包括物理層的連線 電訊號和介質存取層協定的內容 乙太網路是當前應用最普遍的區域網路技術 它很大程度上取代了其他區域網路標準, 如令牌環網

中文手册

bingdian001.com

Microsoft Word - GT21L16S2W简要说明V3.7.doc

Tel:

ATMEL AT90S8515 AVR CPU AVR AVR AVR ATMEL RISC 32 8 r0 r X Y Z R0 R1 R2 R13 R14 R15 R16 R17 R26 R27 R28 R29 R30 R31 0x00 0x

2

JLX

stm32_mini_v2

Microsoft Word - MAN2023A_CH_APPONE.doc

Microsoft Word - MSP430 Launchpad 指导书.docx

51 C 51 isp 10 C PCB C C C C KEIL

a b c d e f g C2 C1 2

#include <reg51

TH2512/TH2512A Tonghui Electronics reserves the right to make changes at any time without notice in order to improve design and supply the best possib

MCU DSP MSO MCU DSP MSO MSO MSO MCU/DSP I/O MSO 16 Microchip IC18 turn-on MSO chirp MCU I/O I 2 C

6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C C C51 C51 ANSI C MCS-51 C51 ANSI C C C51 bit Byte bit sbit

<4D F736F F D20B5DAC8FDCBC4D5C2D7F7D2B5B4F0B0B82E646F63>

(Load Project) (Save Project) (OffLine Mode) (Help) Intel Hex Motor

外围器件-new.cdr

Microsoft Word - MAN2011A_CH_RTT.doc

目录 1 IPv6 快速转发 IPv6 快速转发配置命令 display ipv6 fast-forwarding aging-time display ipv6 fast-forwarding cache ipv6 fas

untitled

ARM Cortex-M3 (STM32F) STMicroelectronics ( ST) STM32F103 Core: ARM 32-bit Cortex -M3 CPU 72 MHz, 90 DMIPS with 1.25 DMIPS/MHz Single-cycle multiplica

2 12

CC213

2005.book

ICD ICD ICD ICD ICD

下 图 是 连 接 的 方 法 在 这 篇 文 章 里 还 会 介 绍 如 何 建 立 大 量 的 进 程 无 线 节 点, 如 何 将 这 些 传 感 器 集 成 到 一 个 开 源 家 庨 自 劢 化 服 务 器 除 了 在 手 机 App 上 看 到 家 里 的 情 形 外, 你 还 可 以

<4D F736F F D20CBABC1FA DA3A8BAACB6C1D0B44D31A3A9C4A3BFE9D7CAC1CF B0E62E646F63>

PCM-3386用户手册.doc

ST template WORD

Microsoft Word - ~ doc

untitled

Using STM32 Software Library

untitled

FET848

邏輯分析儀的概念與原理-展示版

FM1935X智能非接触读写器芯片

<4D F736F F D20B9F9B0EABBCDBBAFAB48DEB3B4C1A5BDB3F8A7692E646F63>

1-1 SH79F6431 A. 2( ) 9~15V ( 12V) U2 U3 3.3V SH79F B. 1(VCC/GND) SH79F6431 C. VDDIO SH79F6431 P4 P5 P0.6 P0.7 VDDIO VDDIO=5V D. 2 V 1.0

行业

行业

NORCO-740 CPU M/00M NORCO-740 NORCO-740E NORCO-740G NORCO-740GE Intel 845GL Intel 845G

行业

目录

Microsoft Word - 实用案例.doc

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File

untitled

USB解决方案.ppt

FPGAs in Next Generation Wireless Networks WPChinese

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例

目录 1 IPv6 快速转发 IPv6 快速转发配置命令 display ipv6 fast-forwarding aging-time display ipv6 fast-forwarding cache ipv6 fas

C语言的应用.PDF

展 望 与 述 评 2 广 电 设 备 与 技 术

12232A LED LED LED EL EL CCFL EL CCF

Microsoft Word - GTC doc

2 Keil µ vision 2.1 1) Keil µ vision2 V2.34 µ vision3 2) Sino_Keil.exe Keil c:\keil\ 3) JET51 USB PC C:\Keil\ USB PC 4) S-L

1 CAN 69 4 接受滤波 CAN CRC LLC 超载通知数恢复管理 CAN 据数据封装 / 拆装 5 链帧编码 ( 填充 / 解除 ) 媒体访问管理 路 CAN 应答 SAE J CAN 1 1 CAN 层 1CAN CAN 7 CAN 1 2 2CAN CAN 1 58%


SPMC75F2413A_EVM_使用说明_V1.2.doc

C PICC C++ C++ C C #include<pic.h> C static volatile unsigned char 0x01; static volatile unsigned char 0x02; static volatile unsigned cha

PCI Express

T stg -40 to 125 C V cc 3.8V V dc RH 0 to 100 %RH T a -40 to +125 C -0.3 to 3.6V V -0.3 to VDD+0.3 V -10 to +10 ma = 25 = 3V) VDD

投影片 1

本实验需要用到两个特征值, 两个特征值的属性各不相同, 我们同样在 SimpleGATTProfile 中新建即可, 接下来就开始吧 新建特征值表 : 表 3.3 串口透传特征值属性 长度 属性 UUID 功能 (byte) SIMPLEPROFILE_CHA R6 15 可读可写 FFF6 服务器

B 6 A A N A S A +V B B B +V 2

untitled

128K Flash EPROM 的程序?\(Bank=64K\) 切?

<4D F736F F F696E74202D20C9E4C6B5D3EBCAFDC4A3BBECBACFC0E0B8DFCBD C9E8BCC62D E707074>

技 术 支 持 电 话 传 真 电 子 邮 件 网 址 CONVERGE PRO 880/880T/840T/8i, CON

内置协议及链路层、具有六路接收通道

第一章

untitled

untitled

系统架构 - 模块划分 功能 状态机 H265 主要的模块 : 1. 顶层模块 H265ENC_top 包括 sys_ctrl,enc_core 及 fetch 三个模块 2. sys_ctrl 就是一个状态机, 控制 fetch 和 enc_core 中各子模块的工作 3. enc_core 编码

21 flash

《將進酒》

学习MSP430单片机推荐参考书

chap07.key

50-FB23-24_BES_V_ z1_ b

General Description: Preliminary TTP916 Consumer IC VCD/DVD LCD Green mode Stand-by mode( 1W ) Features: 2.2V-5.5V LCD RAM read condition 2.6V-5.5V RC

() () () () () () () () DDRAM () II

Transcription:

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 与开发板相连 1 CE Chip Enable Activates RX or TX mode 排针 P5 的 PA2 2 CSN SPI Chip Select 排针 P3 的 PA1 3 SCK SPI Clock 排针 P5 的 PA5 4 MOSI SPI Slave Data Input 排针 P5 的 PA7 5 MISO SPI Slave Data Output, with tri-state option 排针 P5 的 PA6 6 IRQ Maskable interrupt pin. Active low 排针 P5 的 PA3 7 VDD 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. #include "stm32f10x_gpio.h" 2. #include "stm32f10x_spi.h" 3. #include "stm32f10x_rcc.h" 4. #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 页 -

基本流程就是 : 1. 开启所用到的端口的时钟 GPIOA, 复用时钟 AFIO,SPI1 时钟 其中 AFIO 时钟是因为 GPIOA 是用作 SPI 方式的, 所以别忘记开启它 2. 配置 SPI 的模式, 配置 SPI 模式的关键是时钟极性 (CPOL) 第 36 行, 和时钟相位 (CPHA) 第 37 行 这是根据 NRF24L01 的时序图来设置的 所谓时钟极性, 就是 SPI 端口在空闲的时候,SCK 的电平, 例程中为低电平 而时钟相位, 则是 SPI 采集数据的时钟边沿, 例程中为第一个时钟边沿 ( 上升沿 ) 截图来自 : nrf24l01p( 新版无线模块控制 IC).PDF,page52 继续分析 main 函数, 在第 14 行调用了 NRF_Check() 函数, 分析一下它 : 1. u8 NRF_Check(void) 2. { 3. u8 buf[5]={0xc2,0xc2,0xc2,0xc2,0xc2}; 4. u8 buf1[5]; 5. u8 i; 6. 7. /* 写入 5 个字节的地址. */ 8. SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,buf,5); 9. 10. /* 读出写入的地址 */ 11. SPI_NRF_ReadBuf(TX_ADDR,buf1,5); 12. 13. /* 比较 */ 14. for(i=0;i<5;i++) 15. { 16. if(buf1[i]!=0xc2) 17. break; 18. } 19. 20. if(i==5) 21. return SUCCESS ; //MCU 与 NRF 成功连接 22. else - 第 9 页 -

23. return ERROR ; //MCU 与 NRF 不正常连接 24. } 这个函数是通过调用 SPI_NRF_WriteBuf() 和 SPI_NRF_ReadBuf() 函数, 对 NRF 的地址寄存器进行读写, 先向寄存器写入数据, 再读取出来进行比较, 以此来检验 NRF24L01 是否与 MCU 正常连接的 SPI_NRF_WriteBuf() 和 SPI_NRF_ReadBuf() 函数很类似, 前者实现向寄存器写入一串数据, 后者实现读取数据功能 下面以 SPI_NRF_WriteBuf() 为例 : 1. u8 SPI_NRF_WriteBuf(u8 reg,u8 *pbuf,u8 bytes) 2. { 3. u8 status,byte_cnt; 4. NRF_CE_LOW(); 5. /* 置低 CSN, 使能 SPI 传输 */ 6. NRF_CSN_LOW(); 7. 8. /* 发送寄存器号 */ 9. status = SPI_NRF_RW(reg); 10. 11. /* 向缓冲区写入数据 */ 12. for(byte_cnt=0;byte_cnt<bytes;byte_cnt++) 13. SPI_NRF_RW(*pBuf++); // 写数据到缓冲区 14. 15. /*CSN 拉高, 完成 */ 16. NRF_CSN_HIGH(); 17. 18. return (status); // 返回 NRF24L01 的状态 19. } SPI_NRF_WriteBuf() 调用了 SPI_NRF_RW() 函数 : 1. u8 SPI_NRF_RW(u8 dat) 2. { 3. /* 当 SPI 发送缓冲器非空时等待 */ 4. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); 5. 6. /* 通过 SPI2 发送一字节数据 */ 7. SPI_I2S_SendData(SPI1, dat); 8. 9. /* 当 SPI 接收缓冲器为空时等待 */ 10. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); 11. 12. /* Return the byte read from the SPI bus */ 13. return SPI_I2S_ReceiveData(SPI1); 14. } SPI_NRF_WriteBuf() 流程 : 1. 使 CE 端口置低,SPI 通讯时先进入待机模式 使 CSN 端口置 低, 开启 SPI 通讯 - 第 10 页 -

2. 调用 SPI_NRF_RW() 向 NRF 发送将要写入的寄存器地址,SPI_NRF_RW () 返回的是 STATUS 寄存器的数据 ( 不是将要操作的寄存器的值哦!) 3. 连续写入数据, 最后拉高 CSN 端口, 结束 SPI 传输 命令的组织形式 : 完整的写命令 = 写命令 + 寄存器地址 截图来自 : nrf24l01p( 新版无线模块控制 IC).PDF,page51 写时序 : 截图来自 : nrf24l01p( 新版无线模块控制 IC).PDF,page52 回到 main 函数, 检查完 NRF 与 MCU 的连接, 从机开始进入接收模 式 NRF_RX_Mode() 函数 : 1. void NRF_RX_Mode(void) 2. 3. { 4. NRF_CE_LOW(); 5. 6. SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); // 写 RX 节点地址 7. 8. SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); // 使能通道 0 的自动应 答 9. 10. SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01);// 使能通道 0 的接收地 址 11. 12. SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); // 设置 RF 通信频 率 13. - 第 11 页 -

14. SPI_NRF_WriteReg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);// 选择通道 0 的有效数据宽度 15. 16. SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f); // 设置 TX 发射参数,0db 增益,2Mbps, 低噪声增益开启 17. 18. SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG, 0x0f); // 配置基本工作模式的参数 ;PWR_UP,EN_CRC,16BIT_CRC, 接收模式 19. 20. /*CE 拉高, 进入接收模式 */ 21. NRF_CE_HIGH(); 22. } 配置接收模式和发送模式都是向 NRF 寄存器写入配置参数, 这些参数具体 意义在 nrf24l01p( 新版无线模块控制 IC).PDF,page57 要注意的是从机和主机的参数要一致 下面是发送模式的配置 : 1. void NRF_TX_Mode(void) 2. { 3. NRF_CE_LOW(); 4. 5. SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); // 写 TX 节点地址 6. 7. SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); // 设置 TX 节点地址, 主要为了使能 ACK 8. 9. SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); // 使能通道 0 的自动应 答 10. 11. SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01); // 使能通道 0 的接收地 址 12. 13. SPI_NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x1a);// 设置自动重发间隔时 间 :500us + 86us; 最大自动重发次数 :10 次 14. 15. SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); // 设置 RF 通道为 CHANAL 16. 17. SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f); // 设置 TX 发射参数,0db 增益,2Mbps, 低噪声增益开启 18. 19. SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x0e); // 配置基本工作模式的参 数 ;PWR_UP,EN_CRC,16BIT_CRC, 发射模式, 开启所有中断 20. 21. /*CE 拉高, 进入发送模式 */ 22. NRF_CE_HIGH(); 23. Delay(0xffff); //CE 要拉高一段时间才进入发送模式 24. } 在发送模式配置要特别注意一点, 第 23 行, 延时,STM32 运行频率比 NRF 模块快得多, 不加延时直接发送数据的话很容易导致发送出错 - 第 12 页 -

截图来自 : nrf24l01p( 新版无线模块控制 IC).PDF,page42 回到 main 函数, 配置完接收模式后就开始等待 NRF 模块传来中断接收数据 由 NRF_Rx_Dat() 函数来实现 : 1. u8 NRF_Rx_Dat(u8 *rxbuf) 2. { 3. u8 state; 4. NRF_CE_HIGH(); // 进入接收状态 5. /* 等待接收中断 */ 6. while(nrf_read_irq()!=0); 7. 8. NRF_CE_LOW(); // 进入待机状态 9. /* 读取 status 寄存器的值 */ 10. state=spi_nrf_readreg(status); 11. 12. /* 清除中断标志 */ 13. SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state); 14. 15. /* 判断是否接收到数据 */ 16. if(state&rx_dr) // 接收到数据 17. { 18. SPI_NRF_ReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);// 读取数据 19. SPI_NRF_WriteReg(FLUSH_RX,NOP); // 清除 RX FIFO 寄存 器 20. return RX_DR; 21. } 22. else 23. return ERROR; // 没收到任何数据 24. } - 第 13 页 -

接收流程 : 1. 等待 IRQ 引脚的信号,NRF 模块在接收到数据, 发送完成数据, 或重发超过次数都会在 IRQ 引脚进行标志 ( 这个实验中采用的是 STM32 循环读取 IRQ 引脚信号, 实际上可以把这个引脚配置成外部中断来减轻 MCU 的负担, 读者可以一试 ) 关于 NRF 整个无线传输过程可以参照 nrf24l01p( 新版无线模块控制 IC).PDF 的 page36~37 页的流程图 2. 读取状态寄存器的值来判断是否接收正常, 利用 SPI_NRF_ReadBuf() 来从接收缓冲区读取数据到 STM32 3. 清中断 ( 通过向 STATUS 寄存器写 1 可以清除相应的中断位 ), 清空接收缓冲区 到这里就把所有的 NRF 驱动应用函数解说完啦! ^_^ 回到 main 函数, 从机把接收到的数据都加 1 之后再发送给主机, 主机又把数据发送回从机 如此循环, 就是整个实验的流程 9.4 实验想象 实验时请先开启从机的电源, 再开启主机的电源, 这是代码的流程决定 的 - 第 14 页 -

实验效果 : 从机的反馈 : 主机的反馈 : - 第 15 页 -

- 第 16 页 -