|
项目设计的前言:作为一个嵌入式的工程师,在编写代码时候,难免会遇到不同电平之间的转换。例如:RS485通讯方式,RS232,TTL信号,为了查看通讯之间数据的正确性,经常使用到不同的电平转换模块,还需要一个USB转串口工具,将数据上传到PC端,这样我们才能将查看控制器或者是负载返回的数据,为了避免调试代码起来方便,让自己的工作变得整洁,方便我们自己的工作,前端时间正好研究SPI通讯方式的NRF24L01这款无线芯片,利用业余时间做了一个无线通讯模块。在这里分享一下开发的经验。 一:部分原理图设计:: z' Q; }8 B8 s) A 4 U; h, J; v2 b# y; Z* ]2 H & f y' v* k* s; o 二:PCB图展示:) l9 m$ m/ b' |- N 4 O8 f; P' R0 B1 S  三:软硬件设计的思路:; \0 ~5 F. X8 Q* w F 在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。 " p% v: V& s' b9 U! j+ r1 v 无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。, B3 A0 p7 N6 s4 z r' a' r& W% R" c 软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。 使用串口2完成与SPI之间的交互, . u- K& `$ a! v/ x C 软件配置参数:使用STM32cube MX软件生成USB,SPI,串口底层的驱动部分,这样开发起来也比较容易; cube软件配置图如下,主要是对该项目中使用到的引脚进行配置 : s: R/ J% l) @5 ?0 c- P5 O2 g! }2 ^ ! R3 N0 @( |) o0 j3 L" B 部分软件代码: : d- M5 S. n6 m; g; B$ N, c9 I ```abc if(sd == 0) {7 P) G) W# q' P; P/ l! M USART_Cmd(USART2, ENABLE); //使能串口 8 |& X. `# o+ c' F; Z' `8 a& H1 k if( linecoding_old.bitrate != linecoding.bitrate ||+ w# I. z0 Z( Q" q linecoding_old.datatype != linecoding.datatype || linecoding_old.format != linecoding.format ||, R1 p9 r; M, S* {! o! { linecoding_old.paritytype != linecoding.paritytype )/ y3 ] S0 l8 F8 O4 b9 w9 W( I { if( usart2_flag == 0 ) { uart2_config_change(linecoding); memcpy((void *)(&linecoding_old),(void *)&linecoding,sizeof(linecoding));; N M: X0 Q4 Y" v& T7 ?! i2 B } } else if(queue_size(&Qusart2Send) > 0 && usart2_flag == 0)8 s& w1 o0 V1 ` a9 S' _& v% \; ? { QueueElementByte data_byte; usart2_flag = 1;. B" @7 y# G, B6 f7 {8 b9 k if(dequene(&Qusart2Send,&data_byte) == 0 ) {5 U) H$ S/ R$ N# h8 Y# a USART_SendData(USART2,data_byte.buffer); }* z! L1 @" G. \# N& ^ USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断 }! Z( a( V" F! A/ D6 m4 k' T if(GetEPRxStatus(ENDP6) == EP_RX_NAK) {# t3 d, I. ?2 N1 l9 q' Q+ P8 _$ ? SetEPRxValid(ENDP6);+ ~3 m) q" G- Z* X& i }/ U$ x! l* u* G }4 q, f [+ s% q if(GetEPRxStatus(ENDP4) == EP_RX_NAK) {- A, G3 k) s: c, j3 b% A" F if(CDC_MAXSIZE - queue_size(&Qusart2Send) >= 64 ) SetEPRxValid(ENDP4); } 4 s7 c5 X! B! i# X: U3 [1 l" | if(nrf_state == 0) NRF24L01_TxPacket(buffer,1);: w' r# D7 {+ ?4 K' ^& g }6 Q7 g8 e# ~% E: V else {3 V4 A# `# Q# T7 s2 X% l' F. [; q! E USART_Cmd(USART2, DISABLE); //失能串口 if(nrf_state == 0) {+ j7 d) v" G6 \2 A) s+ ?8 K2 F if(dap2nrf_Data() == -1) {, n Q, L/ y5 @5 o s7 V/ O4 }3 y if(GetEPRxStatus(ENDP6) == EP_RX_NAK) { SetEPRxValid(ENDP6); R* M7 G/ V5 W* w9 \ | }# l j. I2 |3 Y$ \6 ? 5 |5 Y# Y" t2 c0 Y, M: t! d8 Y if( linecoding_old.bitrate != linecoding.bitrate ||" o1 a; J( \5 K* m+ f9 k linecoding_old.datatype != linecoding.datatype || linecoding_old.format != linecoding.format || linecoding_old.paritytype != linecoding.paritytype )& g, M* e! d# V { buffer[0] = 33;//特殊串口设置指令 memcpy((void *)(buffer+1),(void *)&linecoding,sizeof(linecoding)); NRF24L01_TxPacket(buffer,sizeof(linecoding)+1);+ ^5 Q! o) S9 Q1 ]3 E+ w: B }/ N! ^' P C8 X else if(queue_size(&Qusart2Send) > 0). |* @% h5 g* a6 W( G {; K; J' c/ P s; e9 g( d( T- v& A, B QueueElementByte data_byte;5 E4 f, T! r. H6 o) D for(i = 1; i < 32; i ++)# g+ s7 [. w: j9 W$ b/ ~; e6 { {- d5 {6 i. q4 b- `" N# O if(dequene(&Qusart2Send,&data_byte) == -1 )' U& a. W3 ~) ~' x+ B break;0 t4 r: `5 d$ V. X6 s1 p buffer = data_byte.buffer; q$ b2 _3 e% \ j9 I: ^& _( M } buffer[0] = i - 1;1 F8 l, O4 J& q- S NRF24L01_TxPacket(buffer,buffer[0]+1); J0 R9 f2 d) z3 R- o/ D3 k } else { if(GetEPRxStatus(ENDP4) == EP_RX_NAK); ?1 ^! E( ~% M2 Y {2 |$ y# C) ^' f; h- ]& ` SetEPRxValid(ENDP4); } buffer[0] = 0;1 e4 [* @! s' G. i! ^ NRF24L01_TxPacket(buffer,1); }( F- b( Y$ o+ i! S }' D# t' K6 y/ P1 a, U) } }7 }# W6 i1 q. A } ``` ! ^/ q5 ]5 Z% q 实物使用截图如下: 4 h1 G$ |" X! Z4 K+ X9 b! I 在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。 - `2 n, ^& B# L1 O9 V0 d 使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。+ n$ r% B" `4 v; Q' d5 y7 d- k" C3 B 硬件设计的时候,设计注意事项: 使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。 B4 F7 r4 K1 o' [5 Y3 ` MP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。 7 k$ k. |# y0 O% Z; J% p PW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。& I- K+ [) P" K# S 同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。& d- D5 R! Z9 ` 在软件开发时候,有以下的注意事项: 抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。 / c0 r% N+ R- B* c 功耗管理:在不需要通信时及时将NRF24L01置于待机模式或掉电模式以降低功耗。/ f$ y( N8 e$ f. O: \ ! x. [# a' }! p6 @1 }; q 距离与障碍物:无线通信距离受环境因素影响较大,障碍物会严重影响通信质量。在实际应用中要考虑通信距离和障碍物的影响并采取相应的措施。 NRF24L01的开发过程需要仔细规划硬件连接、合理配置软件参数、掌握调试技巧并关注实际应用中的注意事项。通过不断的实践和总结可以逐渐提高开发效率和应用效果。 2 W v3 s* Z8 t4 k& Z- f8 Q3 m+ ?4 g 原理图见附件: x8 M s4 ^% J ' H. M6 \$ N6 J* b  # Q, T) D }3 G0 [8 E) o- B |
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之继电器模块
微信公众号
手机版
重新上传一下 原理图!!!