|
项目设计的前言:作为一个嵌入式的工程师,在编写代码时候,难免会遇到不同电平之间的转换。例如:RS485通讯方式,RS232,TTL信号,为了查看通讯之间数据的正确性,经常使用到不同的电平转换模块,还需要一个USB转串口工具,将数据上传到PC端,这样我们才能将查看控制器或者是负载返回的数据,为了避免调试代码起来方便,让自己的工作变得整洁,方便我们自己的工作,前端时间正好研究SPI通讯方式的NRF24L01这款无线芯片,利用业余时间做了一个无线通讯模块。在这里分享一下开发的经验。5 z( ]( P! f4 p 一:部分原理图设计: , V. G9 {- G. E: }0 ~4 r* z $ j5 Q! T) X; _$ c+ p 二:PCB图展示:( c/ }: C N8 ~+ y0 C; @- h6 F# T% Y' g ! V* E, N9 p+ m9 f7 v4 p- A  三:软硬件设计的思路: 在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。 无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。! @2 c( j2 P& J# E+ S 软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。 * C& p7 t# V/ u0 B 使用串口2完成与SPI之间的交互, 6 u+ e$ l% o+ _' ~ 软件配置参数:使用STM32cube MX软件生成USB,SPI,串口底层的驱动部分,这样开发起来也比较容易; ; i0 _ A& F' t5 C1 e M# q7 s cube软件配置图如下,主要是对该项目中使用到的引脚进行配置5 W& r! ^6 x# |0 Z! O3 P7 T ' L8 i; {$ w+ U P) Q+ N A/ ~ 8 w/ K1 ~8 b% F/ C( G 部分软件代码: H( t9 n. _( N& }0 n ! D1 r9 o9 p: I1 K! Q ```abc, F( x: h, Q8 g. { if(sd == 0) { USART_Cmd(USART2, ENABLE); //使能串口 if( linecoding_old.bitrate != linecoding.bitrate || linecoding_old.datatype != linecoding.datatype || linecoding_old.format != linecoding.format || linecoding_old.paritytype != linecoding.paritytype ) {; G1 F; U: f$ M if( usart2_flag == 0 ) w; c: n2 x3 N {) H0 y) V! t ~1 a$ S uart2_config_change(linecoding);4 p. J: a/ p$ z! o# G$ T. d memcpy((void *)(&linecoding_old),(void *)&linecoding,sizeof(linecoding)); } }! h1 E6 t8 S# }2 s- t9 p else if(queue_size(&Qusart2Send) > 0 && usart2_flag == 0) {( i& C% L# e* Y% j! K" o* g; J QueueElementByte data_byte;" g$ _1 j/ p$ `' t7 ?+ T usart2_flag = 1; if(dequene(&Qusart2Send,&data_byte) == 0 ). a! y& X, ]* v3 y) D8 f! P: Y {! n& ]8 V; C) Q" X- l USART_SendData(USART2,data_byte.buffer);) j" y# s$ ^: R+ q1 Z } USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断 }" T7 G- h9 h: W8 z a9 E1 w' H% C8 }0 i5 O; V- ? if(GetEPRxStatus(ENDP6) == EP_RX_NAK) {- X# ^; X* x9 B4 @3 ]( ^ g SetEPRxValid(ENDP6); }/ V, j( P9 ^' r7 I. ^ R* B7 g if(GetEPRxStatus(ENDP4) == EP_RX_NAK)6 T& K; Q* q- \2 _- b {. o3 t% M# m6 ^4 |6 Y if(CDC_MAXSIZE - queue_size(&Qusart2Send) >= 64 ) SetEPRxValid(ENDP4);0 t" C3 P' B7 N O2 f } 7 [0 U' [% U) T4 P, I if(nrf_state == 0)) x6 V+ j" ?: `0 y$ ^ NRF24L01_TxPacket(buffer,1); } else7 z, y/ Y, u' R; r+ Q. _' V6 P0 a- o4 w {" t. Y B, v: U/ f6 u9 \ USART_Cmd(USART2, DISABLE); //失能串口 ' p$ x/ {8 k. g e8 Z* S( ^9 a9 V if(nrf_state == 0)9 T1 b( `$ \2 u& [! D1 {2 ]. t { if(dap2nrf_Data() == -1)2 }$ R/ Z6 q" c, e2 c1 q { m3 B* b# V2 \/ x 3 p2 Q X) @1 s$ L+ ~3 t if(GetEPRxStatus(ENDP6) == EP_RX_NAK) { SetEPRxValid(ENDP6);* D. v2 y" A! b } if( linecoding_old.bitrate != linecoding.bitrate ||# x. `$ i s: H$ `' E linecoding_old.datatype != linecoding.datatype ||; ? Z* N; I3 O+ A" F linecoding_old.format != linecoding.format || linecoding_old.paritytype != linecoding.paritytype )5 R4 `9 E; B$ p" H3 H { buffer[0] = 33;//特殊串口设置指令) C+ f, K; r0 T2 c" h6 j1 O memcpy((void *)(buffer+1),(void *)&linecoding,sizeof(linecoding));" E8 Y! c+ U. r t, _ NRF24L01_TxPacket(buffer,sizeof(linecoding)+1);- Q3 m$ M* @8 E6 l b/ [. x } else if(queue_size(&Qusart2Send) > 0) { QueueElementByte data_byte;# i7 W3 p/ a& Z; _/ q: a for(i = 1; i < 32; i ++) {+ g2 }4 N7 Z6 W5 N if(dequene(&Qusart2Send,&data_byte) == -1 ) break;* d- {! {7 F7 ~1 p1 N9 H6 i, N% g buffer = data_byte.buffer;$ p W6 @1 q. j" ^ } buffer[0] = i - 1;+ q: W7 l% e" i8 E+ {. i1 ^ NRF24L01_TxPacket(buffer,buffer[0]+1); } else/ F8 l/ |3 d( F6 F- `) f. T6 L3 | {0 G+ l8 |9 L! S1 |& K0 |- _ if(GetEPRxStatus(ENDP4) == EP_RX_NAK)9 {1 O- r; O; Y; E% t {3 D7 p. E" Z/ | SetEPRxValid(ENDP4);7 H8 R. @ b* \$ Q }" a: M z7 h' M% a, m, G2 l( y buffer[0] = 0;7 `6 E$ x- T3 t# A+ O+ p4 N NRF24L01_TxPacket(buffer,1);8 ~, M8 D r! F4 y }, E' |& f$ f* L( ^! ^ }8 {& @7 m+ \, F2 W1 H) O }2 j+ d2 z1 G' F. H } ```" {' D8 j: x" b3 M, G/ p4 R' R# ? : Y7 K/ {! u0 Z9 C. A$ }0 }& G 实物使用截图如下:" Q1 r; ?. B |% P X# J( i 2 _ a) z" j/ p8 u3 e. f" N4 O 在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。 1 r1 l: b4 M2 D- l: `9 i6 n 使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。5 c8 R6 ^2 q+ X2 K ) C# V0 Z2 f' }3 O" d2 w 硬件设计的时候,设计注意事项:9 f' }2 ?6 ]( N6 @ \% n 使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。 MP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。 PW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。 6 [. `* S1 y1 n( l! I. V; F' ?- U9 g 同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。& F5 ~+ u) V2 `8 C! F 在软件开发时候,有以下的注意事项: 抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。 功耗管理:在不需要通信时及时将NRF24L01置于待机模式或掉电模式以降低功耗。 9 V ^2 I W& ? 距离与障碍物:无线通信距离受环境因素影响较大,障碍物会严重影响通信质量。在实际应用中要考虑通信距离和障碍物的影响并采取相应的措施。; r. N- a. p; ]2 `0 a @ NRF24L01的开发过程需要仔细规划硬件连接、合理配置软件参数、掌握调试技巧并关注实际应用中的注意事项。通过不断的实践和总结可以逐渐提高开发效率和应用效果。) k2 F5 b. m9 @' u 1 }' Y$ ~9 g/ ~& f$ K+ ? 原理图见附件: ' o6 ~+ [& r; f2 I: s7 Q6 c# G) c  - L! V/ R9 v+ \0 F7 Q$ @ |
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之继电器模块
微信公众号
手机版
重新上传一下 原理图!!!