本帖最后由 zhdzhd-174422 于 2019-2-27 20:14 编辑 : R% k+ }4 t: t: Y$ y0 D+ g/ L
5 Q# y$ Z* L4 M8 S) \7 ^5 b3 Z
AWU是用来当MCU进入低功耗的活跃停机(Active Halt)模式时提供一个内部的唤醒时间基准。该时间基准的时钟是由内部的低速RC振荡器时钟(LSI)或者通过预分频的HSE晶振时钟来提供的。STM8S的LSI时钟测量在使用LSI低速内部时钟时,为了确保最好的精度,它的频率可以通过TIM1_CH1来测定。
4 M5 w6 X: Y5 E
- F% Z. N+ K( a; f! X+ L& p1、复制官方AWU工程文件:
0 e9 x8 f( B6 M* i5 b
j+ f7 V6 H2 b/ [- S2 ?" G) l9 b5 l7 A
2、打开IAR工程,先清除上一工程的编译信息:
" R F( ?3 d0 N9 D/ e' D0 ^
& c+ [0 y+ K4 \1 K
2 z3 Y3 I7 U& t: v2 s. A8 k2 H3、修改main.c文件:- /* Includes ------------------------------------------------------------------*/
% Y8 C. }6 f/ W/ b4 P! q - #include "stm8s.h" \9 g v- e8 B1 r) X- i3 ]
- #include "main.h": U4 a4 R) A$ q3 \# R+ v
" F) |, N9 Q* `+ B T- 4 D9 u7 i. I% }: v7 L
- /**
# I% V+ @6 j6 o& h9 X - * @addtogroup AWU_ActiveHaltMode
; g, U g d$ A- r7 C8 [ - * @{8 U6 ?7 {. g! R9 K" Y) \3 f
- */
! l i, s/ A( b7 U8 N9 [ - : G7 S4 }5 W' O G
- /* Private typedef -----------------------------------------------------------*/
7 F- R; j7 P3 T [ - /* Private define ------------------------------------------------------------*/7 @4 d7 B$ {1 i4 K6 H
- /* Private macro -------------------------------------------------------------*/
3 X( t- B; x; Y! V' w- ^& b2 e/ A% C - /* Private variables ---------------------------------------------------------*/- A D x) a) z9 f( b5 p
- /* Global variables ----------------------------------------------------------*/: h! Q" ?/ |- m
- bool ButtonPressed = FALSE;
; Z+ G0 C/ W+ [1 A7 s6 ?, P/ g4 r - /* Private function prototypes -----------------------------------------------*/4 H7 B. T+ W* C9 P# R1 s4 L
- void Delay (uint16_t nCount);8 m+ n' o# R, g( ~0 c+ ]2 B" |
- uint32_t LSIMeasurment(void);
0 K) K# V' c5 B: L1 {" w5 D5 j - static void CLK_Config(void);
1 m! i' k- ?4 c9 }+ U+ m - void AWU_Config(void);
+ F" J) @# a. y - static void GPIO_Config(void);
# n0 G4 B6 `8 |6 w
' q8 P) x& a4 z( b) a7 y1 Q- /* Private functions ---------------------------------------------------------*/
+ |7 Y i7 o6 J# c) D - % F" ^2 F/ G- Q$ C+ w; V+ I# C
- /**
8 l4 Z# a) `$ G: R4 j- I - * @brief Example main entry point. J3 Z" [( U& `1 Q. ^- _2 T5 M
- * @param None* o3 U% G0 K* J5 v6 q* j: i
- * @retval None
" x' a: X$ |1 S# Q0 g; J - */2 G; _+ t$ {# f1 O) ~2 @& C. m. {
- void main(void)
/ b5 H5 |# C% u* g* e( w0 Z - {
* j3 G J- L: p5 D- F* h7 r4 h" c - uint16_t i = 0;
, _1 x& u4 v5 M( p8 P! `. @ - uint16_t j = 0;
m0 R' M/ y0 S' [3 E: v' I+ h! e - ! K' E1 k. D- \% j4 b E+ Q; J
- /* 时钟配置 -----------------------------------------*/
" V+ X) O% ?% m5 h0 c: Y - CLK_Config();
; e! `7 n9 K' [8 g4 i -
9 V t0 E! Q' b! v - /* 端口配置 ---------------------------------------*/$ t# v% Q2 s" C6 N6 c( c
- GPIO_Config();
( E( }, F( ?& I: \ -
+ r6 C/ |+ k; J. n# h" m2 Q+ Y - /*AWU配置 --------------------------------------------*/& O0 ^1 X1 B- m$ r0 K/ H
- AWU_Config();7 |0 Q! w/ ~: ]$ H
+ B, L) V1 r2 G: D- /* 使能总中断 */
! _9 D% k# n5 W1 O - enableInterrupts();# [9 ? t: X) A! B, d
- 3 B- ~. I& @8 c- a% D ?' i
- while (1)+ v9 F3 h+ T9 k. G. p
- {& R1 }4 l8 |% [7 ]& \* [3 B$ w
- /* 按键扫描 */; z( U2 C; K. _9 n
- if (ButtonPressed == TRUE)* v' @# ?" ^$ |
- {
2 k' t8 j& ]6 T' y6 A
+ V7 ?6 t+ m, E* U, f _/ A7 d- ButtonPressed = FALSE;
8 W/ v# |$ F3 Y$ j* L* q. _ - 0 c6 ~/ D# E# M4 h( U" T
- /* LED快速闪烁 */
3 C: _, U1 O) V: D - for (j = 0; j < 20; j++)
p: t" w$ g5 n- L; R/ x - {
5 ^) c4 [1 \, R2 |$ u' ^, J - GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);1 {; N# O+ D2 q7 X1 d% m
- for (i = 0; i < 5; i++)
# C$ p! ?- ]* r' t5 A, @8 t$ F! f- T - {
$ f% ?7 [4 A6 {, O# w8 d b - Delay((uint16_t)60000);
" I! m s& o( P) r+ @/ J - }. o! q2 \; Y4 ]& y: C
- }
0 x/ z$ W, K" i9 f$ K
) R7 j6 t6 R/ M7 B8 k& a4 d$ ~- /* LED熄灭 */. |2 n1 G3 T$ J, o9 C' V1 i
- GPIO_WriteLow(LEDS_PORT,LED1_PIN);
( E8 {' [ ^0 F7 D4 B - /* 进入停机模式 */
6 D% y8 O- ~ e - halt();
+ I9 |; Y: w& Q3 o1 Q - }! ?* o7 [" t2 |. N: j
- else# Z1 R, Z$ Q! m4 X
- {( ]; ]+ K8 g* R7 M" M0 p4 c& m
- /* LED慢速闪烁 */
# H- `- X" h6 R- q' b4 | - for (i = 0; i < 15; i++)- x! R4 U' p! q+ _5 o& W
- {
1 J; f" I- F R# V - Delay((uint16_t)60000);
5 w- \& F! @; U8 {4 Z# Q- q( n - }5 E ]+ r6 X( Q4 e% H% i! j8 b! u
- /* LED反转 */
" q/ @: E2 ^8 s$ H* G+ a - GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);8 H% \* ?: c% m1 |4 A! R6 t; \
- }$ T: n S' O6 v" q5 p4 f$ ^% m
- }
* Z( S* w$ M* x8 y3 e$ C6 D - }) \. @! U6 l0 }/ j3 v- D
- 0 o* l, j0 c, k7 E/ ~3 i, s9 ^- }
- /**
, g/ A4 r; c5 u. ^, A$ U0 n1 P0 d - * @brief Configure system clock to run at 16Mhz2 l" D" @: B# y6 r2 @# D- B4 W
- * @param None
9 s. \. l* @7 ?9 J8 W; X+ P - * @retval None! V% }5 Z/ `8 K5 c1 c) X0 a9 w! {
- */
- Z5 A7 o$ l; \" L9 g - static void CLK_Config(void)
0 D0 j6 p A" q/ K# _" O - {/ F! s+ d2 W( U6 |; L9 W
- /* Initialization of the clock */
/ `9 V$ z9 S1 M - /* 配置HSI分频率,CPU分频率1 */! ]& N. ]3 Y; k! l. ?1 X7 S) v* Q
- CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);8 X7 g3 K) r: ]
- }( M: a$ W/ c1 t$ K1 t7 C
- % t1 Y A6 m, u( Z1 s7 \1 {5 s
- /**
3 ~- y+ p" P6 V: ?9 H8 g - * @brief Configure the AWU time base to 12s- v1 x6 n2 h. A# |( R5 P
- * @param None8 T' [: F" g, I
- * @retval None
, I$ z5 Z7 C! a$ ` - */
. k. t. T) f+ |4 l6 Q - void AWU_Config(void)$ y; S* I6 g1 n
- {
% O) V8 I' c% Q7 G6 ] o4 T - /* 初始化 AWU */) {: Z" ~2 c; s8 I1 i* _
- /* 通过LSI 校准AWU唤醒时间*/9 U5 ~, b# E) i& E/ t& W
- AWU_LSICalibrationConfig(LSIMeasurment());% Z$ A( R7 }' ] w2 u& p7 C$ U
- ( W9 L3 P4 Y% Q. {( ?5 h
- /* 停机12S后唤醒 */ G2 W/ [6 L/ C) d* R. C
- AWU_Init(AWU_TIMEBASE_12S); W8 ]5 r1 B% H5 r
- }: C. e; G; A, J1 H
- + {, [0 d/ z0 X& I
- /**- ?1 W& S: _/ Y
- * @brief Configure GPIO for LEDs and buttons available on the evaluation board0 u: }5 q6 ?( Y+ z: a2 W0 b
- * @param None$ O+ L% K3 V+ S3 a2 n
- * @retval None
2 o: n3 V$ n9 \8 C* U/ S - */
0 d) _2 Y& `- a1 `# J/ @/ z - static void GPIO_Config(void)" L* {) b. ?4 z
- {
# b' ~5 K7 p* [! Z M, D - /* 设置外部中断端口C模式为下降沿触发 */
- J9 D& {. X1 d3 A. Z# f% W - EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_FALL_ONLY);
' j- i! j8 G# T: b- N% A: Q -
8 J! l% H8 N+ f7 s! e1 u - /* 初始化外部中断IO口 ,悬空输入并使能中断*/2 q& t" {1 a- h2 }; w0 K
- GPIO_Init(BUTTON_PORT, (GPIO_Pin_TypeDef)(BUTTON_PIN), GPIO_MODE_IN_FL_IT);
% k- ]1 u9 p( M8 s9 j - ) |* d4 ^5 q% T4 Z" z- `
- /* 配置LED1 IO口为输出模式 */
# n( Z& Q! Z# h7 n - GPIO_Init(LEDS_PORT, (GPIO_Pin_TypeDef)(LED1_PIN), GPIO_MODE_OUT_PP_HIGH_FAST);
- [6 I* a+ S: t9 }, S7 J% u k. | - }. r8 D' v; ?, p8 Q P. V% R
- 4 @% ? `* w* y+ N5 e
- /**$ g# P( i, s* @8 ?1 t; @
- * @brief Measure the LSI frequency using timer IC1 and update the calibration registers.
* ]/ D* {) Z# m. ~) I$ y" V$ T - * @note It is recommended to use a timer clock frequency of at least 10MHz in order ' q. k2 O! M+ d0 a0 l. g' L
- * to obtain a better in the LSI frequency measurement.8 }) W7 r& F2 a
- * @param None
5 e& l2 C- W4 [ - * @retval None$ D- L' [5 R; L0 a; J: t
- */
H# \) d6 ?: O% R9 E# ] - uint32_t LSIMeasurment(void)
6 c) W& x" e" O: {) g& H4 s/ Y5 \ - {) ^4 z# Y4 P% w6 A% w" f
- : w! x1 M5 j6 E- p: Z: Y, P7 v
- uint32_t lsi_freq_hz = 0x0;
: D1 P/ I+ ]' `$ S - uint32_t fmaster = 0x0;- T5 m: s4 G/ i$ l5 C0 f
- uint16_t ICValue1 = 0x0;
0 m) X0 ?* k8 W - uint16_t ICValue2 = 0x0;
/ p. a0 G3 l! P* ?* w - * P' ~. q0 v. {; _/ ~7 S
- /* 读取主时钟频率 */
/ h5 g4 d: ^8 W l' f' H3 T& U* l. C - fmaster = CLK_GetClockFreq();
# q j; B& ~" B) a& y" c6 P/ Q+ F% M0 x2 b: \ - 2 F$ c( D% p. l3 |0 Z' C1 u- o2 {
- /* 使能 LSI 测量: LSI时钟连接到TIM1_CH1 */
8 k8 h, \4 r0 ^, P/ h1 I6 J - AWU->CSR |= AWU_CSR_MSR;' Y0 V- A v( |/ ^+ w6 z. J0 z
- 0 D1 _' F# k% h: Q% Q. R& q1 H
- /* 每8次捕捉一次!!! */
9 o, N6 m5 B7 v# p7 Y9 q - /* 使能TIM1捕捉 */
4 ?0 i( d p* Z4 ] - TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0);2 j# W5 _2 ~- @% m* o3 A
-
! {" k6 D/ j. g7 ]9 @+ o$ ?* s - /* 使能 TIM1 */
; g4 O' M; U! ]9 L& J# B5 Y) W - TIM1_Cmd(ENABLE);
0 r% z+ p/ @: {% v& E/ v# l( K -
3 H6 ~' z j Q( p8 ?1 k8 R; @! v - /* 等待 CC1 捕捉 *// n8 r$ x: D& o7 {' u! {
- while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);4 c1 v3 q; w/ K$ `1 s# l
- /* 读取 CCR1 值*/
. w. q% }0 d) G - ICValue1 = TIM1_GetCapture1();
9 C0 |6 g( x; Z0 J, A2 m6 g- u" H0 r - TIM1_ClearFlag(TIM1_FLAG_CC1);
) O' q+ w5 t, C1 |4 Q) }$ q -
2 N, O* Y+ H2 d7 K - /* 等待 CC1 捕捉 */
% e* V! D7 ^- O, [' n M4 a - while ((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);
* M% u& r" T) T/ e" | - /* 读取 CCR1 值*/. e/ v$ H3 X; o1 Z4 n
- ICValue2 = TIM1_GetCapture1();0 X# }5 ]; |( A. }' O/ L/ O
- TIM1_ClearFlag(TIM1_FLAG_CC1);
; ~* N. Y' H y+ C- L/ b$ s7 f - , K( \) A7 ], j
- /* 关闭CC1捕捉 */
( a. n/ D3 k- {' o% {0 P - TIM1->CCER1 &= (uint8_t)(~TIM1_CCER1_CC1E); B- h: D- i- g1 N# F4 z- F
- /* 关闭TIM1 */% v k/ A( M) S* h; A* c$ `
- TIM1_Cmd(DISABLE);3 Z3 f A/ w: x
- / o" c3 [' @) z ?! o, y9 E% E
- /* 计算LSI时钟频率 */
4 s6 c1 G9 L, f - lsi_freq_hz = (8 * fmaster) / (ICValue2 - ICValue1);$ l: f* X: w- p
- - c" u: N4 ?2 V
- /* 禁用LSI测量: LSI时钟从TIM1_CH1断开 */1 @" U! b: R0 ~5 l* m4 t
- AWU->CSR &= (uint8_t)(~AWU_CSR_MSR);3 U; i) q& {4 t# ^( n: O
- /* 返回计算的LSI值 */% h2 Y5 C& Q0 t$ T
- return (lsi_freq_hz);7 y* P; `9 C: @8 k5 h5 U
- }* O" d2 D) K; e0 @
g) a7 a$ _1 h" c/ u" Q* Z$ E- /**& T; i0 c+ A! A4 O5 ^) _1 i) p
- * @brief Delay.
- }- Y0 j( n! a. T+ O - * @param nCount! [' T0 G+ h9 N% O9 T$ i
- * @retval None
- _; R% W3 t. ?& l( K0 _ - */9 I- e' B }$ I: k8 M
- void Delay(uint16_t nCount)
; f4 w, K, I$ [' y P - {1 U' B3 Z; x5 Y% l4 b
- /* Decrement nCount value */
4 F% E. a. ?: K6 p - while (nCount != 0)! ?" T' f! ]2 j1 s; Q
- {
% E9 @! X1 j0 H2 `' q - nCount--;
: a Z0 H0 i0 K/ q, t" } - }
1 T* g" g L# P5 K - }
复制代码 2 e, l5 E& w4 S! ~
4、编译运行:
( ]' l! I$ ?; Q
# v9 a& B/ K' K3 |* y" N' D7 l' f$ Z6 R3 a! f* B
2 [3 S! s4 S+ l& A
" i9 S) E- l. B |
已收藏