你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

使用STM32F103制作的无线下载器

[复制链接]
〃聪聪哥哥 发布时间:2024-12-19 19:00
项目设计的前言:作为一个嵌入式的工程师,在编写代码时候,难免会遇到不同电平之间的转换。例如:RS485通讯方式,RS232,TTL信号,为了查看通讯之间数据的正确性,经常使用到不同的电平转换模块,还需要一个USB转串口工具,将数据上传到PC端,这样我们才能将查看控制器或者是负载返回的数据,为了避免调试代码起来方便,让自己的工作变得整洁,方便我们自己的工作,前端时间正好研究SPI通讯方式的NRF24L01这款无线芯片,利用业余时间做了一个无线通讯模块。在这里分享一下开发的经验。
3 X2 u2 Z, ~0 z* F2 _
! s. k5 G2 N1 u/ b一:部分原理图设计:- J# d1 w# p# ?2 @

. G# y; J( }, C. m4 J![12-1.png](data/attachment/forum/202412/19/183819haf0jpwfrbfjj9er.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-1.png"); z  j4 E" V* D6 }. s0 A" G/ O

+ h1 R: ~1 S9 X1 p; V" F" U3 a二:PCB图展示:
3 Y; e5 Q1 K& [% _0 T* n8 D
" a5 `* j9 u1 H! c![12-2.png](data/attachment/forum/202412/19/183852j26ztttwzci2cc1t.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-2.png"), A$ _+ ?& b  v! y6 E; V8 G0 u& k

3 K7 r6 m: b5 t9 `) S9 M三:软硬件设计的思路:; y' d  I- h4 s+ K( Z" `2 W9 N; t

9 c5 Y' S6 }* D" c8 z2 A5 v! m在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。
: q" y8 T$ e# ~! I; S1 q% d; q; }* s
无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。. C( I6 ?5 t; G$ g: K! v

: c. V) g8 @3 w, j8 @9 S5 N2 K$ y, P软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。
  R' y: ^4 h+ V4 f- R+ D; N. W. m/ N. Z0 k9 V8 H
使用串口2完成与SPI之间的交互,
8 {+ K8 I3 g% M0 r8 f
3 O1 P. J! T& h; q% T软件配置参数:使用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

* b6 c4 `" G( ]* s  v![12-4.png](data/attachment/forum/202412/19/184938vzhuojy923nhu3lj.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-4.png")
4 T# h. B0 J; ~- T' D- a# [2 g$ G6 O! I( R
部分软件代码:
- _+ g# C0 u3 I# E' w; A& v; [9 d0 m6 Y3 H7 H3 T0 m8 C
```abc  i% h* C: j4 @+ ]& `* g# s" N
                if(sd == 0)
8 W9 S! C- ]4 _. m                {
7 M4 u# q# y: v/ c* I6 u" j7 l                        USART_Cmd(USART2, ENABLE);                    //使能串口
( |6 `# t! I0 Q                        if(        linecoding_old.bitrate != linecoding.bitrate ||
/ [. E6 V* N3 H) s5 S% I2 e8 L/ B                                        linecoding_old.datatype != linecoding.datatype ||8 E3 z" q! f: w. }4 W. e
                                        linecoding_old.format != linecoding.format ||
1 u0 p3 m: P% ?                                        linecoding_old.paritytype != linecoding.paritytype )
& u, n8 A* K# d$ z* C; h/ V  j                        {
9 f: ~* O8 n; R# i; h                                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;
& x$ L$ s3 H+ |  u+ u+ B                                if(dequene(&Qusart2Send,&data_byte) == 0 )
2 ?# l( P) h! h6 `2 x                                {0 r( b2 g! ?& O2 @
                                        USART_SendData(USART2,data_byte.buffer);
2 i) G, ~- S' \" W  r: b/ w6 G                                }+ e8 P6 J9 F4 |9 r
                                USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断8 W* I$ y( U2 J! a) h! Y
                        }
