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

使用STM32F103制作的无线下载器

[复制链接]
〃聪聪哥哥 发布时间:2024-12-19 19:00
项目设计的前言:作为一个嵌入式的工程师,在编写代码时候,难免会遇到不同电平之间的转换。例如:RS485通讯方式,RS232,TTL信号,为了查看通讯之间数据的正确性,经常使用到不同的电平转换模块,还需要一个USB转串口工具,将数据上传到PC端,这样我们才能将查看控制器或者是负载返回的数据,为了避免调试代码起来方便,让自己的工作变得整洁,方便我们自己的工作,前端时间正好研究SPI通讯方式的NRF24L01这款无线芯片,利用业余时间做了一个无线通讯模块。在这里分享一下开发的经验。5 H/ g+ N  d& X3 k0 @, z' K
& j$ q. B+ x5 Y* v( Y/ L
一:部分原理图设计:
5 ~  R- k9 |. z0 G) ^& j; G! @& K& D3 N
![12-1.png](data/attachment/forum/202412/19/183819haf0jpwfrbfjj9er.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-1.png")7 _  y9 Y/ |" ?5 n- b9 c; }/ M

3 @' m1 D0 ~+ r' _二:PCB图展示:$ \& X1 ]$ i3 w: r0 m1 f; i; g
& a7 B0 V6 q1 d8 J: J
![12-2.png](data/attachment/forum/202412/19/183852j26ztttwzci2cc1t.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-2.png")
6 W- k. R& k% j& h. i% J7 \$ o
' t/ L: P6 Z4 ?2 O6 c三:软硬件设计的思路:
3 z0 @6 H" I5 [/ V1 t0 }5 m& i9 k4 W1 M; L4 f( y0 O0 q- \+ w
在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。
" l" r1 `! s9 Z1 d5 C. @  J1 s6 J4 A( Q$ ]( K7 f: p; }# ^. {+ J
无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。
( Z8 L9 e; N9 E
" ]2 o: `. G0 Q软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。
! z2 X5 k0 {4 }. O& Z! y# R2 {" u
使用串口2完成与SPI之间的交互,
- Z, d' X) t# }3 T0 H: S
+ P" F7 U; i( p7 v软件配置参数:使用STM32cube MX软件生成USB,SPI,串口底层的驱动部分,这样开发起来也比较容易;9 E8 A! ]; j. @) L6 P+ h/ x
1 _- z" c! {2 e( r( }$ C
cube软件配置图如下,主要是对该项目中使用到的引脚进行配置
$ s! B; S5 j; `5 v- a( |1 P6 L7 y2 {. L$ v
![12-4.png](data/attachment/forum/202412/19/184938vzhuojy923nhu3lj.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-4.png")# C$ g/ G( x+ }0 d

) q/ \  F7 i  s" u' Z/ u5 K部分软件代码:
7 Q( X& ?6 Q# \
; n7 i- J$ X( T8 P```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);                    //使能串口
; d5 e0 q* K/ e# E3 ~& F                        if(        linecoding_old.bitrate != linecoding.bitrate ||" m; Z9 P2 c* G0 {
                                        linecoding_old.datatype != linecoding.datatype ||
