如果是定时上报温湿度数据的方式,我们可以将这个节点做成低功耗的,这样用电池供电,使用起来就非常方便了。
}, S, m: K3 O! O) U' N低功耗实现有2个地方:4 o) N' u; @; C+ K: g9 J- g
1,MCU本身的低功耗;
. S/ l. Q& Z) D8 ]2,DRF169H的低功耗;
9 d5 Q! @- M3 y0 H8 tAHT10的功耗非常少,我们这个是采用5号电池供电,基本上就不需要考虑了。
5 P. H6 C- u' m项目做下来,休眠时大约电流是50UA,如果20秒发送一次,电池用一年基本上是没问题的。$ J. c, v8 F6 ^" k) J& b
下面来分别简述下这2个方面的实现方法:
# \" o, k0 O( j4 e
0 ?0 o7 K) f- f) ~' Q1,MCU本身的低功耗: A2 v6 [/ Q* `% i6 M# N3 k
STM32G0系列的功耗管理函数在这2个文件里面,是ST自带的库函数,实现起来非常方便
9 N0 m" ^& p# |/ T' j' Q/ ^stm32g0xx_hal_pwr_ex.c
, Q ~, S4 R1 `# _0 z7 Rstm32g0xx_hal_pwr.c
. v% X6 i+ s9 G7 \ x" W4 m' B! |& B s+ r; I m- @
具体的实现方法:4 [) @+ k% @4 f! I7 {4 r& q3 B
1,关闭LED及设定DRF1609H进入休眠,设定DRF1609H进入休眠是串口发送指令给DRF1609H
. N& Q6 c1 E4 ]) N9 F4 L2,设定RTC中断时间,设定MCU进入低功耗
+ b; s. ~7 @9 b3,RTC中断唤醒MCU休眠( Z J+ G" r+ x) L2 C$ _" E$ V
4,唤醒后重新初始化MCU(包括系统时钟、串口、IO口、DMA)5 M; B0 Y9 _4 F1 w+ K3 f; }/ J
5,测量一次温湿度数据- t, {' ]; S& E4 Z# K/ k% {
6,唤醒DRF1609H,下拉DRF1609H的Function按键唤醒' {* \6 G0 Z1 H) r- p) X" `3 l/ z
7,发送温湿度数据
( }( A3 N4 T/ h8,重复以上1-7& r, ]4 K, p7 x& T- Y! o p. _
: T. o+ W& u- ^6 W3 P
- // --Enter Low Power Model -- //3 G3 A: G$ V8 v# U! W
- LED2_OFF();
4 j1 D: E2 C. h! n( y - drf1609h_enterLowPower();
4 R! _( t" w7 T0 _# ?% s - HAL_Delay(5);
复制代码- //--Set wake up time = 0x500B = 10S ----
& U- z) C+ }8 D. R - //--Set wake up time = 0xA017 = 20S ----9 u3 l( e4 g! D; N) R. u3 X
- HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x500B, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
$ M9 x$ }! y$ Q5 P - HAL_PWREx_EnableFlashPowerDown(PWR_FLASHPD_STOP);
$ p7 b, D9 _; o9 s9 z1 ^ - //HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);# ?2 i: }/ X! F" T. b% U, H# |
- HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);
复制代码- SystemClock_Config();
6 K# J2 O- N+ d - MX_GPIO_Init();
6 ]5 M& w0 k k4 b1 p# } - MX_DMA_Init();8 s. }# a% o* f6 n" S; g8 h
- MX_USART1_UART_Init();) P$ ^6 q9 b3 _2 @+ }. Y- F
- ) z" ?4 j: F' M2 C' I; ~
- LED2_ON();
复制代码- //-------------------: g2 O+ V! V/ l+ ? l5 ~
- read_AHT10_once();
复制代码- //--------------------
* S' j" }. h2 e. @5 L' ~& B - drf1609h_outLowPower();
; N, ~' A' o9 a8 B - HAL_Delay(5);
复制代码- //--Send out the AHT10 Data as point-to-point transfer model -----
9 S. ]) q. l+ D" E# ?6 I - set_lowpowerSendOutData();<div>HAL_UART_Transmit_DMA( &huart1, lowPowerSendOutData, 8);
/ k# t" L. B1 ]" k/ N( |$ o - HAL_Delay(5);</div>
复制代码 9 q8 V$ ]- S/ x: g
2,DRF169H的低功耗实现
8 l$ c+ R4 c0 c2.1,进入低功耗# M/ K4 W- n6 T9 y- A
DRF1609H只有工作在End Device节点下才有低功耗功能;
( o C2 o! y( a, H5 [8 q发送指令,即可以使DRF1609H进入低功耗,发送指令后是有回复的我们可以等待回复,也可以delay 5MS
+ o# B- N# ~# I) ~& p7 \$ j- drf1609h_enterLowPower();* Y+ j, t. w8 h% S$ C3 C
- HAL_Delay(5);
( d# I, j A5 z8 b
复制代码 # E3 u. M3 J# @) ~
具体可以参考DRF1609H的说明书0 Y6 ?3 q! Q) u7 m
! E! |: n' r+ d1 u
2 m. u9 G- `8 ]3 ~
4 v& u& f* }: H; z1 s5 D, H
' h" u( |4 h% M+ k/ n2 s+ k ?0 y
" E+ g3 O2 O) Z" I2 N$ C
) a' [7 h8 n9 b# d7 V
; l8 [8 _4 L& V; P( ?( T/ t8 O# z* g; L0 ?$ P1 b) t
2.2,退出低功耗
, t& d* D3 @, j% o( r2 T( I退出是模拟下拉Function按键5MS实现
+ b m" ]8 ]" n) P, ?+ I3 d- drf1609h_outLowPower();
" N% a1 c+ A7 J9 d. d - HAL_Delay(5);
复制代码- //-----------------------3 c L* W2 m. v: k
- void drf1609h_outLowPower(void)
: s" e) p$ {" {+ B - {
, Z2 S! K1 B1 |0 h2 Z+ e - set_outLowPowerPin_outPut();3 H+ n! ]; m& v T) J5 F
- HAL_Delay(1);
" l# ]. u- w+ `4 r0 w/ E
! C# `6 T9 j# y- X4 Y3 }5 V- set_outLowPowerPin_out_1();
( ~4 N" ?; X0 _2 [9 t - HAL_Delay(1);& y. O) V3 E6 {- e' O2 Z6 \6 ?( N5 Z
- # \9 r0 A+ I: O5 t
- set_outLowPowerPin_out_0();
H3 O+ j: V( v( [, e - HAL_Delay(5);
. F; g R) U _+ x% k3 ]" L - 6 y: m% |$ p9 l4 R
- set_outLowPowerPin_out_1();
$ |0 _0 _- x7 J - HAL_Delay(1);$ s/ H. s, o% ~$ m7 S
- ( n- U2 j; E9 L6 q2 g
- set_outLowPowerPin_input();
$ a6 c0 r1 R( L - }
复制代码
; a8 i. I/ x/ o( |2.3,退出低功耗以后的数据传输( j: j$ u/ u# o: e3 s: J: _" G
DRF1609H进入低功耗以后,将不会自动更新路由路径,所以唤醒后用点对点发送方式,点对点发送方式会自动寻找路由,但是效率比较低,所以一般情况下用透明传输方式。% { m5 Y. e' g4 v6 @- i/ v7 @' _8 b
Coordinator的短地址永远是0x0000,即采用目标地址为0x0000的点对点方式发送。
V9 m' c( ~& j; R0 o* ^: O8 T& }点对点发送的官方描述是这样的:( |3 }5 o; {5 q4 N1 f+ Y
* S7 _% N# t! G
A, `% {# M) Q5 ^
! c- b# h. G" L- x5 }4 \
6 o; @) z* k. w4 u f代码实现为:7 ]. P* J. W/ F8 q! l! U
' g$ `" W6 {6 {8 R" `$ l; i7 B
- //--Send out the AHT10 Data as point-to-point transfer model -----
. j9 g$ {3 l5 N - set_lowpowerSendOutData();0 }1 y2 d' Q% n: y9 u; K5 M
- HAL_UART_Transmit_DMA( &huart1, lowPowerSendOutData, 8);1 Z5 m+ U/ @7 A9 \. h, }
- HAL_Delay(5);
复制代码- //----------------------
/ Z7 W* s, T2 R( k% G - void set_lowpowerSendOutData(void)
9 @7 Y' K( J) {0 X" M - {/ n1 W* Q! w- q6 I
- lowPowerSendOutData[4] = AHT10_OutData[0];1 Q6 k! K- \3 ~7 \9 M6 L
- lowPowerSendOutData[5] = AHT10_OutData[1];
$ X9 p n; {' x2 d0 H, G& G4 w+ } - lowPowerSendOutData[6] = AHT10_OutData[2];
) [$ Z" n4 G* r0 T - lowPowerSendOutData[7] = AHT10_OutData[3];
/ V2 w# B# A; E* r9 O - }
复制代码- uint8_t lowPowerSendOutData[8]={0xFD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
复制代码 3 A* }+ l; |' V ]
' q e3 f7 I7 m9 |$ I7 F* f Z& R B) M& L! \+ ]6 g3 b1 x
, w4 B# r; m4 f6 J' A
|