如果是定时上报温湿度数据的方式,我们可以将这个节点做成低功耗的,这样用电池供电,使用起来就非常方便了。, f$ |: h" B. Y6 c$ B$ M, O' U( c
低功耗实现有2个地方:/ l! s$ P1 u( |+ G
1,MCU本身的低功耗;5 @" w7 v" s' b& e. y8 X
2,DRF169H的低功耗;
8 Q% ~ L* f7 h# F- CAHT10的功耗非常少,我们这个是采用5号电池供电,基本上就不需要考虑了。 L) T$ B7 g- B" ]: j- N
项目做下来,休眠时大约电流是50UA,如果20秒发送一次,电池用一年基本上是没问题的。, g& a4 C8 z' h: a7 f! o' S
下面来分别简述下这2个方面的实现方法:
7 p$ r6 ?1 ~0 m8 T1 y- \4 D1 R" [2 E' R6 u
1,MCU本身的低功耗
& g' I1 }3 X v" _$ c f3 C" H/ Z8 sSTM32G0系列的功耗管理函数在这2个文件里面,是ST自带的库函数,实现起来非常方便8 Q: v+ T) l" D# A& U V
stm32g0xx_hal_pwr_ex.c
8 v' t* T( J/ ^! Q; Ostm32g0xx_hal_pwr.c4 q7 ^5 a/ W V' t; d ]
0 ?+ f$ `; I; \: P3 V具体的实现方法:
9 I, _2 W7 ^5 |0 O3 R1,关闭LED及设定DRF1609H进入休眠,设定DRF1609H进入休眠是串口发送指令给DRF1609H ^6 k, y8 Y+ k( T- w. ?4 l8 v& j. N
2,设定RTC中断时间,设定MCU进入低功耗8 \- D9 M+ k& M ]
3,RTC中断唤醒MCU休眠1 Z; \9 i+ p2 Z) j
4,唤醒后重新初始化MCU(包括系统时钟、串口、IO口、DMA)
/ H; e9 ?5 \0 O# k4 ?$ z( W, x5,测量一次温湿度数据
/ A" r2 Q4 a; R; [1 Y: N6 d6,唤醒DRF1609H,下拉DRF1609H的Function按键唤醒1 Q) ]. M! y/ y: y6 L Z* i
7,发送温湿度数据
1 w& f, k/ t3 A" x1 ^8,重复以上1-71 n* |6 t4 u4 g+ m. H
5 v8 ]4 f1 S6 q# b. i0 A1 p/ w- // --Enter Low Power Model -- //
7 S; ~$ I( M2 _9 c8 \" a9 k - LED2_OFF();5 L: z( K$ m7 y3 I6 w4 H" t5 @
- drf1609h_enterLowPower();
6 P. r% J( H8 d% Q6 X3 a- ` - HAL_Delay(5);
复制代码- //--Set wake up time = 0x500B = 10S ----! k, J& b* ]$ N7 Y/ v6 |6 v
- //--Set wake up time = 0xA017 = 20S ----
# n4 P( J8 z X1 z9 ~3 \1 K* j - HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x500B, RTC_WAKEUPCLOCK_RTCCLK_DIV16);" |) {5 o. E( \0 p; ^) w' N
- HAL_PWREx_EnableFlashPowerDown(PWR_FLASHPD_STOP);
8 e! L) Y3 X! t# f7 u5 ]) u z - //HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);. Z% k$ {5 o; \7 `7 O
- HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);
复制代码- SystemClock_Config();
0 L/ a$ t# t! n7 h - MX_GPIO_Init();( C Q& b# Q# w
- MX_DMA_Init();
6 i- f7 J0 B! S+ N& o - MX_USART1_UART_Init();
' ]% Q5 ]. S. I% z4 K5 m - . b, ]" G; @, q/ w* O( z* G
- LED2_ON();
复制代码- //-------------------, N6 m$ J! D( E q& l9 t
- read_AHT10_once();
复制代码- //--------------------
( D e7 K; R' e - drf1609h_outLowPower();
* A% J6 ^/ X% P M - HAL_Delay(5);
复制代码- //--Send out the AHT10 Data as point-to-point transfer model -----; x; ?7 I! s* f0 m. T. S
- set_lowpowerSendOutData();<div>HAL_UART_Transmit_DMA( &huart1, lowPowerSendOutData, 8);
; f0 h9 g. O! o4 \8 b - HAL_Delay(5);</div>
复制代码 . q. }+ G2 C2 I# D$ L5 ^
2,DRF169H的低功耗实现: U4 r+ u- h' q
2.1,进入低功耗7 X. b* q0 Y) V; Y8 `
DRF1609H只有工作在End Device节点下才有低功耗功能;) [9 A3 ~) X& V8 s7 A
发送指令,即可以使DRF1609H进入低功耗,发送指令后是有回复的我们可以等待回复,也可以delay 5MS
7 s9 O9 F ^' `8 c5 `3 G- U$ Z5 R- drf1609h_enterLowPower();
% G7 a! @3 s& d9 r' r - HAL_Delay(5);1 o, I) s0 s( t, i4 \/ T" U
复制代码
* u% q) A% k0 b. o8 h具体可以参考DRF1609H的说明书4 a! P5 d+ D! A; M1 o# ^. m
2 m* O' t. U. o8 E, s n
2 |$ H# j( @+ e) {9 }6 A2 K8 v* w- [# q5 K0 |) G% w* C2 B s" V
. c% r' l: Y5 X# `- u4 J
3 `# b" q+ b( k/ x4 S7 ?: n: Y* {0 X. m1 \
, R. D X; K4 |- r4 D' S' h+ R" I' G7 K8 \
2.2,退出低功耗/ ]$ r. B( n; {& f" T0 v, j
退出是模拟下拉Function按键5MS实现
& n' N6 `8 C7 v/ L7 _. ]- drf1609h_outLowPower();
$ k5 i9 J7 D9 }" I* k% ?* a$ V4 u - HAL_Delay(5);
复制代码- //-----------------------! @4 V8 F. L6 s3 S9 [3 A
- void drf1609h_outLowPower(void)
; F A! s P: @$ l - {
2 x$ v& ?0 S# t4 [ - set_outLowPowerPin_outPut();2 h- V$ ]7 n8 e8 F" b6 ~
- HAL_Delay(1);
9 N) p7 Q1 h% @4 t1 c7 L3 ^ - ! h2 d: r8 o* R8 H
- set_outLowPowerPin_out_1();! `5 z& k8 m% Q$ c
- HAL_Delay(1);
3 p9 V+ j* N0 S+ t8 A6 U
) |; x: Q* T7 L1 `% M6 M( @- set_outLowPowerPin_out_0();
9 U9 a% y4 j2 `$ C" [ - HAL_Delay(5);" n1 o% o( M& U* O% C/ n3 T* ?
4 A p# s! I, J2 Q5 g3 d- set_outLowPowerPin_out_1();% K* H& X3 F: L
- HAL_Delay(1);0 P( E. f0 Z& G% K7 y
* j& H5 G1 M y- set_outLowPowerPin_input();. Y% U1 ?8 {+ c2 W# A
- }
复制代码 $ `+ |5 z! T2 m1 G- T" G, h
2.3,退出低功耗以后的数据传输9 l' L5 p4 v: u6 q
DRF1609H进入低功耗以后,将不会自动更新路由路径,所以唤醒后用点对点发送方式,点对点发送方式会自动寻找路由,但是效率比较低,所以一般情况下用透明传输方式。1 G6 ~7 C/ q: }2 `# r4 y7 V. n
Coordinator的短地址永远是0x0000,即采用目标地址为0x0000的点对点方式发送。) Y# v* `. J2 [9 L1 _
点对点发送的官方描述是这样的:* M- u$ K' `6 R& r: _7 T' r
4 _4 m) \ p. S. H& |6 @
2 t; Z6 O/ b G- q1 x" ~/ ^) o6 B8 n9 E8 Y+ i2 o3 M- @
- D9 d5 \1 C6 |7 y* _' d" n代码实现为:0 y3 D, ~' t( H9 T
: {% Y3 P: p G& @6 Q: F7 v7 o) O
- //--Send out the AHT10 Data as point-to-point transfer model -----! @3 g/ U: t- ~6 b
- set_lowpowerSendOutData();3 ^7 [+ R% L4 j5 U1 P4 }% g& R% q
- HAL_UART_Transmit_DMA( &huart1, lowPowerSendOutData, 8);
7 K! h% G) z& d# k( u0 B M# { - HAL_Delay(5);
复制代码- //----------------------2 a$ E2 y$ c s J& F" C
- void set_lowpowerSendOutData(void)
' j. [' V5 U! q4 a+ E/ a - {# C: ~) Z+ W/ ?& j
- lowPowerSendOutData[4] = AHT10_OutData[0];8 U# ^8 |* g9 s2 J# y& M" _
- lowPowerSendOutData[5] = AHT10_OutData[1];- F4 M( L- H7 x0 o( k# o# C
- lowPowerSendOutData[6] = AHT10_OutData[2];" c: l% Q0 _: g# e6 Z( l2 H3 Y+ o
- lowPowerSendOutData[7] = AHT10_OutData[3];
: |9 w# M2 m1 p' Z - }
复制代码- uint8_t lowPowerSendOutData[8]={0xFD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
复制代码
5 f. ^* q- G' i: K. O- x- K3 W" V7 ? I; r, T) K5 B
$ k. Z+ L, h* t" p% ?
; v. Q: A3 V) I+ L4 [
|