|
项目设计的前言:作为一个嵌入式的工程师,在编写代码时候,难免会遇到不同电平之间的转换。例如:RS485通讯方式,RS232,TTL信号,为了查看通讯之间数据的正确性,经常使用到不同的电平转换模块,还需要一个USB转串口工具,将数据上传到PC端,这样我们才能将查看控制器或者是负载返回的数据,为了避免调试代码起来方便,让自己的工作变得整洁,方便我们自己的工作,前端时间正好研究SPI通讯方式的NRF24L01这款无线芯片,利用业余时间做了一个无线通讯模块。在这里分享一下开发的经验。 一:部分原理图设计:- J# d1 w# p# ?2 @ ; z j4 E" V* D6 }. s0 A" G/ O 二:PCB图展示: , A$ _+ ?& b v! y6 E; V8 G0 u& k 三:软硬件设计的思路:; y' d I- h4 s+ K( Z" `2 W9 N; t 在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。 1 q% d; q; }* s 无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。. C( I6 ?5 t; G$ g: K! v 软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。 . W. m/ N. Z0 k9 V8 H 使用串口2完成与SPI之间的交互, 软件配置参数:使用STM32cube MX软件生成USB,SPI,串口底层的驱动部分,这样开发起来也比较容易;6 L2 s# C3 g' M7 X3 f + y/ d/ ^" O+ _2 I0 {! X+ S* Q9 P! H" j; Y cube软件配置图如下,主要是对该项目中使用到的引脚进行配置9 d& G! e9 B/ Y7 \$ }! X' C  # [2 g$ G6 O! I( R 部分软件代码: & v; [9 d0 m6 Y3 H7 H3 T0 m8 C ```abc i% h* C: j4 @+ ]& `* g# s" N if(sd == 0) { USART_Cmd(USART2, ENABLE); //使能串口 if( linecoding_old.bitrate != linecoding.bitrate || linecoding_old.datatype != linecoding.datatype ||8 E3 z" q! f: w. }4 W. e linecoding_old.format != linecoding.format || linecoding_old.paritytype != linecoding.paritytype ) { if( usart2_flag == 0 )" ^5 h1 v2 K6 f) a% t {3 T& A7 n8 T0 Y+ S; s uart2_config_change(linecoding);( t o$ z7 q" T, P& _% q memcpy((void *)(&linecoding_old),(void *)&linecoding,sizeof(linecoding));& {# b$ j5 G9 U ~: x- \( ]# ^ }: o; _' A& A. Q6 \3 \ }& I* z8 y( ]- ^: f else if(queue_size(&Qusart2Send) > 0 && usart2_flag == 0)5 o* k/ q( ?- f3 W3 i {9 a; Z- X' O1 U4 O% C* Z9 X0 f QueueElementByte data_byte;7 v7 @! K `$ c# \+ X usart2_flag = 1; if(dequene(&Qusart2Send,&data_byte) == 0 ) {0 r( b2 g! ?& O2 @ USART_SendData(USART2,data_byte.buffer); }+ e8 P6 J9 F4 |9 r USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断8 W* I$ y( U2 J! a) h! Y } 4 g2 J1 U$ `$ S5 B4 N if(GetEPRxStatus(ENDP6) == EP_RX_NAK)9 E5 n% h% w4 f+ a9 z7 B. D8 Y {! g+ ~4 b6 }% s# |" N, ]5 q/ [7 f SetEPRxValid(ENDP6); } if(GetEPRxStatus(ENDP4) == EP_RX_NAK) {" W& P7 W5 d5 r) `0 W if(CDC_MAXSIZE - queue_size(&Qusart2Send) >= 64 )9 d8 |: c* }, ^; u4 [6 y, L SetEPRxValid(ENDP4); } & m9 P, h/ {7 g3 h, n# Y4 R3 @ if(nrf_state == 0) NRF24L01_TxPacket(buffer,1); } else Q" |. L K0 Z+ N9 n+ z {3 [6 i5 {# w1 ]1 {( H1 D( W USART_Cmd(USART2, DISABLE); //失能串口 ( X0 }) P. @1 ~' t, d if(nrf_state == 0)% m; o+ o0 D. G% P6 A {7 |$ D7 [: M1 s if(dap2nrf_Data() == -1): F L+ {% B& G8 P1 t! ^# R# Y { if(GetEPRxStatus(ENDP6) == EP_RX_NAK)" Z0 N9 [, r- j( M; E' M# g1 l# T { SetEPRxValid(ENDP6); Z. P# d! u. J. g+ [. }: o a }& ~ B* b6 C) J6 Z) T 1 _0 F5 o& ~7 r$ R& }( G if( linecoding_old.bitrate != linecoding.bitrate || linecoding_old.datatype != linecoding.datatype || linecoding_old.format != linecoding.format || linecoding_old.paritytype != linecoding.paritytype )4 z- d3 n: \8 A- N) G {. m, F' ~1 k/ U buffer[0] = 33;//特殊串口设置指令4 V& e4 s8 C4 ?4 B) ?. D3 l memcpy((void *)(buffer+1),(void *)&linecoding,sizeof(linecoding)); NRF24L01_TxPacket(buffer,sizeof(linecoding)+1); }* x' G8 F9 r8 z, R* o else if(queue_size(&Qusart2Send) > 0)3 W! s" ~% L1 E7 F) Z {9 H- U- L: a- I! Q2 V% \ QueueElementByte data_byte; for(i = 1; i < 32; i ++)$ S* Q3 ?+ s8 x& X( ~0 H4 j% K {' \5 W6 ~8 R, a% j% r if(dequene(&Qusart2Send,&data_byte) == -1 ) break;- h" c5 C2 V& {) V0 J buffer = data_byte.buffer;' g1 `$ q% E3 U } buffer[0] = i - 1; NRF24L01_TxPacket(buffer,buffer[0]+1);% ]' U* ?8 ]5 S/ A } else d; w( i0 K: J {5 g4 b# ~% D$ }* L. s& Q/ }1 m% Q if(GetEPRxStatus(ENDP4) == EP_RX_NAK)3 a9 P1 M, f9 ? r- y {1 W2 M: U6 d4 I4 H8 ^( [! }4 V* f, y0 B SetEPRxValid(ENDP4);1 i+ t4 g; g; f) R; [ }% v. `$ C+ L2 U1 z& K& ` buffer[0] = 0; NRF24L01_TxPacket(buffer,1); }6 |5 C3 U' b0 w; c& L% V9 Q5 a }! R# u! X* W+ f) O }* N$ e, g/ m2 Z& f, Q3 y2 _ } ``` 实物使用截图如下:8 u% {3 w: U6 d! z 2 f/ X2 r+ q3 @0 @. A  0 i( U/ [2 W- ]' _$ k9 ^) R 在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。 2 J9 V5 F+ _* f; _% v5 c9 B 使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。 硬件设计的时候,设计注意事项: ( h+ c! r- `1 } R3 j! s 使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。 % x8 [: T1 j; A- R- Q2 s* L" X. ? MP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。 ) K8 `4 D& i5 N: H+ d PW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。 同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。 - i0 i2 F( H# w1 l6 k: Q3 R3 ` 在软件开发时候,有以下的注意事项:0 g, h0 b" q9 d) G: G+ O7 ] 抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。 功耗管理:在不需要通信时及时将NRF24L01置于待机模式或掉电模式以降低功耗。7 T9 E) b( @1 Z S9 s v$ t' @3 L3 Y e0 J; n 距离与障碍物:无线通信距离受环境因素影响较大,障碍物会严重影响通信质量。在实际应用中要考虑通信距离和障碍物的影响并采取相应的措施。; E, u7 R: i9 D* }4 y# N/ ^ 1 L0 ~" p$ l1 U/ a- X: \ NRF24L01的开发过程需要仔细规划硬件连接、合理配置软件参数、掌握调试技巧并关注实际应用中的注意事项。通过不断的实践和总结可以逐渐提高开发效率和应用效果。" ]" J2 ~. A. ]4 F( b, G6 `) N1 G& K 原理图见附件:: r( ^$ {$ y \; R+ x ; i$ E: ]$ D% C) V+ {! ?, j5 r- E  |
DMA 原理从 0 到 1:为什么它能解放 CPU?一文讲透 DMA 的工作流程
【福利三:雨露均沾·逢7狂欢】之五:STM32系统时钟PLL故障排除1例
【福利三:雨露均沾·逢7狂欢】之三:AI帮我查BUG
福利三:雨露均沾·逢7狂欢】之二:STM32F407VG串口通信乱码故障的排除
基于STM32F103的I2C主从机通信
OpenBLT移植到STM32F103战舰开发板上适用于所有STM32F103系列的Bootloader
TFT LCD 与 FSMC 的硬件连接大容量 STM32F10xxx FSMC 接口
单片机:初学者该了解的STM32F103基础知识
2025软件工具兔哥知道
STM32之继电器模块
微信公众号
手机版
重新上传一下 原理图!!!