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

使用STM32F103制作的无线下载器

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

7 b4 A% h( F& g/ A+ a' ]一:部分原理图设计:
, m8 r: o2 S2 M$ f( o
  |4 Q: U' }+ A+ d% V& q![12-1.png](data/attachment/forum/202412/19/183819haf0jpwfrbfjj9er.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-1.png")
7 f/ W4 x: p; l9 J' g
' a3 Q) U9 u& ~2 M  g4 W- P二:PCB图展示:
( B$ b/ {3 N. e* R  i' @) t/ w& g& \! T4 O
$ `+ I9 s$ H7 a# C5 }# i% T4 t. }- n' M![12-2.png](data/attachment/forum/202412/19/183852j26ztttwzci2cc1t.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-2.png")1 C, e0 p( v) y: d) y1 s

7 p: _; c5 Y6 n+ {, v- h1 W三:软硬件设计的思路:8 D1 B' O( \* D; r& x* ^

1 X0 j& ]' l: f在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。
8 S' m1 h0 x& r) `
- B$ u% s5 T0 @+ ?; N: [无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。
4 Q4 I  V4 j- Q! A/ h
$ I5 c. H) N  R6 Z$ ~6 [# O* D软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。6 v; h1 K7 X- A" p2 P
9 a5 \8 R) f5 N
使用串口2完成与SPI之间的交互,* G, @* p, g0 n& F
) c6 t( @/ G/ l9 u- Z, V* a& _1 f* W
软件配置参数:使用STM32cube MX软件生成USB,SPI,串口底层的驱动部分,这样开发起来也比较容易;  `" O8 ^8 ^  d! |6 D

+ S3 l/ i: _! c$ ?; qcube软件配置图如下,主要是对该项目中使用到的引脚进行配置. G* K& p+ A, n
2 a9 B5 `+ r* ?; Z2 R# d! T) o
![12-4.png](data/attachment/forum/202412/19/184938vzhuojy923nhu3lj.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-4.png")
: a: G8 |) |. A3 c. P. T& Y
+ R; V+ j' `8 Q* K7 h部分软件代码:# }5 H$ s1 j' y/ {. a! {3 v
/ Q' f% [$ L' g' l  M9 K; P% p
```abc
" e8 G9 W- {' z) v1 S5 w' X2 M                if(sd == 0)
2 r: n+ G3 a+ R; W$ Y& G2 |  ~                {9 y" S7 d5 s6 f$ T. x7 x- [
                        USART_Cmd(USART2, ENABLE);                    //使能串口
, g5 O. R1 Q8 O* _                        if(        linecoding_old.bitrate != linecoding.bitrate ||  u$ ?  B! s/ K! i& ]
                                        linecoding_old.datatype != linecoding.datatype ||
1 R" a; S4 e/ D8 H3 K2 ]                                        linecoding_old.format != linecoding.format ||& U; P7 m& h; Q/ C" @5 H9 ]
                                        linecoding_old.paritytype != linecoding.paritytype )0 p* [6 F( e0 r. W: w
                        {! d' Z, G6 l( A& f% s6 o' T' a2 x
                                if(        usart2_flag == 0 )9 W7 _- t" \* A6 L
                                {: G- {6 l0 q$ h! A! G
                                        uart2_config_change(linecoding);9 v! |1 {/ q( h2 K# ~: t; f% u+ M
                                        memcpy((void *)(&linecoding_old),(void *)&linecoding,sizeof(linecoding));
! c5 N! r+ A9 O7 S- [' F                                }
% ]( Z! X* L- S5 P0 F: b) y' [                        }3 \, R8 L. b9 S% x+ F& g; y  {
                        else if(queue_size(&Qusart2Send) > 0 && usart2_flag == 0): M$ V* x. }  \' q* @* j
                        {* K6 [8 ~% }* j. c2 [
                                QueueElementByte data_byte;- T0 q/ F/ [# F3 o& k( k
                                usart2_flag = 1;
  I" \3 j- d9 k' G( S# E                                if(dequene(&Qusart2Send,&data_byte) == 0 ). |, p0 p5 {- R0 Z: C5 j" F1 f; P
                                {! A4 ^6 o: C! n& L
                                        USART_SendData(USART2,data_byte.buffer);
/ U9 k; q9 R5 a                                }
! ~# c7 N. U( v6 c& U6 m! q                                USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断5 U) t. C8 K; Q8 g
                        }: \+ N( {% I" `+ `; R2 K0 V) _' u$ `
              
: K- W( Y" m, \2 L                        if(GetEPRxStatus(ENDP6) == EP_RX_NAK), ~3 a6 h* E3 U
                        {
0 H% z' h8 g; b" J: X                                SetEPRxValid(ENDP6);
1 B& A2 C  N" ^& [                        }/ \0 [3 s4 D* m- G4 n4 G. L- z
                        if(GetEPRxStatus(ENDP4) == EP_RX_NAK)# f+ f; F; g3 `/ u, K0 P  H( n
                        {
, e. d. H1 l. b6 E/ w                                if(CDC_MAXSIZE - queue_size(&Qusart2Send) >= 64 )
& b+ W1 }' D6 @! ^                                        SetEPRxValid(ENDP4);4 G+ }3 O" ?/ D- W3 F1 ?
                        }* B: s( ^' H9 v* g% Z' C

9 e- a, Y6 G, y/ {                        if(nrf_state == 0)
/ p1 z5 P8 ~$ j0 J# M                                NRF24L01_TxPacket(buffer,1);+ T; Y' s" D- j& E9 [2 W. {4 N
                }4 H+ r1 c0 q% @& l6 T
                else
- Y8 H" y+ [* H$ M: g                {
1 K! _- r& \( a7 ]                        USART_Cmd(USART2, DISABLE);                    //失能串口
, e2 v0 e0 z# v+ V$ }                        if(nrf_state == 0)
" B; e1 E/ J1 i, k2 X5 b$ }  L                        {& e9 D9 @/ ]# d. X& o" S/ h# p
                                if(dap2nrf_Data() == -1)
) X$ y, z5 y/ U1 ^; r" r                                {, `' `- z9 @, s1 x" C) j
                              / P4 Q2 w8 s: K) n3 Y* W6 R2 R$ f
                                        if(GetEPRxStatus(ENDP6) == EP_RX_NAK). {- p0 \/ H# P) A* @6 r5 d
                                        {' w! P1 ?) f6 D7 e! b/ k9 A. d
                                                SetEPRxValid(ENDP6);, W, t0 h. i+ Z' b0 e' c
                                        }
! h9 @; l& q8 h: A) h8 \                              ! c- _7 o  S5 _& g  W
                                        if(        linecoding_old.bitrate != linecoding.bitrate ||5 `' v7 e7 c* |. k. h7 s1 y
                                        linecoding_old.datatype != linecoding.datatype ||
2 c; D/ k5 @! B+ q6 r% S8 r, L                                        linecoding_old.format != linecoding.format ||0 x( h4 z9 X7 ]- V. N# ~4 J
                                        linecoding_old.paritytype != linecoding.paritytype        )+ e5 J0 E3 l7 w6 i
                                        {+ {# l0 S% \8 V/ v8 O" ?' w4 e
                                                buffer[0] = 33;//特殊串口设置指令3 {2 \! p/ W8 |; H) d$ R
                                                memcpy((void *)(buffer+1),(void *)&linecoding,sizeof(linecoding));# M" v5 k8 ~4 j( P5 P( q* h
                                                NRF24L01_TxPacket(buffer,sizeof(linecoding)+1);
# p) F; q3 F! ^/ J                                        }  [* S5 c7 e" D
                                        else if(queue_size(&Qusart2Send) > 0)
* g" y  S/ p4 y$ A                                        {
9 G: ?7 V# b& H8 V9 B: O, t, x                                                QueueElementByte data_byte;+ _$ a% B& d( Z- K& ]" h
                                                for(i = 1; i < 32; i ++)
( y* x3 u* b( C" m                                                {
0 }' l  i$ S$ q& J                                                        if(dequene(&Qusart2Send,&data_byte) == -1 )
! Z% q+ o' D. I                                                                break;) G! b4 C( T' Y; i
                                                        buffer = data_byte.buffer;0 _; I- t" ?' ?9 e0 F
                                                }
, V. E+ V- I3 o                                                buffer[0] = i - 1;& ?* i* C% a. M. \" T9 L# B
                                                NRF24L01_TxPacket(buffer,buffer[0]+1);! ]# h& S7 P4 {8 f/ `
                                        }
. ?/ _7 m0 ^+ L' |1 F                                        else$ q, X+ d: v$ h2 E
                                        {
: @' o! B/ C& A9 Z4 O1 f                                                if(GetEPRxStatus(ENDP4) == EP_RX_NAK)8 E* j2 ?' ?9 \7 w' ?
                                                {2 ~. v, E/ G2 X) |9 o4 l% @1 ^
                                                        SetEPRxValid(ENDP4);
  h7 @  S; v( E$ K  N4 C  D& w0 M                                                }3 z) V7 u2 j- M' r/ S: j' C7 ?
                                                buffer[0] = 0;
$ {" t1 g1 y. K; s2 R: Z5 O% d                                                NRF24L01_TxPacket(buffer,1);" U) J- H$ z! K; i+ e: j
                                        }
1 ?( W8 m! O+ t* y8 }. g3 O                              : ]" g& |) y# u9 |8 F* b
                                }+ l, V2 K. j8 T( U) L0 `7 c0 j- h
                        }+ X( B% n- l% J" E/ E; R6 Y7 ~
                }
. ^9 v! r% J0 {0 T0 V```1 K! o  ?, o7 `* H: k4 d

. N  t2 w8 f) M% c实物使用截图如下:9 \) l* f' [( ]

0 a" S% w' @9 R/ b- J: ~& _![12-6.png](data/attachment/forum/202412/19/185713mjuwqnqnzbnnqznz.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-6.png")8 q  Z- `. t" E& e4 l

& L- V7 h8 M  T( E) R4 ~& R! y& X在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。# r5 t* Q' k- m& C

, p: k( C. Y1 i- F使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。
4 e* Y' k/ M5 _0 ]! n1 c8 @& B2 ?  F9 c9 g5 Q8 I
硬件设计的时候,设计注意事项:
( O, ^" `2 F, e- {9 d4 R9 b) d' ^# _
使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。0 C) v. E2 m7 O+ G+ w( J6 A
1 G9 D0 |5 Z- x5 \( a5 g0 _- }  X
MP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。6 G7 ?+ ?) d/ ]7 k& s8 A5 R
% c2 ?. a' W. P: p3 w
PW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。
& ^0 S! S9 v. l6 u7 h
* I. D) A7 G5 j6 k$ V/ E+ W3 p同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。! i. E5 h' t( s- G) D3 K  L
/ c) V! g' U2 h% Z/ _
在软件开发时候,有以下的注意事项:4 Z8 K9 ?% ^: I/ H" D

