如果是定时上报温湿度数据的方式,我们可以将这个节点做成低功耗的,这样用电池供电,使用起来就非常方便了。
/ O4 @( c' |- ~' ?" C低功耗实现有2个地方:% p0 \8 V7 T% w- N) R, r
1,MCU本身的低功耗;
9 P: H& W' G/ d6 h2,DRF169H的低功耗;
; @& {4 r6 @2 \/ S2 K6 [- _/ R9 |AHT10的功耗非常少,我们这个是采用5号电池供电,基本上就不需要考虑了。 M+ _+ G- r+ @) G# m+ p+ F
项目做下来,休眠时大约电流是50UA,如果20秒发送一次,电池用一年基本上是没问题的。
, i% g M3 ]+ A9 n% ~下面来分别简述下这2个方面的实现方法:5 \+ F8 f, ? L/ I
- _2 S( a8 Z* B' Q! W; W! _4 N, ?- P
1,MCU本身的低功耗$ T& n) b, | T0 w
STM32G0系列的功耗管理函数在这2个文件里面,是ST自带的库函数,实现起来非常方便6 j' W2 [' S0 T1 L1 A, U
stm32g0xx_hal_pwr_ex.c0 h9 L8 O7 E, N& _% W1 A
stm32g0xx_hal_pwr.c" D+ `: s, y' v, W0 ]2 N6 o$ I: L
7 l& Y3 n7 H& W$ U
具体的实现方法:5 L6 P# v: m/ ~0 y; U( ?6 C
1,关闭LED及设定DRF1609H进入休眠,设定DRF1609H进入休眠是串口发送指令给DRF1609H
& B7 q3 j( s! a2 }& s# D2 E2,设定RTC中断时间,设定MCU进入低功耗
$ u( U. P" n& ?7 _6 G3,RTC中断唤醒MCU休眠6 ~7 j& U: ~* c' R( b+ @' y& A
4,唤醒后重新初始化MCU(包括系统时钟、串口、IO口、DMA) x* F d6 B8 D, w7 R
5,测量一次温湿度数据4 z2 G) E! u' @" |. O
6,唤醒DRF1609H,下拉DRF1609H的Function按键唤醒
5 x6 ?' k( z6 ]( |. f1 c7,发送温湿度数据
/ q5 c- {0 ?6 z! j8,重复以上1-7
0 W5 P/ m4 B, W
; j) V% A8 R% o$ _- b& A- // --Enter Low Power Model -- //
# ^2 s% j' A( g# c8 \8 v$ r$ m$ S - LED2_OFF();
+ S3 V8 x, O6 p2 M - drf1609h_enterLowPower();
3 i( R, z, T& K9 x* x - HAL_Delay(5);
复制代码- //--Set wake up time = 0x500B = 10S ----
/ R+ ^3 Q$ x t5 R* j - //--Set wake up time = 0xA017 = 20S ----: E9 g. Q2 e9 C8 i% c
- HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x500B, RTC_WAKEUPCLOCK_RTCCLK_DIV16);6 N4 M* X ]: ^% r& C( Y
- HAL_PWREx_EnableFlashPowerDown(PWR_FLASHPD_STOP);
# b/ @, T7 L* D+ z' k9 e - //HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);! R& I0 A7 @6 C: O" P. s- ~% v
- HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);
复制代码- SystemClock_Config();
" d7 I1 ^- j1 d3 I$ c0 P - MX_GPIO_Init();! |- K4 Z) ~9 b
- MX_DMA_Init();5 P: [# @) Z) q5 ?% E; k% g
- MX_USART1_UART_Init();
" ~& ]* Y9 A% D2 Z! v
5 A- j. Q* L8 J' h4 r+ a. N- LED2_ON();
复制代码- //-------------------8 K3 s' m+ v! ~+ t6 g6 a
- read_AHT10_once();
复制代码- //--------------------
8 _" ~0 F, ]6 W# }) _4 U - drf1609h_outLowPower();
0 d: E& ]+ v$ ~- Y4 q - HAL_Delay(5);
复制代码- //--Send out the AHT10 Data as point-to-point transfer model -----: P+ p" [. E u6 |
- set_lowpowerSendOutData();<div>HAL_UART_Transmit_DMA( &huart1, lowPowerSendOutData, 8);8 b( z: D: i) B2 W' t- G
- HAL_Delay(5);</div>
复制代码
% b0 b0 m# l- F9 k" K+ o2,DRF169H的低功耗实现
5 b9 {& ^- [8 J2.1,进入低功耗
; Y' t/ v1 m z' J4 _ sDRF1609H只有工作在End Device节点下才有低功耗功能;5 Y: U) X# \. R- `( j
发送指令,即可以使DRF1609H进入低功耗,发送指令后是有回复的我们可以等待回复,也可以delay 5MS
: s+ }7 Q( V! v) q! }, v- e! s. I- drf1609h_enterLowPower();. o9 M: }* n/ [" ]; ~6 e
- HAL_Delay(5);
9 \* N) l9 C, |0 ?" q' N' g
复制代码 / q/ y- C( Y0 Q7 e
具体可以参考DRF1609H的说明书
L, L8 n2 p$ Q8 g+ T
8 C$ o& q; n: W( a# @3 q6 M3 [, e. F9 ]8 s- o( F4 G
" |0 b8 G8 j* i3 I, U4 |$ U7 Q
. a* u; k, N2 }0 t3 J2 J: T8 A9 D' _) J- D
/ ]9 {$ |: h) P
: G- G- I" ^# b5 v/ ~
6 p; @7 ]/ J. W* L9 `" R2.2,退出低功耗8 _ y0 d/ {( ~; y
退出是模拟下拉Function按键5MS实现
% Z3 m7 R7 y; E5 A1 n, j3 M- drf1609h_outLowPower();
5 _3 p7 P5 M7 C. E* `* D9 i - HAL_Delay(5);
复制代码- //-----------------------
, k$ v/ ^% m8 O8 p - void drf1609h_outLowPower(void)
4 h/ F) q9 n3 O/ A$ h T - {
! D3 O; r) U6 |: H0 ~/ G+ _ - set_outLowPowerPin_outPut();
. d. q0 z( {. k U" D9 e( U - HAL_Delay(1);: e1 z- Q E- E% T! N2 j, D0 Y% M) |
& i+ S# j. J- S+ \1 E- set_outLowPowerPin_out_1();9 m" a/ A) z# K
- HAL_Delay(1);& h4 H2 g; ?& F2 J: A$ {
% L, B; X( l$ K. x f* `3 u- set_outLowPowerPin_out_0();
; T& `' n+ M. u/ } J - HAL_Delay(5);
- \' B# Y! B& N/ K' m) j5 N - 7 T' ^+ \5 x3 @& o% k" M) R4 y
- set_outLowPowerPin_out_1();1 ^, L6 t2 x% I/ g3 G
- HAL_Delay(1);
) L4 b0 O, B! @ L( G, z5 o
) [- R' y* ~: R1 n' _- set_outLowPowerPin_input();- K5 S$ R( Y7 N( v& }$ p
- }
复制代码 + |5 j- e3 K, N
2.3,退出低功耗以后的数据传输( @' ^* H6 y0 o* ]3 z f! A
DRF1609H进入低功耗以后,将不会自动更新路由路径,所以唤醒后用点对点发送方式,点对点发送方式会自动寻找路由,但是效率比较低,所以一般情况下用透明传输方式。6 [" T4 E% V% K& g9 J: t$ q6 o' p# l
Coordinator的短地址永远是0x0000,即采用目标地址为0x0000的点对点方式发送。9 q# W, G. J( ~* n; p/ l
点对点发送的官方描述是这样的:$ V: ~5 e& J; F/ j7 E- r/ d8 B
2 }# o+ F6 X& e4 W5 O
# ^# l7 S( }: D9 H3 T ?% }% ~, g3 T) O& A6 }
7 c& [# `! D4 X
代码实现为:$ d3 w7 n8 ~" d+ {9 u( j
1 M; ?, X4 n: t( S3 `
- //--Send out the AHT10 Data as point-to-point transfer model -----
1 c# Z! q* ?3 h! t8 w- n2 j, s - set_lowpowerSendOutData();+ G8 M( t+ x3 f4 F0 v* h
- HAL_UART_Transmit_DMA( &huart1, lowPowerSendOutData, 8);
; k/ s3 v- Q1 G - HAL_Delay(5);
复制代码- //----------------------
5 B8 k# ]3 M7 e6 {0 o) \5 ` - void set_lowpowerSendOutData(void)
0 e2 @+ |: o: r5 b+ F) C' G - {* E9 l/ t) v6 N
- lowPowerSendOutData[4] = AHT10_OutData[0];: l$ M( J9 d8 L' ~- f
- lowPowerSendOutData[5] = AHT10_OutData[1];9 w* `- |5 t) V0 W, n+ {
- lowPowerSendOutData[6] = AHT10_OutData[2];+ x4 n8 L+ z$ w. N% o
- lowPowerSendOutData[7] = AHT10_OutData[3];
8 U# ?. ~, _0 Y3 @. g" c6 H) F - }
复制代码- uint8_t lowPowerSendOutData[8]={0xFD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
复制代码
0 P3 k5 _- U/ W) N& y# n1 `/ |' G3 X7 d6 G( H# n: B$ ?/ ?
( s3 z. w0 e4 U# E+ q2 {" ^! t
$ ]" a/ c, N: z9 X! Y2 f0 A) x7 E( a- i2 Q |