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

使用STM32F103制作的无线下载器

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

. g9 h' S% w/ e![12-1.png](data/attachment/forum/202412/19/183819haf0jpwfrbfjj9er.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-1.png")
4 t6 p, I$ z' w& b/ E  c* y# d# i+ ^4 l# t- b* N
二:PCB图展示:
4 c; [# Y, W" |( M" w& |- S! [0 `# c  j: R' v% e! F+ n; Q
![12-2.png](data/attachment/forum/202412/19/183852j26ztttwzci2cc1t.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-2.png")5 i8 m. \& ?$ Q6 E- R* }
; \: K% p1 w+ ?, ]
三:软硬件设计的思路:
, t$ }6 u9 y' ?* e
& M1 o( {. X. S! i4 z6 D/ S在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。3 T" ~, H( W8 O
% r$ r8 ~1 _- `
无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。
' C3 X6 L( y% w# t
: l7 g9 Q. T1 G- m  d7 _% w软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。
5 u: u( P6 a+ H( X7 T# M* Y: p/ F  g# X$ D% w
使用串口2完成与SPI之间的交互,
* Y; j* W7 C; c2 r
$ J& _9 O2 h( `& k% x* s/ m! M3 m软件配置参数:使用STM32cube MX软件生成USB,SPI,串口底层的驱动部分,这样开发起来也比较容易;3 F0 q# b% U/ @
  f8 s# I& }3 t. _# [
cube软件配置图如下,主要是对该项目中使用到的引脚进行配置! M5 V5 H/ ~4 n; _% J

/ h, r5 j0 a( ]% A9 Z0 p( J. G, a![12-4.png](data/attachment/forum/202412/19/184938vzhuojy923nhu3lj.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-4.png")
' r+ b+ m: i9 f1 [2 [6 z- m( u. z
: @" g# S& V% j部分软件代码:
4 o+ T$ c& h% s- A5 k0 j2 @# L0 i, l2 A$ M! `4 l+ Y: {
```abc
) O2 f2 `  U$ Q2 M& X                if(sd == 0)
+ i$ U5 \$ |/ i                {
; Y( N9 v6 S, g                        USART_Cmd(USART2, ENABLE);                    //使能串口
+ X* z  W$ L; w% c, ]' e' V# S                        if(        linecoding_old.bitrate != linecoding.bitrate ||
  R9 I( `9 i- v2 j" R                                        linecoding_old.datatype != linecoding.datatype ||+ V: W, ~, P7 \4 e" i
                                        linecoding_old.format != linecoding.format ||
6 P, U; B; r7 t& H                                        linecoding_old.paritytype != linecoding.paritytype )" z1 q7 \# I) s7 H4 o: N8 X. q
                        {
  z. T3 p  G1 ^9 e& c& L                                if(        usart2_flag == 0 )
! A2 K# }; ?* C; ^6 O, O9 ?                                {
" B4 b5 p' X% c' l$ ?! t) L* B                                        uart2_config_change(linecoding);
  I& e6 j0 Y! C- Y8 R6 i) S                                        memcpy((void *)(&linecoding_old),(void *)&linecoding,sizeof(linecoding));5 [$ f: T! w+ r; S1 I
                                }
7 X+ u+ h8 S. S# h4 z* J6 E. f                        }, n: u0 x2 [; ?( w: F) u
                        else if(queue_size(&Qusart2Send) > 0 && usart2_flag == 0): C9 o* e/ L5 t# A3 P; r8 b- o. e
                        {# r% P, ^, v) i# S1 h' ^
                                QueueElementByte data_byte;; C0 A5 G# Z; Y$ ?0 n* P6 J, q2 `4 p
                                usart2_flag = 1;' H$ z, R, [1 \2 a! U/ h: y
                                if(dequene(&Qusart2Send,&data_byte) == 0 )4 Z# u. B+ f) E
                                {
: `4 R0 D: x9 H; f/ I                                        USART_SendData(USART2,data_byte.buffer);6 V! Z6 ~* ?5 L5 j: Z$ G
                                }
3 q9 y  L- g7 U$ a; J+ O) q                                USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断
* Z2 `! c. e/ a, o7 W                        }7 W* \" j# [% f( Q( c2 C" H
              1 t# m8 q( o( f4 J. y+ D; V/ t
                        if(GetEPRxStatus(ENDP6) == EP_RX_NAK)
0 ^/ p. D& D8 c5 J& x4 s& S4 }( J                        {
% t- [, {! o+ y' P5 B1 c, T2 x                                SetEPRxValid(ENDP6);
  j# H  A& _' D) ^/ y! y1 X& L                        }5 N! p& B% P2 z+ W1 |
                        if(GetEPRxStatus(ENDP4) == EP_RX_NAK)
1 i  i; R! b: {2 v/ {                        {
0 c% I- O  g: y0 U3 b9 L$ r                                if(CDC_MAXSIZE - queue_size(&Qusart2Send) >= 64 )" N2 j% O) o  V, q1 r5 B
                                        SetEPRxValid(ENDP4);0 g2 k6 N8 e, w, M& K- Z! z0 Z
                        }# s2 o3 M$ T( h9 L' T+ g
4 Z0 I" X) q- y. M
                        if(nrf_state == 0)
; `. ~+ @+ M! ~" G- b                                NRF24L01_TxPacket(buffer,1);
; P3 \, N9 X$ Z" g) j                }- j" o% Y6 A( x1 R
                else
7 ]* O6 i. Z" b" K                {
4 ~" I( D6 L; w/ K2 h& w7 M                        USART_Cmd(USART2, DISABLE);                    //失能串口 ! u: j6 a% P0 }( h4 W$ u6 v5 J+ d
                        if(nrf_state == 0)
' w( U! B6 m- M& _) C6 @8 L                        {
6 T5 b+ n! d0 l, `* u8 d+ [; s5 T, ]3 i                                if(dap2nrf_Data() == -1)
" A1 V3 p8 N5 E6 ^% T) x                                {
2 T9 D1 I, v6 A2 r3 j" P: r                              
8 H" D5 j; q+ y2 d' q, S( u* P                                        if(GetEPRxStatus(ENDP6) == EP_RX_NAK)
' s* p4 R) V$ Z# u  F  |" Y7 W                                        {
  H4 T9 N9 p9 _( l) ?2 }  a                                                SetEPRxValid(ENDP6);# \) K2 S# _- L& J6 u
                                        }
  U( ^4 X; [# V                              
% p4 s% w2 P$ [                                        if(        linecoding_old.bitrate != linecoding.bitrate ||
3 L2 }4 S" ^5 V: q                                        linecoding_old.datatype != linecoding.datatype ||" I9 V4 U' h" p0 i
                                        linecoding_old.format != linecoding.format ||
( }4 G  z, |( P8 `/ @* T                                        linecoding_old.paritytype != linecoding.paritytype        )
5 j" Q# T- O( S; D                                        {
! o4 B9 Y% e! Z& T0 j% `2 q/ G" [                                                buffer[0] = 33;//特殊串口设置指令* z  I4 E& w  `. m! p, A3 y* C# S
                                                memcpy((void *)(buffer+1),(void *)&linecoding,sizeof(linecoding));
" l$ r- |. F$ O0 @# v1 E! k                                                NRF24L01_TxPacket(buffer,sizeof(linecoding)+1);
" ~4 F1 j' a9 i# Y                                        }
" V' e3 N. D* V# [( X3 N! i) b                                        else if(queue_size(&Qusart2Send) > 0)! d, g  Y0 ^9 y5 \0 v; Z
                                        {' p$ Y* w* A. Z. K# ]; v- J# {' i
                                                QueueElementByte data_byte;
; w+ B6 x% R9 r' }  P; W, ?                                                for(i = 1; i < 32; i ++)9 F4 ^6 c/ i6 ?5 V5 J
                                                {0 g. ?5 ?/ T8 ?
                                                        if(dequene(&Qusart2Send,&data_byte) == -1 )0 F5 E, l  t& s9 s7 e
                                                                break;+ j2 ?8 F8 m$ ]! ]6 P6 u7 o
                                                        buffer = data_byte.buffer;/ x7 I; I+ a0 O6 d
                                                }4 N1 n2 d7 S% b7 e) a$ l4 M! p- w
                                                buffer[0] = i - 1;
/ N: r& z3 L. Y% g' t& w; F                                                NRF24L01_TxPacket(buffer,buffer[0]+1);
% H- ^5 E/ y1 v( `0 u  H4 `                                        }
4 L' K$ v, ~2 W( p% s                                        else
$ @% C. B0 Q( _6 h9 Q  N                                        {
3 ~8 E7 j1 O. U                                                if(GetEPRxStatus(ENDP4) == EP_RX_NAK)  a; K5 A3 v* J9 B+ g& T/ p; ]
                                                {& a( r, E3 R  |. H* A: }/ T8 O
                                                        SetEPRxValid(ENDP4);
* z1 N+ J+ x: j" ^# V                                                }
  H: ?! C+ E7 Q9 Q                                                buffer[0] = 0;
/ i9 Y3 _& g1 w" Q                                                NRF24L01_TxPacket(buffer,1);4 x: Q/ e. z& t' F+ O! q; l0 \
                                        }: b1 M; {- w5 N4 z- n" o# S8 R
                              
1 N# [7 o8 k$ `# y9 j5 m                                }+ j( I- \* D/ _: [% b. K
                        }% x* U* ~2 t# B0 @% ~% Q
                }, K2 `( g! z+ G+ w" U
```
" ~6 j% [: B6 `# [+ Q- S1 X6 u% g2 I% r7 D6 B# c4 T
实物使用截图如下:
! x% y& p& ?' l# f: }0 D0 o
/ M3 X5 ^' H7 K' x![12-6.png](data/attachment/forum/202412/19/185713mjuwqnqnzbnnqznz.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-6.png")
0 j, l$ J6 w. S+ S4 e+ J; ]7 p8 {. F; ~0 {$ T
在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。0 u/ R* A+ v- s  r9 T. Y( E4 r
' w  x, s3 R2 S! X3 Q6 {
使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。
, H6 v  h, X# j9 Q9 P7 J1 T+ ?
( T: t; |4 l0 _$ i! @4 D- E硬件设计的时候,设计注意事项:
% p9 ?- n& N5 k) T" k" K/ [* Y9 v9 z
使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。8 `  d) e) y9 m
& N  ?+ n$ M$ N# U* i( k
MP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。5 M* U% X0 e+ _" `; D+ M$ F

& X, [1 X: P7 y5 N% x2 T% |PW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。
1 q6 r, X! p3 t7 u' V
( I# o; ~8 M/ g- Z0 j( e同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。8 Y+ j/ y$ l2 X4 ?

* K3 r$ T0 E# ]8 V& {在软件开发时候,有以下的注意事项:
# K8 Q: \7 T% Z1 @3 t( R& R) _& d. E
抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。
) s/ T4 u/ D( S- |/ A
6 ^: X- p: u4 x& J2 u" ^( D3 J功耗管理:在不需要通信时及时将NRF24L01置于待机模式或掉电模式以降低功耗。. D( r) ]: K' ]0 D

: \2 T( {1 D* F( O% ~: ^距离与障碍物:无线通信距离受环境因素影响较大,障碍物会严重影响通信质量。在实际应用中要考虑通信距离和障碍物的影响并采取相应的措施。- F$ j  [7 z$ y! i
0 t) c8 ^' H& A1 ]& R% \( P  [! M
NRF24L01的开发过程需要仔细规划硬件连接、合理配置软件参数、掌握调试技巧并关注实际应用中的注意事项。通过不断的实践和总结可以逐渐提高开发效率和应用效果。  T; R0 Y: U6 w1 S  r
! d3 F0 S) q! }2 Y! Y* J
原理图见附件:9 r$ n% I+ M. \- X% D

) f7 R8 K& n7 V  u! }- p: P![PDF.pdf](data/attachment/forum/?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "PDF.pdf")
) j3 A; G* u2 Y. J
; r8 _. E7 ~, i# L1 B% {
12-1.png
12-4.png
1.jpg
1.jpg
赞 收藏 评论1 发布时间:2024-12-19 19:00

举报

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

' ?1 X) \- F% P  c重新上传一下 原理图!!!
8 q4 e$ I8 ^: Q" {: L( @ 无线下载器原理图.pdf (1.56 MB, 下载次数: 2)

所属标签

相似技术帖

官网相关资源

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