0 X0 n; Q# K, B" l* r7 y* @抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。. y/ S5 }# A! P, e/ }6 J: ~9 h

( J2 f& r- U# d4 G( ~功耗管理:在不需要通信时及时将NRF24L01置于待机模式或掉电模式以降低功耗。! A, i( l( T1 y: }6 {* L
) [. u  E6 T; Z! h* _- S+ e7 y# H- z
距离与障碍物:无线通信距离受环境因素影响较大,障碍物会严重影响通信质量。在实际应用中要考虑通信距离和障碍物的影响并采取相应的措施。8 C. `1 }  _* T
7 Q- S0 M7 o9 S% m: ~
NRF24L01的开发过程需要仔细规划硬件连接、合理配置软件参数、掌握调试技巧并关注实际应用中的注意事项。通过不断的实践和总结可以逐渐提高开发效率和应用效果。# {( t. c5 O% ~) L, F  M# U

  i5 E/ e5 w* e. `4 n9 _# ]0 c原理图见附件:
  N& x/ G; T7 H: Y' D6 n- a8 u+ x7 I& ^* |) p1 o- h* ~: K
![PDF.pdf](data/attachment/forum/?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "PDF.pdf")  H# Z9 i& G  C6 f; u
  a5 I( x- q. g! S
12-1.png
12-4.png
1.jpg
1.jpg
赞 收藏 评论1 发布时间:2024-12-19 19:00

举报

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

0 M. d/ G( ]2 i# n6 e重新上传一下 原理图!!!
7 ^/ h- x% Z& V2 ?8 { 无线下载器原理图.pdf (1.56 MB, 下载次数: 2)

所属标签

相似技术帖

官网相关资源

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