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

使用STM32F103制作的无线下载器

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

; \( x$ o% d8 @( o![12-1.png](data/attachment/forum/202412/19/183819haf0jpwfrbfjj9er.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-1.png")4 U; h, J; v2 b# y; Z* ]2 H
& f  y' v* k* s; o
二:PCB图展示:) l9 m$ m/ b' |- N
4 O8 f; P' R0 B1 S
![12-2.png](data/attachment/forum/202412/19/183852j26ztttwzci2cc1t.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-2.png")
( j$ {/ m& K* \% J# b
5 n7 D7 @4 l6 c7 ?* X( i0 }" Y三:软硬件设计的思路:; \0 ~5 F. X8 Q* w  F

, z' Z1 X+ W* v6 @在本次项目中使用主控为STM32F103C8T6芯片,当时使用该块芯片是因为该款芯片具有USB功能,该芯片可以虚拟一个USB的串口进行数据交互,而且封装也比较小,在PCB布局方面比较简单。
  m9 ?) m4 P: s2 R2 T; y/ w" p% v: V& s' b9 U! j+ r1 v
无线模块采用的是一款SPI通讯的NRF24L01芯片,在实际的使用过程中比较稳定,可以满足数据之间的交互。, B3 A0 p7 N6 s4 z
  r' a' r& W% R" c
软件设计思路:利用串口1的引脚的接收发送引脚,使用消息队列的方式,可以将USB下发的的数据发送出去。
( j3 A) w1 G: O6 M  }
. P" y6 ^# C$ ~6 ?使用串口2完成与SPI之间的交互,
% q1 n" e' A6 D1 x; l. u- K& `$ a! v/ x  C
软件配置参数:使用STM32cube MX软件生成USB,SPI,串口底层的驱动部分,这样开发起来也比较容易;
8 U. G, p# h; ]0 t
; a: }5 j, e! E+ Ecube软件配置图如下,主要是对该项目中使用到的引脚进行配置
/ [* H, t+ d# ^- [: s: R/ J% l) @5 ?0 c- P5 O2 g! }2 ^
![12-4.png](data/attachment/forum/202412/19/184938vzhuojy923nhu3lj.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-4.png")! R3 N0 @( |) o0 j3 L" B

8 T/ o8 {% }0 v4 w* A部分软件代码:
3 [1 Y; _4 |- U% T: l: d- M5 S. n6 m; g; B$ N, c9 I
```abc
% @  O2 ^  f% o1 K: H. [                if(sd == 0)
+ l/ p4 U/ j0 ]: Z( |1 y                {7 P) G) W# q' P; P/ l! M
                        USART_Cmd(USART2, ENABLE);                    //使能串口 8 |& X. `# o+ c' F; Z' `8 a& H1 k
                        if(        linecoding_old.bitrate != linecoding.bitrate ||+ w# I. z0 Z( Q" q
                                        linecoding_old.datatype != linecoding.datatype ||
, [. d$ u1 x! g& i6 i5 q- L                                        linecoding_old.format != linecoding.format ||, R1 p9 r; M, S* {! o! {
                                        linecoding_old.paritytype != linecoding.paritytype )/ y3 ]  S0 l8 F8 O4 b9 w9 W( I
                        {
  \) U; o$ t. [  B                                if(        usart2_flag == 0 )
; e& N5 ]2 m9 O                                {
; k4 B$ E% \0 w1 c6 w6 L                                        uart2_config_change(linecoding);
% r' v, \5 B* J+ a" o                                        memcpy((void *)(&linecoding_old),(void *)&linecoding,sizeof(linecoding));; N  M: X0 Q4 Y" v& T7 ?! i2 B
                                }
/ h8 [+ |; g+ J2 f7 F3 }                        }
+ z8 X8 y& W# @# `. Y+ S                        else if(queue_size(&Qusart2Send) > 0 && usart2_flag == 0)8 s& w1 o0 V1 `  a9 S' _& v% \; ?
                        {
* h! ^) T# k0 X; S1 S* i8 q                                QueueElementByte data_byte;
1 {+ \' p, m' t) _3 ?; z6 y; f                                usart2_flag = 1;. B" @7 y# G, B6 f7 {8 b9 k
                                if(dequene(&Qusart2Send,&data_byte) == 0 )
6 B! L) _. L6 E9 U! ^! X                                {5 U) H$ S/ R$ N# h8 Y# a
                                        USART_SendData(USART2,data_byte.buffer);
; J% D0 }! ~; q/ _                                }* z! L1 @" G. \# N& ^
                                USART_ITConfig(USART2, USART_IT_TXE, ENABLE);//开启ENABLE/关闭DISABLE中断
3 l4 M) S/ y0 w                        }! Z( a( V" F! A/ D6 m4 k' T
              
( j& B6 R% _! ^5 H8 U3 `                        if(GetEPRxStatus(ENDP6) == EP_RX_NAK)
& a4 D; G3 ?4 t/ T4 q                        {# t3 d, I. ?2 N1 l9 q' Q+ P8 _$ ?
                                SetEPRxValid(ENDP6);+ ~3 m) q" G- Z* X& i  }/ U$ x! l* u* G
                        }4 q, f  [+ s% q
                        if(GetEPRxStatus(ENDP4) == EP_RX_NAK)
# W9 W3 ^+ Q+ r: i+ i  _& U                        {- A, G3 k) s: c, j3 b% A" F
                                if(CDC_MAXSIZE - queue_size(&Qusart2Send) >= 64 )
0 u0 |! M% [* m' s2 ]" y                                        SetEPRxValid(ENDP4);
4 o& `0 }7 |; I9 ~9 e5 ]                        }
' {) I5 O1 R4 I7 e+ S3 V" U7 _4 s7 c5 X! B! i# X: U3 [1 l" |
                        if(nrf_state == 0)
- z9 {5 E) C& h                                NRF24L01_TxPacket(buffer,1);: w' r# D7 {+ ?4 K' ^& g
                }6 Q7 g8 e# ~% E: V
                else
' s5 q% C! q$ w% ^                {3 V4 A# `# Q# T7 s2 X% l' F. [; q! E
                        USART_Cmd(USART2, DISABLE);                    //失能串口
. E- o# ^2 x' V0 X. w6 X8 {9 D                        if(nrf_state == 0)
0 ?/ ]/ W4 a+ k; ~6 e                        {+ j7 d) v" G6 \2 A) s+ ?8 K2 F
                                if(dap2nrf_Data() == -1)
: v4 t2 e0 ]  a: i9 d6 _2 i) w                                {, n  Q, L/ y5 @5 o  s7 V/ O4 }3 y
                              
