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

NUCLEO_L552ZE_Q 『人生中的首块STM32L552开发板』┅ nRF24L01双机...

[复制链接]
三界狗 发布时间:2020-3-26 00:14
上回在NUCLEO_L552ZE_Q_STM32Nucleo_144 开发板上测试了外部中断的使用,本想着这回来一篇有关TrustZone的文章,毕竟这才是Cortex-M33的重要的内容,于是花了些时间去研究,然而现实总是那么残酷,在这碰了壁,自己建立的工程下载进去之后没有反应,就想着先去看看官方给的GPIO_IOToggle_TrustZone例程,按照说明文件里的步骤下载到开发板上,结果还是没有任何反应,我也是一头雾水,在网上也找不到任何有关的资料,说明文档是英文的,看得也是一知半解的,所以就没弄成,还是决定先放在一边吧,不能被这个耽搁了。恰好手上有两个nRF24L01P模块,还有两块stm32f103c8t6小板子,于是就鼓捣了一下使用它们来做个无线通信测试,下面就请跟随我进入正题吧。7 H$ p0 S7 P2 A
评测内容:
( b& j( d5 W+ f1、使用STM32F103C8T6系统板连接nRF24L01P作为主机发送一固定长度字符串,NUCLEO_L552ZE_Q_STM32Nucleo_144 开发板的板载SPI通信接口连接nRF24L01P作为从机接收,并且通过uart串口将接收到的数据发送到PC上位机显示,使用板载LED指示发送和接收状态。
0 H8 f" ~  ?  e8 A所需元件:  m  V3 X* h, V+ Q% x* p
1、NUCLEO_L552ZE_Q_STM32Nucleo_144 开发板*1
4 J0 o+ w; n- A, j: ~9 U2、STM32F103C8T6系统板*1;# h4 T3 q+ ~. b1 r8 w/ L' Q3 a
3、nRF24L01P模块*2;
6 B' N+ ~$ `3 I& q2、板载红色LED;
9 Z7 m. [: }! S

$ f2 ~0 p% h0 Q  J) a评测步骤:
9 A. u5 h6 w) Q) F1、新建工程:1 Z. x9 T7 ?6 v0 E& y
本次测评我使用STM32CubeMX的开发板模板进行工程创建,针对NUCLEO_L552ZE_Q_STM32Nucleo_144 开发板上的板载硬件已经默认帮配置好了,只需要根据自己的需求配置SPI接口便可以了,按照如下步骤便可创建一个开发板的默认配置工程;
/ A  e; g+ F2 m. m  ?; a
1-1.png

; x) M" V% j, r
1-2.png
; l$ O1 `7 X- d$ R0 t7 p
2、配置SPI接口:' Q/ ]& U+ c' I- I' H
根据下图配置将SPI接口设置好,SPI接口使用的是开发板上的CN7排座的SPI_A接口,在STM32CubeMX上SPI1的默认SCK引脚在PA1上,我根据开发板的原理图将其改到了PA5,需要注意的是,nRF24L01P的IRQ引脚需要设置成上拉输入模式;
+ C! X9 Z4 h5 \# W1 |, A
1-3.png
% Q6 K9 M% x3 p3 S
nRF24L01P的SPI接口
) d9 h& Y, b/ V6 I( `% |$ |8 a
1-4.png
1 Y* U8 D8 o; j2 t% V# K" j
SPI配置选项

