如果是定时上报温湿度数据的方式,我们可以将这个节点做成低功耗的,这样用电池供电,使用起来就非常方便了。
! v9 B1 |' q/ v# L! l9 B) h, F7 g0 {低功耗实现有2个地方:, a+ {& Z, j0 H! e
1,MCU本身的低功耗;* m" i" c- \0 ?6 d! b0 k. v
2,DRF169H的低功耗;, Y( [& |. @! O% k$ u, j
AHT10的功耗非常少,我们这个是采用5号电池供电,基本上就不需要考虑了。& b6 I3 K' e! o* [1 k: h7 L
项目做下来,休眠时大约电流是50UA,如果20秒发送一次,电池用一年基本上是没问题的。
: _/ C/ a8 f: z0 o7 ^0 ?: E4 z下面来分别简述下这2个方面的实现方法:: V% X4 ]1 k- w
8 e2 s V4 _! T* U' u! w1,MCU本身的低功耗- U5 [# L8 C- M& t* n- f% s
STM32G0系列的功耗管理函数在这2个文件里面,是ST自带的库函数,实现起来非常方便$ B: o+ |& E, F& |$ }; W
stm32g0xx_hal_pwr_ex.c
, l8 n" t+ X! y9 H/ u8 fstm32g0xx_hal_pwr.c
2 O: C, L/ ^( e+ ]% L+ ]- @9 v' h
! K8 ?% f8 p7 O! {具体的实现方法:+ b0 R4 X& ?8 H1 Z: A# }4 W2 }
1,关闭LED及设定DRF1609H进入休眠,设定DRF1609H进入休眠是串口发送指令给DRF1609H- a* C: n* d% g% ~# L1 t
2,设定RTC中断时间,设定MCU进入低功耗
7 f) u8 f- z- w3,RTC中断唤醒MCU休眠" z( y; D" _, d$ M( v2 `
4,唤醒后重新初始化MCU(包括系统时钟、串口、IO口、DMA)# d. m. G3 M+ c& G$ z
5,测量一次温湿度数据
- @3 F1 T0 O! S; t6,唤醒DRF1609H,下拉DRF1609H的Function按键唤醒
8 ~4 @; [7 {, {6 b6 \; a! r( I7,发送温湿度数据
6 i- d/ O" C/ o( T% S8,重复以上1-7
+ q' Z/ q" h- j" Y* f
/ }$ ^, k& B. C( Q- // --Enter Low Power Model -- //7 r) N8 q, _. N; ~
- LED2_OFF();
7 X' a; u% H" \3 |- B$ }$ A/ O - drf1609h_enterLowPower();
8 D. o; h! f! z+ G* W - HAL_Delay(5);
复制代码- //--Set wake up time = 0x500B = 10S ----& L/ C: ? ~: t- A
- //--Set wake up time = 0xA017 = 20S ----
4 p+ u( n# k) A; ? - HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x500B, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
# a% w6 A, Q/ f" d - HAL_PWREx_EnableFlashPowerDown(PWR_FLASHPD_STOP);
1 C# O- W9 S0 ^9 h- n - //HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);8 l1 a @3 S5 i* f
- HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);
复制代码- SystemClock_Config();# y5 E$ ]3 L4 g9 D3 M2 x
- MX_GPIO_Init();
+ a' v; S. A Z O8 H& F - MX_DMA_Init();2 w4 i4 g$ v3 X) {3 |$ Z! t% }
- MX_USART1_UART_Init();8 p3 L4 [" m! Q; J! D f0 x
- $ ?4 v! U: s/ b1 K) `
- LED2_ON();
复制代码- //-------------------
6 X# a/ _: i* C8 u - read_AHT10_once();
复制代码- //--------------------
8 D0 G, @' w* V8 o( i - drf1609h_outLowPower();
/ D. H8 C! T1 _; t, T: W( { - HAL_Delay(5);
复制代码- //--Send out the AHT10 Data as point-to-point transfer model -----7 Z: d$ b) x: n! d ~! W
- set_lowpowerSendOutData();<div>HAL_UART_Transmit_DMA( &huart1, lowPowerSendOutData, 8);
' n3 i2 X! B8 u' g& f - HAL_Delay(5);</div>
复制代码 . N: T/ ^; s# y9 Q
2,DRF169H的低功耗实现% j4 N- b+ o# S. M5 ]# W* p- K
2.1,进入低功耗
! i+ B, }1 y) F* ?; NDRF1609H只有工作在End Device节点下才有低功耗功能;( r1 U7 B6 t, Q0 X i
发送指令,即可以使DRF1609H进入低功耗,发送指令后是有回复的我们可以等待回复,也可以delay 5MS) n0 V, m4 D4 O$ x& {# b
- drf1609h_enterLowPower();& W+ ^( y! D+ |) ]( F* U
- HAL_Delay(5);0 z# _ V: }& R4 t
复制代码 4 t" A: U: n5 I) m
具体可以参考DRF1609H的说明书
2 e a' \+ E I$ O* i& a+ C% D
+ D+ j2 S. d6 [4 b+ k
7 ]8 J3 k0 w$ b; Z5 [' n
9 f8 E4 q% D* w; t2 L; |! r1 [
5 y* f Z% x3 D% ~0 a! r
6 [) S4 `3 B$ L; N$ `! U' X/ K" \/ l$ v. Z' a
) {; `9 u; z5 k9 ]/ M
4 \1 p. A5 ]+ D0 b9 ~2 c8 ^
2.2,退出低功耗2 g& A/ K6 s1 I1 M; B, S+ p) c8 d
退出是模拟下拉Function按键5MS实现8 E) m! Z2 f! W+ @1 j
- drf1609h_outLowPower();$ ~( h- j9 K" S- Z. V
- HAL_Delay(5);
复制代码- //-----------------------, L4 C" a1 [% ^( ?* \! t& R* q' i6 A7 _- C
- void drf1609h_outLowPower(void)" I+ L# o1 U6 R
- {* Q0 R- d& H& T' w( p5 `% A& Q
- set_outLowPowerPin_outPut();7 W, a- g" g+ |0 B1 h
- HAL_Delay(1);
! l( v2 D; d; @% t( F. n) ` - 4 u! ~8 D" C* `2 e' @
- set_outLowPowerPin_out_1();/ d. A1 f9 o3 l6 E
- HAL_Delay(1);
4 t! R: `# X; U0 m& L - 5 {: V% Y8 [6 A7 R$ G
- set_outLowPowerPin_out_0();
+ ^8 \6 a9 Y3 h# ^( q - HAL_Delay(5);
) s1 e' L/ W6 S( i8 u
# r9 w0 {8 n0 t4 [- set_outLowPowerPin_out_1();
! R( |9 ^. H3 V. w: e - HAL_Delay(1);" E7 d0 e$ [% E0 Y( P
- A# [0 D2 S7 F2 h' N
- set_outLowPowerPin_input();
0 V5 V7 h1 X1 ` G0 n" A' M - }
复制代码
0 P$ l, ]# X% F& u2.3,退出低功耗以后的数据传输# y1 E. U; R+ M: ]
DRF1609H进入低功耗以后,将不会自动更新路由路径,所以唤醒后用点对点发送方式,点对点发送方式会自动寻找路由,但是效率比较低,所以一般情况下用透明传输方式。* ]6 u: b2 J3 q# e! x& R; Y8 s* |5 t
Coordinator的短地址永远是0x0000,即采用目标地址为0x0000的点对点方式发送。
, j# N% n7 g7 }0 M' X$ e) h点对点发送的官方描述是这样的:. D- w$ \# ?( j8 b p( C# M
. U0 f; O4 X) {' ~
4 o Q$ g: T/ [# w Z
( I( U) g1 S6 H8 F$ d# O" n3 M
# f5 u! \, C' s+ b a4 _: A# r代码实现为:; \3 I+ K! D. C# o
0 t6 o6 @( v# @* v9 X& ]. J- //--Send out the AHT10 Data as point-to-point transfer model -----# b; q# t; H# z# d
- set_lowpowerSendOutData();) G4 y0 B$ W% ^( {5 o0 D
- HAL_UART_Transmit_DMA( &huart1, lowPowerSendOutData, 8);6 [) |7 j3 l# Z: ^- }& Y
- HAL_Delay(5);
复制代码- //----------------------
2 i* E( p6 m3 Q4 H; E2 e* m - void set_lowpowerSendOutData(void)% y& r* ^1 d, p- g
- {
/ m) |+ i. P! }8 \ - lowPowerSendOutData[4] = AHT10_OutData[0];+ G, ?3 j2 s1 o% m% o
- lowPowerSendOutData[5] = AHT10_OutData[1];6 C3 ^6 a5 I- v$ k2 E$ R
- lowPowerSendOutData[6] = AHT10_OutData[2];& I$ v/ c$ t8 ^, z# R: m( `
- lowPowerSendOutData[7] = AHT10_OutData[3];# y* B4 o1 X: J
- }
复制代码- uint8_t lowPowerSendOutData[8]={0xFD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
复制代码
2 f+ K* a0 A1 X- d H4 i0 v' j+ h) s: @. @( k0 U# v3 [1 _: H
2 J+ [$ w* S3 V" f! Q( d
* l1 ?8 z$ m4 ]( b& f. w
|