' T" y; o6 K8 D3 Y& U              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);
* u& \: e0 }9 [                        }
# f0 w/ `* ]$ M6 K1 P3 G                        if(GetEPRxStatus(ENDP4) == EP_RX_NAK)
0 o5 ?0 f6 P' Q5 d0 \. q& z2 [                        {" W& P7 W5 d5 r) `0 W
                                if(CDC_MAXSIZE - queue_size(&Qusart2Send) >= 64 )9 d8 |: c* }, ^; u4 [6 y, L
                                        SetEPRxValid(ENDP4);
1 k* G# e+ R+ p; `. Q. v                        }
0 b3 ?" o. X+ g' B& b' N& m9 P, h/ {7 g3 h, n# Y4 R3 @
                        if(nrf_state == 0)
+ Q% q4 Q  }# O. L1 n9 \" J                                NRF24L01_TxPacket(buffer,1);
; O. D) j3 _, k5 o, P, @) U! R/ I                }
; |' V+ W4 e# _% {' s                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
                                {
/ J, l1 |; G, }2 H                              
( e; a* T0 Y7 @- i: {                                        if(GetEPRxStatus(ENDP6) == EP_RX_NAK)" Z0 N9 [, r- j( M; E' M# g1 l# T
                                        {
+ [5 {" O4 L5 V' m; D* }                                                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 ||
: z4 |/ \1 ~6 a; y! v( F* _) I                                        linecoding_old.datatype != linecoding.datatype ||
. o  m' X: w2 i# b9 r6 X                                        linecoding_old.format != linecoding.format ||
* J9 q5 w5 i6 U4 K                                        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));
; l3 u7 D9 m' a- ]1 ?5 y  V                                                NRF24L01_TxPacket(buffer,sizeof(linecoding)+1);
4 d1 e. _9 n5 S1 K# K                                        }* 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;
- n0 K/ f0 R# [                                                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 )
  d) h  m# _( W# J4 _. s                                                                break;- h" c5 C2 V& {) V0 J
                                                        buffer = data_byte.buffer;' g1 `$ q% E3 U
                                                }
5 `5 ?  ^4 [: B# q                                                buffer[0] = i - 1;
& ^( l) z9 d- X                                                NRF24L01_TxPacket(buffer,buffer[0]+1);% ]' U* ?8 ]5 S/ A
                                        }
4 D3 Z6 Q4 l6 Z                                        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;
. k6 P: r0 m7 ~$ ]( a( Y                                                NRF24L01_TxPacket(buffer,1);
8 x1 U7 _" u$ Q                                        }6 |5 C3 U' b0 w; c& L% V9 Q5 a
                              
& |# J+ d2 D9 A6 W0 z" ~& Z, h                                }! R# u! X* W+ f) O
                        }* N$ e, g/ m2 Z& f, Q3 y2 _
                }
( Z! S5 d0 D, U. r" K& @" Z3 A```
+ \+ }) R6 _- l9 a; x8 L3 x" I" {
; M4 v' p7 T9 y2 h6 B& G6 [/ I实物使用截图如下:8 u% {3 w: U6 d! z
2 f/ X2 r+ q3 @0 @. A
![12-6.png](data/attachment/forum/202412/19/185713mjuwqnqnzbnnqznz.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-6.png")
! V# U9 K8 \+ T* E0 i( U/ [2 W- ]' _$ k9 ^) R
在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。
, x; N0 D/ {: s" C" n' m2 J9 V5 F+ _* f; _% v5 c9 B
使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。
+ \& T  L1 ?7 O) C5 X. [3 D
8 v1 ^$ p' s$ q( y, ^/ k1 P硬件设计的时候,设计注意事项:
7 e% \4 D- l5 N  m( h+ c! r- `1 }  R3 j! s
使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。
9 M  n+ F  q0 r) T* I2 I% x8 [: T1 j; A- R- Q2 s* L" X. ?
MP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。
+ H7 g; W, a5 X8 K+ V/ \( P) R) K8 `4 D& i5 N: H+ d
PW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。
# E# I$ j& D% g( P
- k7 v% e4 B+ O8 n7 C同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。
# k4 q4 r5 \! I: }' |3 M; b; M; w- i0 i2 F( H# w1 l6 k: Q3 R3 `
在软件开发时候,有以下的注意事项:0 g, h0 b" q9 d) G: G+ O7 ]

2 a6 l  H% Z2 }5 R) N抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。
4 u$ H1 N; G$ y( V/ ?+ ?: J7 p
6 q( h& D+ M. b3 q) d! }# R功耗管理:在不需要通信时及时将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

7 e, C6 q( H& ~原理图见附件:: r( ^$ {$ y  \; R+ x
; i$ E: ]$ D% C) V+ {! ?, j5 r- E
![PDF.pdf](data/attachment/forum/?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "PDF.pdf")
* m4 j. [5 T: Y$ z5 t

2 p7 T( H; J9 c  B
12-1.png
12-4.png
1.jpg
1.jpg
收藏 评论1 发布时间:2024-12-19 19:00

举报

1个回答
〃聪聪哥哥 回答时间:2024-12-25 16:51:39

# v4 D) i8 n1 ^, f; Q0 |重新上传一下 原理图!!!
; y: @1 Y" l( k" j: B: J1 J( o 无线下载器原理图.pdf (1.56 MB, 下载次数: 2)

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版