7 N8 c7 v/ P! {: Q/ m6 w* \                                        linecoding_old.format != linecoding.format ||
6 ?6 |" h& h, [9 n                                        linecoding_old.paritytype != linecoding.paritytype )
1 a( G$ G" p+ b& o8 c# U                        {
( Y8 [  z. _/ I* n; l7 V                                if(        usart2_flag == 0 )* N- K0 y' D+ x+ x5 ]4 Y0 ~
                                {
- G# y8 W) H9 Q6 |. c                                        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)
3 A8 b& F, ], I4 x9 i" G1 f                        {' m0 w8 [: ?$ j* l2 ]8 l
                                QueueElementByte data_byte;0 A3 @" n/ J/ y* l5 G% `
                                usart2_flag = 1;
8 u7 q- O* j( u* n                                if(dequene(&Qusart2Send,&data_byte) == 0 )' ?; G  S$ q0 ]; y
                                {. W% |# x+ I4 F; M9 t
                                        USART_SendData(USART2,data_byte.buffer);
8 x+ I2 O0 o% b5 @. s- M4 x$ H                                }" p: r1 |" K  N" C$ p
                                USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断
. t) g7 L9 Y0 h' b6 V- Z                        }
2 _1 @" y2 \* y0 C, @              
7 j8 W& W5 F3 m# e                        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
                }
1 {7 w' Q( P5 h6 o5 l  d                else
  R4 {; a! k- X8 f9 J" d$ t+ X                {  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)
7 g$ V' _6 G& c* V                        {( r6 e% h- L6 T3 O- t
                                if(dap2nrf_Data() == -1)
5 Y% D, _8 ?: S5 Y$ `' @! }- a                                {
+ C, z" Y! ^% J6 Z/ e                              * n. `9 @$ a; K" i" l
                                        if(GetEPRxStatus(ENDP6) == EP_RX_NAK)
5 z- u$ j) U% _! X                                        {  v  f4 x" Y8 K5 o4 S! D# C
                                                SetEPRxValid(ENDP6);
- y* S8 C, c' ?5 x                                        }
- O% S' b2 n8 g' r                              
* x) ~& `9 J: s! Z- m                                        if(        linecoding_old.bitrate != linecoding.bitrate ||1 a2 S4 ~1 I( r2 X: w. Z
                                        linecoding_old.datatype != linecoding.datatype ||
) R1 R# g* a* m& @" U  J6 V* \3 t                                        linecoding_old.format != linecoding.format ||: h2 y' Y6 ?3 G6 m9 T) p
                                        linecoding_old.paritytype != linecoding.paritytype        )
# n8 i, H. E8 L; W4 f                                        {: 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));
- ]1 M+ j& l! }9 R4 U/ e                                                NRF24L01_TxPacket(buffer,sizeof(linecoding)+1);
% O- }3 k# v& M+ ^; E& p3 k                                        }
" Q: B  p# }/ d# r) l8 P9 D                                        else if(queue_size(&Qusart2Send) > 0)* t: g, b# I; c* z
                                        {6 t7 b9 I9 E* U# p2 X" Q
                                                QueueElementByte data_byte;
2 D# h( [5 @1 L" ~+ @) Q! g; d, C                                                for(i = 1; i < 32; i ++)1 y8 w/ v  l, Y4 f" z& w
                                                {
, @6 l2 o2 v7 a8 s                                                        if(dequene(&Qusart2Send,&data_byte) == -1 )
! `2 [) S& x0 J( h5 `' z                                                                break;
! J. U/ S  u5 L/ T                                                        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);
7 _) j' T: V) q( Z; R                                        }; 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)
, \) T  f: ~. @8 e/ q                                                {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);
. \( c, V( v' @" y) p                                        }+ d4 |# R! S$ j# b5 M7 O# w
                              
1 d! @' O8 }/ L; ]: d, h                                }3 U6 q! l+ S6 i1 I; P- i. x' F
                        }
3 H9 n) ?/ F3 o5 @1 b                }& E' I5 w/ z; |4 J( _
```
* ~8 W/ L1 h5 _4 V2 N: a
: `7 A, K) P3 G' s9 v5 w% Y% \实物使用截图如下:8 O- Z; T: q4 T
6 N; Z/ x  a! s4 F: t( h& }
![12-6.png](data/attachment/forum/202412/19/185713mjuwqnqnzbnnqznz.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-6.png")
4 Q4 k2 f, Z5 {( V/ E9 `; n( ]& b3 P
在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。8 ]) O5 \  a' W
) r) \" H5 c$ X/ o
使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。
3 b3 b1 G4 j5 n5 i3 q
5 i9 Z/ J; C- c8 P& F6 V硬件设计的时候,设计注意事项:
* ?- n- G* K+ L! F
8 W! R0 h: D! V3 K- c使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。7 s2 n2 F. s+ E% s

' [& f: S# F, x+ d( CMP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。
& k9 f% e3 n; c! k, Z9 E* R
" d4 ~8 P# a4 M$ w9 gPW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。
' \0 d6 W+ y: k, t1 o. r, w2 Y( f- F) j: c, u) r4 z
同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。
: `) Y5 Y/ b5 z0 q/ Z# K) {1 E8 q# x. B! e& I
在软件开发时候,有以下的注意事项:
7 a9 m4 ]( G8 H- L. i
, B+ p* Q. f% D抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。
, Y* T( u7 h/ I% h; Z& V- |( N0 t: R: W# J
功耗管理:在不需要通信时及时将NRF24L01置于待机模式或掉电模式以降低功耗。# t; w0 |! p# R8 {

0 _4 g! [: u4 C; ~7 o: d4 k1 U: b2 W距离与障碍物:无线通信距离受环境因素影响较大,障碍物会严重影响通信质量。在实际应用中要考虑通信距离和障碍物的影响并采取相应的措施。
8 a5 @* K7 e" H
( l, p3 G+ x) N4 h( BNRF24L01的开发过程需要仔细规划硬件连接、合理配置软件参数、掌握调试技巧并关注实际应用中的注意事项。通过不断的实践和总结可以逐渐提高开发效率和应用效果。
6 O, I+ w5 J* f2 G' T: b9 B: N. K# B2 a' G$ n
原理图见附件:
1 L0 K* N. M/ ~6 W( b/ S
3 b9 T* s. [, o0 ]4 X![PDF.pdf](data/attachment/forum/?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "PDF.pdf")
, q! T8 _* ]1 I" r/ P8 E
$ v. P+ V7 {& C5 g9 D
12-1.png
12-4.png
1.jpg
1.jpg
赞 收藏 评论1 发布时间:2024-12-19 19:00

举报

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

, h0 \# H! x% u. K8 `* _重新上传一下 原理图!!!
3 ]5 d* b3 `' G$ ?3 \& E& o/ {* S 无线下载器原理图.pdf (1.56 MB, 下载次数: 2)

所属标签

相似技术帖

官网相关资源

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