|
项目设计的前言:作为一个嵌入式的工程师,在编写代码时候,难免会遇到不同电平之间的转换。例如:RS485通讯方式,RS232,TTL信号,为了查看通讯之间数据的正确性,经常使用到不同的电平转换模块,还需要一个USB转串口工具,将数据上传到PC端,这样我们才能将查看控制器或者是负载返回的数据,为了避免调试代码起来方便,让自己的工作变得整洁,方便我们自己的工作,前端时间正好研究SPI通讯方式的NRF24L01这款无线芯片,利用业余时间做了一个无线通讯模块。在这里分享一下开发的经验。5 _0 T* q5 _+ ?( f9 o$ [7 {: u 2 I5 @. k: D) K u7 p; U9 g 一:部分原理图设计: ( j: C1 K' w' Q! A2 o# ` ' x4 [8 s i" j . i4 M/ L9 r, I6 B2 t 二:PCB图展示:+ T; e2 s" x5 |; u x  三:软硬件设计的思路: m8 {/ i: E- c& x7 |6 D 在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。 无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。7 _/ C; `6 A* j 软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。 使用串口2完成与SPI之间的交互,$ n; e, X0 H! s- h : {: \* V0 ^( M. z 软件配置参数:使用STM32cube MX软件生成USB,SPI,串口底层的驱动部分,这样开发起来也比较容易; ( N4 \* r0 J* s cube软件配置图如下,主要是对该项目中使用到的引脚进行配置9 O' a, |5 V; o% C 7 ?) K0 E( k7 q+ h8 p 部分软件代码:" q/ h) X3 d4 l3 Z ```abc if(sd == 0)' o* y6 I$ q" v+ t7 p { USART_Cmd(USART2, ENABLE); //使能串口 if( linecoding_old.bitrate != linecoding.bitrate || linecoding_old.datatype != linecoding.datatype ||2 U. Z- \$ L7 I linecoding_old.format != linecoding.format ||% o: K! \, X8 x# I& V8 `% X linecoding_old.paritytype != linecoding.paritytype ). E' ` V7 @' ^1 ^ {1 ~) E8 U- m2 t8 ~ if( usart2_flag == 0 ) u# O. b5 `% h/ H { uart2_config_change(linecoding); memcpy((void *)(&linecoding_old),(void *)&linecoding,sizeof(linecoding)); }* s: s/ b' B3 @2 c* b' A }! W7 Q1 F! X: Z# r8 } else if(queue_size(&Qusart2Send) > 0 && usart2_flag == 0)% \! |, a4 }( o6 v6 O {3 P* B* l \* ?2 ~7 E7 R6 b; ^ QueueElementByte data_byte; usart2_flag = 1; if(dequene(&Qusart2Send,&data_byte) == 0 ) {# H2 s8 L/ e W USART_SendData(USART2,data_byte.buffer);6 r' M. D5 S" C' P+ Y* z% R } USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断 }& j2 o" }; N2 ^ 4 t: g- `$ q" d0 J+ C# O" x if(GetEPRxStatus(ENDP6) == EP_RX_NAK) { h9 G# m7 E% G4 c4 l SetEPRxValid(ENDP6);" D5 [8 ]( v& c# W' }9 h1 h+ l } if(GetEPRxStatus(ENDP4) == EP_RX_NAK)# q( r) _' L2 ~6 g u6 }9 h' q/ C { if(CDC_MAXSIZE - queue_size(&Qusart2Send) >= 64 )4 I/ s9 d$ |1 O SetEPRxValid(ENDP4);2 v9 H+ c6 j8 n. b( G/ e5 G }6 Y' @; H2 \" k8 P# R if(nrf_state == 0) NRF24L01_TxPacket(buffer,1); } else* X4 o' z8 i, ` [& l2 |, G { USART_Cmd(USART2, DISABLE); //失能串口 if(nrf_state == 0) {) D/ j9 U" I8 k. p2 D% [4 a* N8 ] if(dap2nrf_Data() == -1) {* e; Q% e% M2 P3 S& J if(GetEPRxStatus(ENDP6) == EP_RX_NAK) {( \2 Z# K. j2 X$ `6 q0 F SetEPRxValid(ENDP6); }7 a3 k1 l: W& ]. B: H8 ` `' ]# G) E* n" n4 T if( linecoding_old.bitrate != linecoding.bitrate || J0 \" k6 m# }) l1 J9 k linecoding_old.datatype != linecoding.datatype ||; P3 g8 z7 W, m L" S5 n4 [6 C linecoding_old.format != linecoding.format ||9 @- p2 ~& c. c% l! c# ]7 S' \$ {; {+ W linecoding_old.paritytype != linecoding.paritytype ) { }8 g0 {7 u. T& E4 p buffer[0] = 33;//特殊串口设置指令: X8 Y$ L3 h% G2 v w/ k* \ memcpy((void *)(buffer+1),(void *)&linecoding,sizeof(linecoding));/ O! r6 i: F' N0 F& {' h3 B NRF24L01_TxPacket(buffer,sizeof(linecoding)+1); }6 u( [; \. y9 w/ A, n* L else if(queue_size(&Qusart2Send) > 0)% s; Z+ I n3 G/ P2 x; P/ s { QueueElementByte data_byte; for(i = 1; i < 32; i ++)& u8 W! C# X8 d' m5 R: n' G { if(dequene(&Qusart2Send,&data_byte) == -1 )4 H3 |- \; _1 O/ D* Y' F0 j5 p break; buffer = data_byte.buffer; } buffer[0] = i - 1;. ?7 f* S1 [' [. \' D- V NRF24L01_TxPacket(buffer,buffer[0]+1);* } L/ j& O9 J( l4 K1 B; X2 _ g0 J } else { if(GetEPRxStatus(ENDP4) == EP_RX_NAK), z' Q8 u$ q0 K! j { SetEPRxValid(ENDP4); } buffer[0] = 0;; }5 c* O- W8 ^* A! I7 b- Q) } NRF24L01_TxPacket(buffer,1); y' ]6 Q' l, T, S1 ^3 U6 J } 0 _' X$ e) d9 V3 ^7 B* q }# N( {1 i2 l: L; w8 G } } ``` 实物使用截图如下:5 K! x6 m# B) U+ T2 i  5 V8 _. o0 r- Y$ j q# Y 在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。, C1 D' ?' F% d( f, G 使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。1 O! w7 n5 v: e( H. W 0 M* U% b. s( ?' _ 硬件设计的时候,设计注意事项:2 b) |1 v2 ?( z/ P4 v1 N $ z' b( y r6 _) a7 d L D 使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。/ x0 j3 \0 }6 |* O j7 h/ ^ MP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。 ! W# Q3 a: o/ _* v# k. C3 } PW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。 同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。 5 H& b4 Y! V9 B* l' r7 j 在软件开发时候,有以下的注意事项: 抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。 功耗管理:在不需要通信时及时将NRF24L01置于待机模式或掉电模式以降低功耗。$ R7 M8 `: s' f3 [ 距离与障碍物:无线通信距离受环境因素影响较大,障碍物会严重影响通信质量。在实际应用中要考虑通信距离和障碍物的影响并采取相应的措施。 NRF24L01的开发过程需要仔细规划硬件连接、合理配置软件参数、掌握调试技巧并关注实际应用中的注意事项。通过不断的实践和总结可以逐渐提高开发效率和应用效果。 ( M) e, ^( v' ^* L4 _ 原理图见附件: ; s+ P1 R" W3 z; h& F & Y( b/ g/ u: E+ e4 s/ G 6 i+ n/ o/ m, f8 h0 | |
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之继电器模块
微信公众号
手机版
重新上传一下 原理图!!!