如果是定时上报温湿度数据的方式,我们可以将这个节点做成低功耗的,这样用电池供电,使用起来就非常方便了。3 I6 U$ [4 K \
低功耗实现有2个地方:
( v+ b o; C" u) U1,MCU本身的低功耗;
6 ^+ n7 Y6 ?! ]- X2,DRF169H的低功耗;
4 v' d7 J3 }* }. EAHT10的功耗非常少,我们这个是采用5号电池供电,基本上就不需要考虑了。7 d: P; s9 c2 S5 _4 {
项目做下来,休眠时大约电流是50UA,如果20秒发送一次,电池用一年基本上是没问题的。
) g+ t6 P$ T, O- F9 }5 ~% J下面来分别简述下这2个方面的实现方法:
1 p) x' r7 p6 I8 J2 E4 p+ B. e( }4 K/ P C1 {
1,MCU本身的低功耗# q- Z' f1 [( ^ \
STM32G0系列的功耗管理函数在这2个文件里面,是ST自带的库函数,实现起来非常方便
( }! m( D# K. j- V3 Fstm32g0xx_hal_pwr_ex.c
# t5 R; e4 P4 s& P0 Wstm32g0xx_hal_pwr.c- v9 _5 \/ p( J M
% F- Q4 g- q; z$ N+ ` \具体的实现方法:7 P8 ?) G$ t, d) P
1,关闭LED及设定DRF1609H进入休眠,设定DRF1609H进入休眠是串口发送指令给DRF1609H* H6 P% `9 ]: w m" e+ I
2,设定RTC中断时间,设定MCU进入低功耗
! Y7 c2 b K; _& s% N3,RTC中断唤醒MCU休眠" l7 x& O& S2 L, ?
4,唤醒后重新初始化MCU(包括系统时钟、串口、IO口、DMA)
( F, C; X# q% x/ G s* k% E& J5,测量一次温湿度数据
) B/ y# y1 x; a. }6,唤醒DRF1609H,下拉DRF1609H的Function按键唤醒6 H8 `7 i" p; ?' y8 {
7,发送温湿度数据
; `. s* i o- K% S* f8,重复以上1-7+ v; j; M- J4 k5 L& C) i+ t- h1 L/ q
) [, t% f% R! d- // --Enter Low Power Model -- //: h: j, r. `# P
- LED2_OFF();7 A1 h& `' f" ]. R
- drf1609h_enterLowPower();3 D$ E4 T( S3 r
- HAL_Delay(5);
复制代码- //--Set wake up time = 0x500B = 10S ----4 F3 c0 g4 J& O" ?4 X# }4 ?
- //--Set wake up time = 0xA017 = 20S ----; K4 d; Y8 P# t2 a, _5 i
- HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x500B, RTC_WAKEUPCLOCK_RTCCLK_DIV16);0 P. Z% O6 j/ f, b3 f2 z) y
- HAL_PWREx_EnableFlashPowerDown(PWR_FLASHPD_STOP);
d; j9 `: ~. F! ]6 T6 V: j - //HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);$ P4 E" e* d; H' I' N/ ]
- HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);
复制代码- SystemClock_Config();2 ] h+ U: a1 w7 g
- MX_GPIO_Init();5 g2 Y/ ~5 d3 g$ t! @
- MX_DMA_Init();
+ w% t5 r( Q+ k- l* F# g0 M( \5 { - MX_USART1_UART_Init();! P* Q& I- V+ x. a5 _
y; q( d, |6 }: |( a0 K, ~- LED2_ON();
复制代码- //-------------------3 _/ g" E6 z8 j
- read_AHT10_once();
复制代码- //--------------------
p# ^4 ^+ V: q; `- U/ A - drf1609h_outLowPower();% ]7 \3 R9 w) u- Y9 [5 b
- HAL_Delay(5);
复制代码- //--Send out the AHT10 Data as point-to-point transfer model -----* S: z4 b) y. C+ v4 ^5 x
- set_lowpowerSendOutData();<div>HAL_UART_Transmit_DMA( &huart1, lowPowerSendOutData, 8);
4 ]; S! ^5 S+ ~- S - HAL_Delay(5);</div>
复制代码 - @% D! Y$ \& ^" i9 w- d! w
2,DRF169H的低功耗实现
3 _; }) O3 H+ e( W3 }2.1,进入低功耗
. x4 |9 J* M2 G1 I. c; i- l& nDRF1609H只有工作在End Device节点下才有低功耗功能;
) B ~! Y, W8 b2 r% V发送指令,即可以使DRF1609H进入低功耗,发送指令后是有回复的我们可以等待回复,也可以delay 5MS6 O8 c, V0 h5 T5 P. l
- drf1609h_enterLowPower();
" ^8 Z- B8 B7 l+ h5 q - HAL_Delay(5);1 P/ z) d$ N% r
复制代码
5 B" ^& A+ b3 S8 k- S) f具体可以参考DRF1609H的说明书5 W/ x! j& G4 z
. B4 @7 z2 |# v( x
) e7 ]5 M7 f. i9 N$ U. y5 h, i
! o4 F0 W2 V3 B/ ?
3 e2 x* w0 t( r. v/ Y# `, a7 k9 {; O% o4 j1 Q2 Q! }) U
- D/ J' |" O- o9 @. ^$ h
/ I b x8 ]+ S: O# l+ K/ ^6 w2 W( u2 ]8 r& [* I
2.2,退出低功耗2 i K2 F- s8 d4 `5 y3 w/ u
退出是模拟下拉Function按键5MS实现
* B; e& {0 Y! g" E3 I! |" ~% _- drf1609h_outLowPower();* f; }6 C x( }) T* W. B
- HAL_Delay(5);
复制代码- //-----------------------
; [+ E) M; r$ h! D0 x2 _; H7 J5 W2 X* M - void drf1609h_outLowPower(void)+ l/ S, K6 d& |5 m/ E* V3 |
- {
8 A, G" ~2 P; _2 C" y; i - set_outLowPowerPin_outPut();
; W! x6 P& \5 ?% v( d& K4 L - HAL_Delay(1);+ \% n* x! Q T& A0 r! j `
0 v! o, ^& A5 n" B7 x6 W8 K% I- set_outLowPowerPin_out_1();
3 K! n; T& ?& r: S; d. s - HAL_Delay(1);
$ ~0 s8 l; l) ^* g - $ i" s8 j" x: Q. q; X
- set_outLowPowerPin_out_0();$ c8 V/ k9 ?. p: z; o
- HAL_Delay(5);
7 f- m& M! b [3 ^
2 k5 G& ^2 M# c- set_outLowPowerPin_out_1();
$ n9 r7 q" @$ |# M! A, E - HAL_Delay(1);
e: ]- G. u+ o
1 h8 B1 g7 ]/ t- set_outLowPowerPin_input();
4 S& k# N0 D& h - }
复制代码
. {* ]7 ?+ R0 R% x2 k0 e7 k2.3,退出低功耗以后的数据传输1 m* n5 ~6 D: ^6 ?* k% B2 F/ J `
DRF1609H进入低功耗以后,将不会自动更新路由路径,所以唤醒后用点对点发送方式,点对点发送方式会自动寻找路由,但是效率比较低,所以一般情况下用透明传输方式。
" v* i- b z& v3 R/ l" }% S# l4 HCoordinator的短地址永远是0x0000,即采用目标地址为0x0000的点对点方式发送。! \3 L6 Y" ?; A
点对点发送的官方描述是这样的:8 ?" S/ t- R! G- p
: x8 d4 s p3 J+ q1 ?6 [6 n* N
: i/ r3 b2 q* G. I8 t0 c3 [
$ o$ m5 m3 C, i9 [8 u
! @4 |$ O7 F% m- w3 {6 T% q
代码实现为:
4 Q1 |% C0 {1 h' p9 N
) c% [4 ^* ]$ z/ f- //--Send out the AHT10 Data as point-to-point transfer model -----) o3 p6 b+ C8 b& M$ x! B
- set_lowpowerSendOutData();( e4 H: k. J/ s4 T" Y( w h+ j
- HAL_UART_Transmit_DMA( &huart1, lowPowerSendOutData, 8);( O+ y4 H! }, _/ P0 S7 h+ O
- HAL_Delay(5);
复制代码- //----------------------" a& h& D: h) O/ j# J
- void set_lowpowerSendOutData(void)8 }: b6 T( ~# K- T% ]! h0 ]/ n' V3 T
- {1 ~3 \2 p' j9 c1 n$ \/ q; Q
- lowPowerSendOutData[4] = AHT10_OutData[0];$ f, |7 x" |" E% W2 Y* n+ V h7 _
- lowPowerSendOutData[5] = AHT10_OutData[1];
0 r) T- D% P# n; A( k - lowPowerSendOutData[6] = AHT10_OutData[2];
1 ], S; R. g0 F" ]/ n - lowPowerSendOutData[7] = AHT10_OutData[3];
3 }& ]. [" u3 K4 A1 I" a - }
复制代码- uint8_t lowPowerSendOutData[8]={0xFD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
复制代码
; j) J9 t$ x* P$ q* U, @/ P. j4 N+ C( {8 U! ^
. f) Y) r' [) C+ P- b+ [0 d4 Z; O- D& W
|