* a2 \9 V% b& `
1-5.png
4 ]" \' t# [: v3 L
开发板接口原理图
: ]& `' R. A, U, T
3、设置串口波特率:
+ v% c! H& E* \% V, |开发板上与STLink虚拟串口连接使用的是LPUART1,工程创建的时候已经默认配置好了,使用PG7和PG8两个引脚,波特率为209700Bits/s,这个波特率不是我想要的,所以将它改成了921600Bits/s;
1 V2 w- z2 k9 F8 C
3-1.png
8 z4 r$ t- b( m) `# ?
4、保存工程:1 f; ^# c1 o) Z8 p$ R" h
保存好配置工程并且生成MDK_v5工程;
; M" E7 r# z0 H! X
4-1.png
# [5 z& |3 L$ O8 Z3 z  W
5、测试串口的工作情况:
. H# T: _8 \, k5 E# s因为不能保证nRF24L01P能够顺利的工作,因此我是先测试串口能够正常工作之后再考虑加入nRF24L01P;这也是一种调试代码的技巧,一点点来,不然什么东西都一下子加上,调试的时候出问题就会不清楚问题的出处具体是在哪里;
: ^+ K! v) e- {在这里,又再一次体现出了HAL库强大的封装工艺了,在标准库函数上要实现发送一个字符串,需要自己调用串口发送字符的函数来循环实现发送字符串的函数,而在HAL库上,只需要一个函数,不管是发送字符还是发送字符串,统统都能搞定。
# C3 |3 q( p! O) X/ f$ Q- V+ j+ n6 H就像以前学习串口通信的时候发送Hello World一样,添加如下代码到main函数的循环里,2 O$ a% J7 t5 g5 m, @0 X2 g
  1. HAL_UART_Transmit(&hlpuart1, "Hello World !!!\r\n", 17, 100);
    & L, W4 }4 y: c4 \; _
  2. HAL_Delay(500);
复制代码
将代码编译连接通过后下载到开发板上,按下开发板右下角的复位键后,便能在串口助手上看到如下打印的信息,说明串口工作正常;6 K. }* R, S6 E4 H  ]% }! O9 s
5-1.png

4 X+ f2 e5 }9 t, @* ^$ E7 d6、添加nRF24L01P相关的代码:
0 G" t# S3 q* _3 p! h3 fnRF24L01P的代码我使用的是购买该模块的时候官方提供的测试模板,模块使用的是泽耀科技生产的挪威原装芯片nRF24L01P模块,不是黑色PCB板那种,但应该都是通用的,接口也是一样的,已经成功在我的STM32F103C8T6系统板上正常收发了,代码我会在末尾的附件中给出,2 X( U3 B) f1 I% F7 k/ h3 P
复制模板的nRF24L01P源代码和头文件到本工程中并添加到工程里;
) S5 N0 t% }, S  B* t4 z
6-1.png
- ?" j8 Y  ^; b3 p1 g# v0 _" J1 h
由于使用的环境不一样,需要做一点修改,首先是引脚宏定义,在nRF24L01P.h文件的开头添加#include "main.h",并且将不需要的头文件包含去掉nRF24L01P.h文中定义了模块的CSN、CE、IRQ三个接口的引脚,改成如下;
- g6 a3 M) C1 @
  1. /** RF24L01硬件接口定义 */
    8 p  i) F  M  {' `) _+ P2 q; J) A$ g
  2. #define RF24L01_CE_GPIO_PORT                        GPIOD9 Z# K: U1 E4 A% F- H$ x
  3. #define RF24L01_CE_GPIO_PIN                                GPIO_PIN_15
    ' g, A1 c# S7 L4 e
  4.   |% ]( }7 U5 @. ]) m( L. w
  5. #define RF24L01_CS_GPIO_PORT                        GPIOD
    8 B# \3 J) g; l+ `3 }# j
  6. #define RF24L01_CS_GPIO_PIN                                GPIO_PIN_14# d: F( }" B0 I+ Q# k9 m& a

  7. . C5 g/ J; d+ c( A$ r4 N
  8. #define RF24L01_IRQ_GPIO_PORT                        GPIOF! ?4 V, f# @8 I# i  a( w1 j. A
  9. #define RF24L01_IRQ_GPIO_PIN                        GPIO_PIN_12
复制代码
然后是nRF24L01P.c文件中的延时函数,替换成HAL库的延时函数,并且注释掉500Ms的延时函数(HAL库的延时函数能够延时500ms以上),相应的调用延时函数的地方再做点修改;' r! m  {. A, N7 q; C+ V5 H
  1. /**
    8 x5 {/ J4 J* o  L4 E0 ?* f# \
  2.   * @brief :NRF24L01 延时(Ms)
    & A% b' s- z- e) u) X* h3 a8 S% \
  3.   * @param :1 e9 l1 B; [# T3 |
  4.            @TxByte:延时的Ms数
    9 o6 m) x+ F! c( S9 Q- t0 y8 p
  5.   * @note  :不超过2^32。; Q2 I3 k/ q0 ~7 d% G0 L
  6.   * @retval:无
    3 ~; L; y5 t5 ~0 M, R2 k; m
  7.   */
    5 N6 x* c' N1 p! M  N0 u. }
  8. static void NRF24L01_delay_ms(uint32_t Ms)6 Y; u8 M& `( U% [
  9. {- G3 p3 b) z8 \- |0 o  @$ g6 s
  10.         HAL_Delay(Ms);2 {( i. _0 H2 R& b  A& y5 Q6 s
  11. }
    ! ^! n; o6 S+ o. Q8 g2 \' B. H4 a

  12. $ b5 D% H  K7 ], D* K$ R
  13. /**
    & O) s5 n2 i2 j2 }6 R* y
  14.   * @brief :NRF24L01 延时(500Ms)
    1 ~8 h% E* q" R( Y1 O+ ~# D8 s# G- D' z9 i
  15.   * @param :# T! ]5 v/ ~. Z2 b, [
  16.            @Ms_500:延时的500Ms倍数6 N' L1 N' d) r" w% W
  17.   * @note  :不超过255。7 N0 k' q2 l8 U& I$ W% E) x" j
  18.   * @retval:无
    $ J* w) {% N% r+ ?; X7 z
  19.   */
    ! @. f2 J4 U, a" `# m  v- V
  20. //static void NRF24L01_delay_500ms(uint8_t Ms_500)
    . G( J$ K, h/ J$ ~1 s! a
  21. //{
    0 c) c$ c; h, P: Z" \
  22. //        drv_delay_500Ms(Ms_500);5 {) o$ Q6 N% m+ k
  23. //}
复制代码

! J4 L$ |- R$ r% E0 i' k接下来是将SPI读写函数替换HAL库的SPI读写函数,在这里又再一次凸显出了HAL库的那个简单易用的优点;
/ v* y( H. p3 X2 H5 H$ l) f
  1. /**
    2 e! ?( J4 i* Z4 Z" n4 Z
  2.   * @brief :NRF24L01 SPI收发一个字节/ H  l+ k) A% @* e$ v3 b% U7 K
  3.   * @param :
    ) i: i2 A- l' }0 g, u* N6 q
  4.            @TxByte:发送的数据字节
    4 d+ E0 a2 F; C! x' k& c% g0 e
  5.   * @note  :接口函数,方便移植。
    ) h9 j, k+ S/ e4 ?) J: u+ f/ w
  6.   * @retval:读取的数据3 N. G4 V( y* ~0 z% c% F* a# ^
  7.   */
    * A7 k5 O2 X2 v0 w# b
  8. static uint8_t nRF24L01_SPI_RW_Byte( uint8_t TxByte )# Q( n! q4 |2 R
  9. {
    * ]$ M5 g/ L6 N. w5 d( r$ B" k
  10.         uint8_t RxByte;* [  U7 G( m$ Q6 I
  11.         + ?4 w" M9 a4 k9 Y: L. C; |
  12.         HAL_SPI_TransmitReceive(&hspi1, &TxByte, &RxByte, 1, 100);9 X+ h/ ]4 M8 \" f9 W( M, ?
  13.         - T+ S* p. r7 ^, x) e, ]" _7 V* M
  14.         return RxByte;( M/ l2 h9 n% f6 e0 p
  15. }
复制代码
再接下来,nRF24L01P.c文件实现了nrf24L01P使用到的GPIO口的初始化函数NRF24L01_Gpio_Init,由于使用的固件库不一样,且main.c文件中已经统一初始化了,所以就将该函数的内容注释掉,并且注释掉所有调用的地方。编译工程,没有问题说明移植成功。
/ p) g# Y) V/ f. z+ d+ J7、编写代码实现无线接收功能:nRF24L01P.h包含到main.c文件中,在文件开头定义一个用于接收数据的数组;
3 O7 y+ }6 P2 _3 N% Z+ J+ S
  1. uint8_t g_RF24L01RxBuffer[ 32 ] = { 0 };