8 y4 L0 A: ]% _, p8 K* V# u- j                                        if(GetEPRxStatus(ENDP6) == EP_RX_NAK)
* E) m. `5 ]) h                                        {
3 H0 G1 o# P+ p                                                SetEPRxValid(ENDP6);  R* M7 G/ V5 W* w9 \  |
                                        }# l  j. I2 |3 Y$ \6 ?
                              5 |5 Y# Y" t2 c0 Y, M: t! d8 Y
                                        if(        linecoding_old.bitrate != linecoding.bitrate ||" o1 a; J( \5 K* m+ f9 k
                                        linecoding_old.datatype != linecoding.datatype ||
1 q% _/ [: b% d5 d- }                                        linecoding_old.format != linecoding.format ||
& }% F1 v1 ~6 z( J                                        linecoding_old.paritytype != linecoding.paritytype        )& g, M* e! d# V
                                        {
' f+ `3 ]5 h1 ^8 F" Y. X                                                buffer[0] = 33;//特殊串口设置指令
6 p0 R' \7 V  s" W& B8 }# @                                                memcpy((void *)(buffer+1),(void *)&linecoding,sizeof(linecoding));
0 x) b- o( C& F/ N" W  z( L                                                NRF24L01_TxPacket(buffer,sizeof(linecoding)+1);+ ^5 Q! o) S9 Q1 ]3 E+ w: B
                                        }/ N! ^' P  C8 X
                                        else if(queue_size(&Qusart2Send) > 0). |* @% h5 g* a6 W( G
                                        {; K; J' c/ P  s; e9 g( d( T- v& A, B
                                                QueueElementByte data_byte;5 E4 f, T! r. H6 o) D
                                                for(i = 1; i < 32; i ++)# g+ s7 [. w: j9 W$ b/ ~; e6 {
                                                {- d5 {6 i. q4 b- `" N# O
                                                        if(dequene(&Qusart2Send,&data_byte) == -1 )' U& a. W3 ~) ~' x+ B
                                                                break;0 t4 r: `5 d$ V. X6 s1 p
                                                        buffer = data_byte.buffer;  q$ b2 _3 e% \  j9 I: ^& _( M
                                                }
6 [. u  e; X! N0 h3 h, P* J                                                buffer[0] = i - 1;1 F8 l, O4 J& q- S
                                                NRF24L01_TxPacket(buffer,buffer[0]+1);  J0 R9 f2 d) z3 R- o/ D3 k
                                        }
' f; X! h- t) @! i( Z                                        else
* `. S0 e2 o4 y- G# m* K                                        {
: A; e6 h! M9 Y* E, d6 j                                                if(GetEPRxStatus(ENDP4) == EP_RX_NAK); ?1 ^! E( ~% M2 Y
                                                {2 |$ y# C) ^' f; h- ]& `
                                                        SetEPRxValid(ENDP4);
% g  J6 S$ G7 d  @! `                                                }
: w* R4 i( i. _. r4 r$ t                                                buffer[0] = 0;1 e4 [* @! s' G. i! ^
                                                NRF24L01_TxPacket(buffer,1);
' D: t$ F' i" ^+ h" J                                        }( F- b( Y$ o+ i! S
                              
3 S. a4 [1 Z! i; n& _8 m                                }' D# t' K6 y/ P1 a, U) }
                        }7 }# W6 i1 q. A
                }
1 u2 X, k0 a9 X0 X- e```
2 z- ~1 p9 |+ k0 j# y! ^/ q5 ]5 Z% q
实物使用截图如下:
: K3 J) O5 P, u% E3 {( V5 g4 S
8 V2 U1 g/ n6 i' k% E& j8 s1 Y![12-6.png](data/attachment/forum/202412/19/185713mjuwqnqnzbnnqznz.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "12-6.png")4 h1 G$ |" X! Z4 K+ X9 b! I

/ B# x  x- s' K) i! w在实际使用中发现,硬件功耗大概在130ma左右,在数据交互的时候功耗会增加至170ma左右,不过并不影响模块的使用。
  h* M. t8 |* J; \- `2 n, ^& B# L1 O9 V0 d
使用该模块的最大好处就是可以让硬件工程师的桌面更加的整洁。+ n$ r% B" `4 v; Q' d5 y7 d- k" C3 B

% {9 }, s9 O- ]' G* S硬件设计的时候,设计注意事项:
+ r- N- e' T% n; F4 ~* A
3 H2 ?2 L: l/ m0 z. Y+ L使用PS7516用作升压芯片,将电池电压3.7V升压至5V,为外设可以提供5v的电压输出。  B4 F7 r4 K1 o' [5 Y3 `

* s; c* j$ s3 ]4 V) }2 `- fMP2155为降压型LDO,具有可关断功能,当不使用时候,可以使整个系统处于低功耗状态,从而延长电池寿命。
# W0 A* c4 ~5 Q7 k$ k. |# y0 O% Z; J% p
PW4054为锂电池充电芯片,可使用type-c为电池充电,充电电流由R26取样电阻设定。& I- K+ [) P" K# S

: k" M, H$ ^1 z8 t  O7 Z同时PL5356A芯片为锂电池电压检测芯片,可以显示当前的电池电量,后期将电池电压分压至单片机的ADC内,从而精准的检测电池电压。& d- D5 R! Z9 `

