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

使用STM32F103制作的无线下载器

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

/ ?% u& }  q1 b( h  a9 G" x一:部分原理图设计:
% i0 h& y9 v! Q8 h1 ?9 Z1 Z4 v. ~/ B$ j
![12-1.png](data/attachment/forum/202412/19/183819haf0jpwfrbfjj9er.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-1.png")
; x7 l; ?4 E- S- d& \! G
- C; J  K! s. e3 [二:PCB图展示:
4 l# e( n. ~1 i9 \1 i' R  e9 |3 n2 N
![12-2.png](data/attachment/forum/202412/19/183852j26ztttwzci2cc1t.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-2.png"): A6 L& x& z. g) D2 A; e
" }; t& K3 T) i6 {3 b4 D
三:软硬件设计的思路:" W9 u+ W) E3 P
' t/ H- u6 x! C& t2 h2 `
在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。
: c# D/ M; w$ }8 d& F$ g2 d" e6 j1 D2 z3 P, Q7 B1 H2 s" J
无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。9 I* G% Y* Z% K0 n
: Q9 |  ~7 V+ a# O9 t1 n( n/ R3 M
软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。8 f; g% G8 g# F; @
4 \# ?  w  b% \$ H: K
使用串口2完成与SPI之间的交互,7 }4 W5 t0 U% H" r; q0 C
: {2 q6 }, C  U1 G! v4 C/ M# U3 p
软件配置参数:使用STM32cube MX软件生成USB,SPI,串口底层的驱动部分,这样开发起来也比较容易;4 ?- X9 n/ q0 i7 B- y, a

) i2 W/ B/ y$ A9 n: ]5 y6 Vcube软件配置图如下,主要是对该项目中使用到的引脚进行配置
' a0 `  Y9 v% K/ l) ~2 J$ Q. V4 ^* C5 `  C
![12-4.png](data/attachment/forum/202412/19/184938vzhuojy923nhu3lj.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-4.png")( J4 n! E0 i" i: Y3 p  H

+ X: {. j& ~$ y% u4 V+ H! K# S3 G部分软件代码:
1 ?6 w4 |" f( Q. g% `' t* L) m; q4 O2 L1 h  f- H* n
```abc: v5 |) ~9 n8 h( ?# E7 k7 m
                if(sd == 0)! M9 z: f* e" I  a* j1 `: h; f5 K
                {
  P0 P" I* J" q9 K. X. N/ \                        USART_Cmd(USART2, ENABLE);                    //使能串口
5 E7 p/ ^2 H( D: }% J( j+ u4 k                        if(        linecoding_old.bitrate != linecoding.bitrate ||5 z% N/ U0 M6 v- T* m: @/ d) P
                                        linecoding_old.datatype != linecoding.datatype ||0 X$ e8 d9 H# W: T5 D
                                        linecoding_old.format != linecoding.format ||8 |8 H; o8 I" H( c# l/ [
                                        linecoding_old.paritytype != linecoding.paritytype )
  P& b6 s+ F0 A$ m, s( i                        {+ ^1 M- @* o$ E& T- w  K
                                if(        usart2_flag == 0 )) H5 Z8 ?8 x. {. j0 b
                                {$ L0 [; Y2 b2 X
                                        uart2_config_change(linecoding);
/ v$ M2 C& H5 Q) I; o                                        memcpy((void *)(&linecoding_old),(void *)&linecoding,sizeof(linecoding));
5 W' ^. S) `/ Q                                }
3 G2 x  P* N1 Y4 d0 V" S0 x5 `                        }" h: q, ~+ R: K
                        else if(queue_size(&Qusart2Send) > 0 && usart2_flag == 0)
$ C2 t+ F" C( D2 r; M                        {6 @( o, {& s; V+ Z# m
                                QueueElementByte data_byte;, A0 @  d$ {' @: i
                                usart2_flag = 1;
6 n5 C: W: D5 n% ?) ^- ?6 y                                if(dequene(&Qusart2Send,&data_byte) == 0 )
# u$ I$ f* `1 k3 |0 |% L, |                                {  l- }( x1 `' K
                                        USART_SendData(USART2,data_byte.buffer);- E3 K9 ^0 g& H) n
                                }1 c$ {3 y0 D3 f! y
                                USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断! V1 ]9 _0 j7 T6 W1 _
                        }
3 Z" G3 K& ~9 t              & m5 o, z' S7 R$ R, l
                        if(GetEPRxStatus(ENDP6) == EP_RX_NAK)" a! ^/ c+ w9 g
                        {- g  m. y6 b( J2 D
                                SetEPRxValid(ENDP6);6 }# T2 f8 W  w# h. u/ f
                        }
: ~& c! a2 M8 G! s. m+ ~. a  c                        if(GetEPRxStatus(ENDP4) == EP_RX_NAK)
3 h1 f/ s2 Y# |- a9 U1 B                        {) L% Q" r. c& k
                                if(CDC_MAXSIZE - queue_size(&Qusart2Send) >= 64 )
' A: W% j( g* T  @                                        SetEPRxValid(ENDP4);
% q1 I' V: {8 w2 H$ _) i1 [                        }
& k& L- {" T# ], _! {- ?  N  r! B# |3 K' L' \4 `- R# T* ]& G
                        if(nrf_state == 0)/ Q0 A9 j% n* P$ n9 i; `1 n
                                NRF24L01_TxPacket(buffer,1);
" t9 a, I; j8 D1 f+ i& T                }+ y. j* r* z% o
                else
: u1 a, I4 Z; r/ [# J                {
1 ?' y+ b$ q& f  ]                        USART_Cmd(USART2, DISABLE);                    //失能串口
/ ^" t2 S$ f% P9 k                        if(nrf_state == 0)1 c  z0 o+ k3 ^! y' ]
                        {8 w5 C( I" y3 f; V& L
                                if(dap2nrf_Data() == -1)
" K- N6 K3 u6 w, ]                                {1 t8 x7 |  F3 {1 U
                              * m6 ?& R* w! ^
                                        if(GetEPRxStatus(ENDP6) == EP_RX_NAK)
9 A2 ^& L& R4 \9 p/ F7 B                                        {8 M7 n* V- {3 Z$ i3 c8 s( X+ S
                                                SetEPRxValid(ENDP6);
/ p* q; h0 Z1 {+ N' E                                        }: G+ s9 |' i/ @0 |& {9 U, A1 n
                              
2 _/ ~9 M8 g: [$ ^, M                                        if(        linecoding_old.bitrate != linecoding.bitrate ||3 }0 p7 ~8 B0 u
                                        linecoding_old.datatype != linecoding.datatype ||
2 \, V% i! g; O, j( P; ]  J! {                                        linecoding_old.format != linecoding.format ||
/ V: a% f$ w' K                                        linecoding_old.paritytype != linecoding.paritytype        )
7 u' k3 y& k* M) `4 w9 j- q# Y% a8 U                                        {' _' ]# m8 U# j9 ~/ r
                                                buffer[0] = 33;//特殊串口设置指令
8 r2 N2 r% _! ?* m5 v. T                                                memcpy((void *)(buffer+1),(void *)&linecoding,sizeof(linecoding));
8 |# k9 T3 ?& t6 u4 a* a3 l                                                NRF24L01_TxPacket(buffer,sizeof(linecoding)+1);
8 I9 G, U, r( b" z/ H7 m                                        }: [  c1 \" f$ ]2 _
                                        else if(queue_size(&Qusart2Send) > 0)# l2 ]! N1 K' L
                                        {
" ~/ h2 |2 N# p5 B/ G8 T" u                                                QueueElementByte data_byte;: h, K3 S& Z: p) T
                                                for(i = 1; i < 32; i ++)" p  J& ], m* U5 L/ A& d
                                                {
+ z, x2 w  D; l; N4 X) t+ }0 G6 I/ k                                                        if(dequene(&Qusart2Send,&data_byte) == -1 )% y+ A3 u# c0 `7 _; q3 R
                                                                break;9 v# l* ?& n6 L& Y6 g- O/ G
                                                        buffer = data_byte.buffer;
& o4 t- v2 u# u( O7 `                                                }  x& [& K! e; X$ E% k
                                                buffer[0] = i - 1;( k- P; `9 a7 \  @
                                                NRF24L01_TxPacket(buffer,buffer[0]+1);) v  I* s: `1 X, f
                                        }
$ E2 d" R0 \4 E- `  V" m                                        else& H5 X5 G+ z# b/ p
                                        {
6 l' C& x) n6 |/ ]5 f* d" m                                                if(GetEPRxStatus(ENDP4) == EP_RX_NAK)7 H. u4 i- c* @/ K+ H0 [4 B, r# u
                                                {$ {( T2 p. C4 l5 s1 h
                                                        SetEPRxValid(ENDP4);
5 Y. o+ N3 n5 i- p$ R2 ]( h                                                }) V! W/ Y9 y4 L8 u! p
                                                buffer[0] = 0;% x9 i5 Y3 ]9 J; i
                                                NRF24L01_TxPacket(buffer,1);* \' m4 P3 U5 h2 j# q) z
                                        }4 g- f/ J, w# m( _' \6 F* z2 h; E  M
                              
) v/ H; {, z. s# Q                                }4 a) [, K' e% i( S0 Z
                        }
. q% O/ w- H4 m, |& H                }
9 _6 C  h  Y. a, U: j& ]/ f```* F! P2 R4 [+ X  I/ H8 |! x# h, I

/ e, k3 @  f, k& y+ f$ Z0 l实物使用截图如下:( J, n6 x7 Z! s2 H, E/ H
6 z% A! n3 O  k8 F
![12-6.png](data/attachment/forum/202412/19/185713mjuwqnqnzbnnqznz.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-6.png")
9 I5 K+ }) L$ i* ~9 L6 `
, q: v; P, L5 T# s  X在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。
2 `3 s, `/ O5 g' T/ h
2 b9 K1 ~! k' k+ `使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。5 u: U; E( R9 W
' _4 [8 ?' C/ ~% u6 z
硬件设计的时候,设计注意事项:
2 l( V: o- [6 [  f/ n% ]8 w6 G" A( Y8 F! M/ \
使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。4 E# ~2 d$ U8 g. k3 j& o6 M, I
8 U% F1 @) y* {* f2 |, {% h, c# ?
MP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。* }6 ]* D( k, x6 F) Q6 O

  \: c7 c3 M- M6 H+ gPW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。: e# k1 X/ N7 _' w

) d, G6 f# G3 h2 W0 `$ M8 y+ @" c$ X同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。4 R8 V4 w! ?( r
+ e6 [. l! }9 H0 M+ s5 h1 e
在软件开发时候,有以下的注意事项:
% i7 l3 Y4 [* P, t2 S, P
7 d3 r2 K; [) c5 z抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。
0 R- B; _+ X( d" ~# {$ Y9 T3 \: R' v6 r" ^9 K
功耗管理:在不需要通信时及时将NRF24L01置于待机模式或掉电模式以降低功耗。
, ?6 c5 ^2 m! U$ R
+ N7 B5 P! `4 U( H/ n1 I距离与障碍物:无线通信距离受环境因素影响较大,障碍物会严重影响通信质量。在实际应用中要考虑通信距离和障碍物的影响并采取相应的措施。$ B. v. P+ t& @' m) j6 a, ]7 j. W
, `# N* j2 j$ J
NRF24L01的开发过程需要仔细规划硬件连接、合理配置软件参数、掌握调试技巧并关注实际应用中的注意事项。通过不断的实践和总结可以逐渐提高开发效率和应用效果。3 j8 c# ]# ~% Q% U5 t' g- @8 m$ @
1 h1 x) o, s, W* S# W. E& l% g
原理图见附件:
3 m' s" i: M' L8 Q: e7 }) q& J
. T2 {% j- Q$ h! h. W" u" |![PDF.pdf](data/attachment/forum/?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "PDF.pdf")5 A: K: A- c* j$ |( J& B

, _5 Z7 w" x. D" {6 v) Z, e
12-1.png
12-4.png
1.jpg
1.jpg
收藏 评论1 发布时间:2024-12-19 19:00

举报

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

0 ]" j$ G$ _& s4 g* g4 Z% x重新上传一下 原理图!!!
& k8 e1 y5 \5 }1 l" M 无线下载器原理图.pdf (1.56 MB, 下载次数: 2)

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版