复制代码
) Q# p( O# u1 p; K+ m
在main函数中添加如下代码,实现nRF24L01P的无线接收功能
0 K& U& e) a5 h. O0 a4 A
  1. uint8_t i;
    ' ]0 I0 G4 t" O; ^# u
  2.           f: j$ [# n- V, s$ `3 w
  3.   /* USER CODE BEGIN 1 */9 U" I  G( w% N5 V! L

  4. * O3 e0 E* k3 N
  5.   /* USER CODE END 1 */
    # f& Z) f" B# K4 o/ I2 R
  6. 4 J4 Q( L% @7 t4 T( X' S& i2 V# r
  7.   /* MCU Configuration--------------------------------------------------------*/: c, o% Y4 k+ t1 N% a1 ], O9 k, `
  8. $ ^8 Q9 m, a; w: P
  9.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */5 s% m4 \* m% p/ b+ r
  10.   HAL_Init();
    . h+ b9 t. i' o- A- @& ^0 w
  11. # d: C6 F% t  ^2 b9 X
  12.   /* USER CODE BEGIN Init */
    0 j+ g( p; K! m" G
  13. # i* D, W. u' L- I  b4 N
  14.   /* USER CODE END Init */
    ; b2 @( w7 m4 o: ]5 U/ \! @
  15. " ]9 |* }4 j9 ]  I
  16.   /* Configure the system clock */
    , a! V4 u/ _. P/ N- w, q
  17.   SystemClock_Config();
    8 W9 n( v- R, R8 l7 x- S
  18. 3 t' E$ I5 Z4 ]8 B
  19.   /* USER CODE BEGIN SysInit */
    5 l* s6 X% E- {

  20. ' I$ T9 M6 h  f% U. b
  21.   /* USER CODE END SysInit */: I8 r  o/ x7 s& ~+ J' s( C# F1 C

  22. : Q" ^. G3 ^; ~. n# L) b  d, z
  23.   /* Initialize all configured peripherals */% _% X1 ], Q5 o, c' J2 F/ e6 f
  24.   MX_GPIO_Init();2 G7 L$ w9 I! Q0 B1 S2 s
  25.   MX_ADC1_Init();
    ' S$ H: P2 l1 M1 O. `. ~
  26.   MX_LPUART1_UART_Init();9 Z' H/ ?' p$ L) |# E; c6 c. }
  27.   MX_RTC_Init();, Y4 j% M( {9 U" Z1 x$ d. Y) t0 W  q
  28.   MX_SPI1_Init();
    / ?3 ?9 x6 G1 i5 g. X% |% e5 }2 a: }
  29.   MX_UCPD1_Init();  O7 C. N3 |3 B5 t* u$ @
  30.   MX_USB_PCD_Init();
    ' R/ f: r* @# I8 v4 D9 |, B
  31.   /* USER CODE BEGIN 2 */! ]! d- @, k+ x, a- D& O" E
  32.         NRF24L01_check( );                        //检测nRF24L01P是否已连接$ }: t0 j. }9 n( [/ c, i
  33.         RF24L01_Init( );                                //初始化nRF24L01P
    , b) G1 s9 \' V( h/ w+ n
  34.        
    + S2 b2 r( ?# I& K& y# W. g( ^
  35.         HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET);; d, Z6 L7 R: S% e
  36.         for( i = 0; i < 6; i++ )
    5 V, w, J% `5 N; R& Q1 v
  37.         {# q2 F+ Z' H+ D1 d' [& Z* ]% F
  38.                 HAL_GPIO_TogglePin(LED_RED_GPIO_Port, LED_RED_Pin);
    * A2 d" d) x0 o
  39.                 HAL_Delay( 500 );% ~7 C9 z& }: i# q
  40.         }  X  Z) Q0 p3 L3 a8 p
  41.         # d$ {% U& S" ~- r$ i* {
  42.         RF24L01_Set_Mode( MODE_RX );                //接收模式
    & q+ r' L$ F$ L+ `3 k
  43.   /* USER CODE END 2 */. R1 J) d2 [$ J/ @! x  P

  44.   W7 [! s4 M! d# f
  45.   /* Infinite loop */
    8 t6 P6 a& [5 ?; Q! c, r
  46.   /* USER CODE BEGIN WHILE */
    / s7 o' _6 A3 S& D! m4 z8 s
  47.   while (1)3 X2 c# X) Z# y8 ~
  48.   {. W! C) H, @/ t
  49.     /* USER CODE END WHILE */
    : a. t" H) R% H" v* U' L& O

  50. 5 E8 e* K& W4 Q# D" V
  51.     /* USER CODE BEGIN 3 */
    ; K4 q0 j- o, `: D& V/ ~, U; I
  52. , k3 G( d5 @5 `5 }; u& ]
  53.                 i = NRF24L01_RxPacket( g_RF24L01RxBuffer );                //接收字节5 r" f$ Z3 t" g  T# N! ]
  54.                 if( 0 != i )
    ) e' y5 V/ k. }7 ~7 ]) @
  55.                 {5 I" X0 E# ~  D) l5 Y7 S, {
  56.                         HAL_GPIO_TogglePin(LED_RED_GPIO_Port, LED_RED_Pin);/ Z  ]5 V9 K7 k9 F
  57.                         HAL_UART_Transmit(&hlpuart1, g_RF24L01RxBuffer, i, 100);                       
    6 V2 @* K( l2 H  J# r, y: A
  58.                 }
    " p5 b- C* d# `; W
  59.   }/ ]. S& g5 p# S4 m% ~; S$ i& U
  60.   /* USER CODE END 3 */
