|
项目设计的前言:作为一个嵌入式的工程师,在编写代码时候,难免会遇到不同电平之间的转换。例如:RS485通讯方式,RS232,TTL信号,为了查看通讯之间数据的正确性,经常使用到不同的电平转换模块,还需要一个USB转串口工具,将数据上传到PC端,这样我们才能将查看控制器或者是负载返回的数据,为了避免调试代码起来方便,让自己的工作变得整洁,方便我们自己的工作,前端时间正好研究SPI通讯方式的NRF24L01这款无线芯片,利用业余时间做了一个无线通讯模块。在这里分享一下开发的经验。5 H/ g+ N d& X3 k0 @, z' K & j$ q. B+ x5 Y* v( Y/ L 一:部分原理图设计: ) ^& j; G! @& K& D3 N 7 _ y9 Y/ |" ?5 n- b9 c; }/ M 二:PCB图展示:$ \& X1 ]$ i3 w: r0 m1 f; i; g & a7 B0 V6 q1 d8 J: J  三:软硬件设计的思路: & i9 k4 W1 M; L4 f( y0 O0 q- \+ w 在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。 4 A( Q$ ]( K7 f: p; }# ^. {+ J 无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。 软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。 . O& Z! y# R2 {" u 使用串口2完成与SPI之间的交互, 软件配置参数:使用STM32cube MX软件生成USB,SPI,串口底层的驱动部分,这样开发起来也比较容易;9 E8 A! ]; j. @) L6 P+ h/ x 1 _- z" c! {2 e( r( }$ C cube软件配置图如下,主要是对该项目中使用到的引脚进行配置 - a( |1 P6 L7 y2 {. L$ v # C$ g/ G( x+ }0 d 部分软件代码: ```abc( t' ~- h7 z, a& ~4 @ if(sd == 0): K. e( q: I& X1 H4 ~ {( N, i" n y3 j0 | o: v7 S USART_Cmd(USART2, ENABLE); //使能串口 if( linecoding_old.bitrate != linecoding.bitrate ||" m; Z9 P2 c* G0 { linecoding_old.datatype != linecoding.datatype || linecoding_old.format != linecoding.format || linecoding_old.paritytype != linecoding.paritytype ) { if( usart2_flag == 0 )* N- K0 y' D+ x+ x5 ]4 Y0 ~ { uart2_config_change(linecoding);8 Z- k0 `) \" `, ? memcpy((void *)(&linecoding_old),(void *)&linecoding,sizeof(linecoding));$ U. a1 o- J: T }5 A# w4 Q1 x' S7 K9 a/ C }) ~) }8 X! r- A* |0 M else if(queue_size(&Qusart2Send) > 0 && usart2_flag == 0) {' m0 w8 [: ?$ j* l2 ]8 l QueueElementByte data_byte;0 A3 @" n/ J/ y* l5 G% ` usart2_flag = 1; if(dequene(&Qusart2Send,&data_byte) == 0 )' ?; G S$ q0 ]; y {. W% |# x+ I4 F; M9 t USART_SendData(USART2,data_byte.buffer); }" p: r1 |" K N" C$ p USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断 } if(GetEPRxStatus(ENDP6) == EP_RX_NAK)+ _4 b2 b1 }# a) a$ Y5 @( ?' i" O {) i2 U* j& {/ I+ I# B. C SetEPRxValid(ENDP6);+ ]3 o. h2 c' A' b* P' j/ S4 | }& s6 m0 g, ~' N6 S. {/ R if(GetEPRxStatus(ENDP4) == EP_RX_NAK): R7 h- V" T7 L/ d% Q, V {3 n c- s9 }/ _1 n' e* G if(CDC_MAXSIZE - queue_size(&Qusart2Send) >= 64 )+ C% j0 { Z8 T SetEPRxValid(ENDP4);7 i. h3 a7 ?- _. X h5 r2 h# ^ }0 |2 h! F$ s$ a1 X! _/ E! p( J 5 @: Y* s1 p2 Q( d/ Y* N! N1 V8 h if(nrf_state == 0) [7 c7 W$ B0 {" V0 @. y" [ NRF24L01_TxPacket(buffer,1);! }! Q& n$ v' p: z7 V; Y* o ^% m } else { h4 p2 M, d- E0 f: p6 s V8 t$ _$ Q USART_Cmd(USART2, DISABLE); //失能串口 + {- [1 @; X' J0 z& F9 m) b' A4 v if(nrf_state == 0) {( r6 e% h- L6 T3 O- t if(dap2nrf_Data() == -1) { * n. `9 @$ a; K" i" l if(GetEPRxStatus(ENDP6) == EP_RX_NAK) { v f4 x" Y8 K5 o4 S! D# C SetEPRxValid(ENDP6); } if( linecoding_old.bitrate != linecoding.bitrate ||1 a2 S4 ~1 I( r2 X: w. Z linecoding_old.datatype != linecoding.datatype || linecoding_old.format != linecoding.format ||: h2 y' Y6 ?3 G6 m9 T) p linecoding_old.paritytype != linecoding.paritytype ) {: Z z2 s3 u1 z# `+ y6 `; Z buffer[0] = 33;//特殊串口设置指令% A$ {7 x$ T# w" S+ b, ?% I memcpy((void *)(buffer+1),(void *)&linecoding,sizeof(linecoding)); NRF24L01_TxPacket(buffer,sizeof(linecoding)+1); } else if(queue_size(&Qusart2Send) > 0)* t: g, b# I; c* z {6 t7 b9 I9 E* U# p2 X" Q QueueElementByte data_byte; for(i = 1; i < 32; i ++)1 y8 w/ v l, Y4 f" z& w { if(dequene(&Qusart2Send,&data_byte) == -1 ) break; buffer = data_byte.buffer;. |) l6 N0 c* Z9 R1 v" n! T }+ f4 y4 ? [6 T& B/ U* s( j buffer[0] = i - 1;8 U! @: {) \, S* T/ {! h NRF24L01_TxPacket(buffer,buffer[0]+1); }; p; q' E/ [5 ?- O( ^ else& g- ?0 t5 e$ N; f1 `3 ] {3 ?5 N% b# v8 s6 n' N( B* c if(GetEPRxStatus(ENDP4) == EP_RX_NAK) {4 f* G& o" Z& C8 { SetEPRxValid(ENDP4);5 U" Q- ^; n3 o# D }/ F, w# z- K9 W8 ` buffer[0] = 0;& S4 O4 A9 M5 p O5 l3 T NRF24L01_TxPacket(buffer,1); }+ d4 |# R! S$ j# b5 M7 O# w }3 U6 q! l+ S6 i1 I; P- i. x' F } }& E' I5 w/ z; |4 J( _ ``` 实物使用截图如下:8 O- Z; T: q4 T 6 N; Z/ x a! s4 F: t( h& }  ( V/ E9 `; n( ]& b3 P 在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。8 ]) O5 \ a' W ) r) \" H5 c$ X/ o 使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。 硬件设计的时候,设计注意事项: 使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。7 s2 n2 F. s+ E% s MP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。 PW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。 ( f- F) j: c, u) r4 z 同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。 / Z# K) {1 E8 q# x. B! e& I 在软件开发时候,有以下的注意事项: 抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。 & V- |( N0 t: R: W# J 功耗管理:在不需要通信时及时将NRF24L01置于待机模式或掉电模式以降低功耗。# t; w0 |! p# R8 { 距离与障碍物:无线通信距离受环境因素影响较大,障碍物会严重影响通信质量。在实际应用中要考虑通信距离和障碍物的影响并采取相应的措施。 NRF24L01的开发过程需要仔细规划硬件连接、合理配置软件参数、掌握调试技巧并关注实际应用中的注意事项。通过不断的实践和总结可以逐渐提高开发效率和应用效果。 : N. K# B2 a' G$ n 原理图见附件:  $ v. P+ V7 {& C5 g9 D |
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之继电器模块
微信公众号
手机版
重新上传一下 原理图!!!