8 o. P; E: N$ j( _6 y! t在软件开发时候,有以下的注意事项:
) {( E- u3 P: I2 t
7 u" E; C" H( x" R; T4 E  T抗干扰能力:NRF24L01工作在2.4GHz频段,该频段易受到WiFi、蓝牙等设备的干扰。在布局布线时要尽量减少干扰源的影响,并合理设置通信参数以提高抗干扰能力。
4 u; M0 ~/ c1 k, V/ c0 r% N+ R- B* c
功耗管理:在不需要通信时及时将NRF24L01置于待机模式或掉电模式以降低功耗。/ f$ y( N8 e$ f. O: \
! x. [# a' }! p6 @1 }; q
距离与障碍物:无线通信距离受环境因素影响较大,障碍物会严重影响通信质量。在实际应用中要考虑通信距离和障碍物的影响并采取相应的措施。
( v( R: m) P; i* m
+ j3 ~* [, F5 ~5 aNRF24L01的开发过程需要仔细规划硬件连接、合理配置软件参数、掌握调试技巧并关注实际应用中的注意事项。通过不断的实践和总结可以逐渐提高开发效率和应用效果。
# u) s% v2 f6 W: Z+ W2 W  v3 s* Z8 t4 k& Z- f8 Q3 m+ ?4 g
原理图见附件:  x8 M  s4 ^% J
' H. M6 \$ N6 J* b
![PDF.pdf](data/attachment/forum/?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "PDF.pdf")
3 w, v, S& }6 s( g8 t" V
# Q, T) D  }3 G0 [8 E) o- B
12-1.png
12-4.png
1.jpg
1.jpg
赞 收藏 评论1 发布时间:2024-12-19 19:00

举报

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

% _. r$ ]7 T; [4 B) e& E重新上传一下 原理图!!!
7 M% c& U6 }+ E2 Y' ] 无线下载器原理图.pdf (1.56 MB, 下载次数: 2)

所属标签

相似技术帖

官网相关资源

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