复制代码
8、运行结果:代码编译通过,烧录至开发板上,按下右下角的复位键,程序开始运行。发送端我使用的是官方测试模板小改动后在STM32F103C8T6系统板上实现的,在此就不详细阐述了,有需要可下载附件做参考。发送端和接收端都运行起来后,串口助手上也开始打印接收到的数据了;
8 c! D, G( S) X# A' T# r3 |
8-1.png
" [0 ^: T6 I' p  m
8-2.gif

+ t; a. J# f% r) X总结:$ r/ u9 Z) y6 G, J6 l- f. D& P$ B
nRF24L01对我来说是个噩梦,为了能够发挥NRF24L01P的最远传输距离,曾经一点点啃英文数据手册应用在51单片机上(黑色小模块给的例程都是NRF24L01而不是NRF24L01P的,前者的传输距离较短,后者的资料有点少),前些天为了将原先51单片机上程序移植到STM32上,荒废了几天时间,还是无法发送数据,气得我直接将模块给废了,然后就遇到了这款红色版的模块,例程和资料都可以再公司官网上下载到,很详细靠谱。. o% Z; J3 J6 N: p) p! T
NUCLEO_L552ZE_Q_STM32Nucleo_144 开发板的SPI和UART串口评测就这些,简单来说,使用HAL库来开发的代码确实要简单很多,开发板上的STLink还提供有虚拟串口,并且将SPI接口也都在一个地方引出来了,对于接线来说很方便。OK,有关nRF24L01P的细节东西比较多,有些地方没有阐述清楚的,欢迎在评论区指出。. }; P5 I) c  S# K2 i* V

7 K( B( w0 F) M  w/ C4 I7 _
9 m3 c# x: v& Y+ o

& Q8 ?: c/ L8 Z$ Z) C8 A4 ~, O
. m" o' }, V! u8 Y
nRF24L01P_TX.zip (4.45 MB, 下载次数: 2)
收藏 评论0 发布时间:2020-3-26 00:14

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版