本帖最后由 zhdzhd-174422 于 2019-2-27 20:14 编辑
2 N; x- n. f/ A/ N M, G
. D/ D7 Q6 _* D+ V. c8 ` AWU是用来当MCU进入低功耗的活跃停机(Active Halt)模式时提供一个内部的唤醒时间基准。该时间基准的时钟是由内部的低速RC振荡器时钟(LSI)或者通过预分频的HSE晶振时钟来提供的。STM8S的LSI时钟测量在使用LSI低速内部时钟时,为了确保最好的精度,它的频率可以通过TIM1_CH1来测定。
0 _0 N9 R0 r/ H6 x6 g4 g# p8 ^! T) s% R+ p4 R4 z
1、复制官方AWU工程文件:
* f/ x" [3 e4 [: f8 k- `) b
" C+ t: J5 k2 N. r- b7 T2、打开IAR工程,先清除上一工程的编译信息:
: [7 u" B/ b$ ~6 g C r
, C% S1 w/ S/ D/ M0 r$ [0 k" R+ Q
3、修改main.c文件:- /* Includes ------------------------------------------------------------------*/
8 y* y U: F8 j3 w - #include "stm8s.h"
# m; f9 W. {3 ?1 Y0 y - #include "main.h"
3 G0 ^! b% u% `" f z7 K - 8 k" u$ N" f1 ^3 Y" C
- ( l- i# g D/ y: A" a( k
- /**
# ~- p" U# u3 \8 X, l - * @addtogroup AWU_ActiveHaltMode
. q% C/ z% z/ |7 l9 ]$ A - * @{
5 s. ?( v4 Z( c* b, g, s0 p: x - */" z# m2 x% U1 X- Y
; y+ Y& m( T% c- /* Private typedef -----------------------------------------------------------*/! y& f P! y/ c2 |
- /* Private define ------------------------------------------------------------*/
* B' I& e1 [( ]5 @ - /* Private macro -------------------------------------------------------------*/& x8 }0 T# w/ {$ P& c$ r
- /* Private variables ---------------------------------------------------------*/9 \9 P! U; E/ o& W# V& J
- /* Global variables ----------------------------------------------------------*/- U p L% T r" A3 @
- bool ButtonPressed = FALSE;! w, S* i7 _. M: \% c" }' F
- /* Private function prototypes -----------------------------------------------*/
+ |: u3 s/ V+ d$ p - void Delay (uint16_t nCount);6 k* m- h; b( n1 ]. @. q" u
- uint32_t LSIMeasurment(void);! k2 a, [& S, q+ B! _( h
- static void CLK_Config(void);( y8 E/ I6 ~9 t4 G
- void AWU_Config(void);9 D. x0 q8 K- O0 U: J7 b
- static void GPIO_Config(void);/ E) w3 y# d1 B
- ( k3 r S1 ^9 ^0 i- ~( k
- /* Private functions ---------------------------------------------------------*/4 R# E. M- T0 M. Z. T/ W
- 8 i o! k. W0 w& V
- /**! b1 @6 |+ T" H$ H' G9 y' ~! A
- * @brief Example main entry point.' P% f, C! x |5 t* E9 f
- * @param None
* f( I% T: ]3 l$ X, a2 g4 y - * @retval None
: n/ M$ M. o9 q- i% e7 Q Q - */, F2 R: a: _+ l% `5 [; n1 Z, C5 `# G
- void main(void)
) E: i3 Y" U3 {" R - {
( V0 [: ?' v( i3 d1 i - uint16_t i = 0;
0 W# }5 E' H0 h2 w4 w - uint16_t j = 0;
% j4 D; U& Q# y1 w$ P - ( m, r K% Z4 k. B
- /* 时钟配置 -----------------------------------------*/
+ M# c3 G1 D' |) E0 |7 h - CLK_Config();/ t) h6 F, v7 j* P {: o% f) S
- . G) J& n9 `3 G' h) S
- /* 端口配置 ---------------------------------------*/: J! ?; H7 ~3 o% @& \2 W9 w
- GPIO_Config();6 r0 p: r, h9 j" H! W) c
- 0 b% n$ N( r# {9 a, q) m
- /*AWU配置 --------------------------------------------*/% D/ y; @% W5 q8 t
- AWU_Config();
. b3 A r2 y# F" m' o- L- z+ z - % d; A8 ?, u- H' }+ p/ \
- /* 使能总中断 */+ i5 C _9 H6 F3 a, D. Y. T
- enableInterrupts();8 }4 z2 ^1 b3 e* r' u1 t( H: e* F7 c
- ! f$ i9 v# D% }7 N8 |1 o* q
- while (1)
5 Y2 p4 F) E3 i# `; H9 N - {
! _1 R) W2 y k) i8 q( C4 w - /* 按键扫描 */8 Q( j$ @! V( @ A; W3 y: V, ^; Y
- if (ButtonPressed == TRUE)) N6 ]* ]4 y# G7 Q+ e; ]# {
- {
6 q& e0 P. T D7 l - * r9 A6 X" a0 b8 M0 i
- ButtonPressed = FALSE;
& ?/ c2 {7 j% i/ l6 _; @" i -
: f! }& |' F, \. R - /* LED快速闪烁 */3 i% U' C ?7 G6 j" D- p8 F$ R
- for (j = 0; j < 20; j++)
& x3 T7 N ?# i9 [( V' M9 s5 ~ - {$ R- n0 [1 j( Q" R
- GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);+ g h/ \7 y- K% q. |. S
- for (i = 0; i < 5; i++)
0 G+ Y" ~4 U. _, p5 L - {! u2 c) q0 E8 s5 p7 c
- Delay((uint16_t)60000);6 ?1 L, q" a* d2 ~! T) K
- }6 q7 l# M) d6 f8 q0 u$ L/ H
- }
0 g1 x+ }( a, ~! q% C
0 r- v0 f& y6 C5 T" F d- /* LED熄灭 */
5 o1 ~( |, ?, z$ T - GPIO_WriteLow(LEDS_PORT,LED1_PIN);, B( w$ m3 z6 ]6 H0 a, W6 ~+ R
- /* 进入停机模式 */, D- s/ K7 N6 U& R) N( W+ |
- halt();2 ^9 S( S4 b$ Y$ h
- }
' j4 h( R! b5 e - else3 f( N, ?3 ^" o! F
- {1 Z/ N* d% n- g7 {+ X
- /* LED慢速闪烁 */
# X, y+ A' B, O - for (i = 0; i < 15; i++)* v- _* k# F% T# a
- {# z# q( v/ N2 r+ o! P
- Delay((uint16_t)60000);* x# Z5 A! F# j; K) c' |+ z
- }: p' z0 i6 n5 ?8 j8 m- I
- /* LED反转 */
0 J M- x# a8 }4 y' h0 n8 N - GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);
0 r s2 U" Y1 J# @ - }+ ^/ [ {. W! d
- }
- ?# ^& R; p" h3 p5 x - }# K2 [! ]! {& ]
5 D7 @4 j1 t2 @/ G- /**
, _5 _( v# n6 a6 |, |; N; l - * @brief Configure system clock to run at 16Mhz
4 x: f( t7 i) |1 |. Y8 ] - * @param None
6 Z0 S5 q: |& [4 A" d - * @retval None# |6 k1 ]) K1 M' T+ O
- */
# j4 L! N! g4 t2 b' w - static void CLK_Config(void)
/ t }8 k/ ~, P8 `. P C - {
9 ]7 e# k) W, R5 V: O: P - /* Initialization of the clock */( j5 O( I2 M6 z* F9 T" F* O
- /* 配置HSI分频率,CPU分频率1 */9 _5 x% [6 O8 C5 D! U
- CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
) O) Y8 ^, t- |8 p - }
0 s; V4 G& s* T3 G8 l) e - ' X6 D& k" @. X8 H$ J; t a
- /**
( @5 h+ Z& F; p$ G! ?/ v! l* D - * @brief Configure the AWU time base to 12s! E3 G- @/ [0 p3 e: h; \
- * @param None0 t2 X4 I; }: W( V; I$ i& m- O$ m) Q
- * @retval None
6 i8 l. h% w, e) n$ M8 U - */
) f4 R! D) c( N: M* B! ]: V - void AWU_Config(void)3 q+ {7 T& k7 Z. G% g& b% T; y+ i
- {# L6 P3 _1 o9 g
- /* 初始化 AWU */* n5 P; B- [- Y; O
- /* 通过LSI 校准AWU唤醒时间*/8 f8 S6 {6 d6 x6 {7 B! m: e
- AWU_LSICalibrationConfig(LSIMeasurment());
# K8 G8 ?2 C G: n0 x1 f: k0 A -
6 l+ D' j, c0 {' P1 \5 c$ X - /* 停机12S后唤醒 */
3 Z1 s7 i1 Y H ~ - AWU_Init(AWU_TIMEBASE_12S);
8 ^9 x) w, w7 s* b$ j - }
$ |! W+ q+ j' p3 I
4 R5 X. f5 N7 z/ _, o- /**3 ~; W8 |) z8 Y- Y1 F
- * @brief Configure GPIO for LEDs and buttons available on the evaluation board* j1 U- R# \/ K, e" r
- * @param None
( k2 h3 O+ @& T3 B; E& E - * @retval None' G* o* x; F8 e" u' n! G
- */
* i+ ]6 u. A* O! f( Q - static void GPIO_Config(void)# c t! r8 [- |" T0 a1 a7 L- l
- {! G! h2 W# \7 X3 _% r
- /* 设置外部中断端口C模式为下降沿触发 */
9 z l$ k( O! q$ x - EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_FALL_ONLY);9 e$ V, Z; z) `! t0 i( H2 c0 ?
-
/ E% ~# M, [* |$ K- s - /* 初始化外部中断IO口 ,悬空输入并使能中断*/+ M) q. w- ^ W0 r% O5 x1 a I
- GPIO_Init(BUTTON_PORT, (GPIO_Pin_TypeDef)(BUTTON_PIN), GPIO_MODE_IN_FL_IT);! ^0 ~1 c* ?$ K; V: [5 d
-
: K- |# i5 V$ T$ D - /* 配置LED1 IO口为输出模式 */: V5 r6 f* Z' W# V
- GPIO_Init(LEDS_PORT, (GPIO_Pin_TypeDef)(LED1_PIN), GPIO_MODE_OUT_PP_HIGH_FAST);
( ?8 w+ ]' y: M - }
% k& O+ C g6 q - # Q( Q& W, r! D' C4 N. J) D4 Q
- /**, [4 i1 F' L* I7 N
- * @brief Measure the LSI frequency using timer IC1 and update the calibration registers.
5 F n2 M/ T1 [2 ^. k% p ~ - * @note It is recommended to use a timer clock frequency of at least 10MHz in order 3 B) ?: E( H, w5 M7 T' k. y, j
- * to obtain a better in the LSI frequency measurement.! c0 W3 m5 l9 g/ E/ B; R' X+ k% L
- * @param None9 i& L) F; `; Z, ~( j: B, g3 q
- * @retval None6 d2 Y9 R: V, ^4 l0 B7 V* m
- */
1 z! x- Q7 D/ L' B1 g - uint32_t LSIMeasurment(void)
2 O, b" P# G5 }4 t& v - {
% v4 @& j n1 f N$ C% x: c -
) i1 K9 ^* F9 j& h$ ~ - uint32_t lsi_freq_hz = 0x0;% @- z( u8 J( _- ~6 ^
- uint32_t fmaster = 0x0;
7 r5 Z1 m! L; o( f1 V& H( f ~. P7 h - uint16_t ICValue1 = 0x0;
/ b6 X# D/ j3 B' X - uint16_t ICValue2 = 0x0;, W' R, c, C M* K5 k- {! o# V* ^
- 2 @4 D/ J3 n ~0 f
- /* 读取主时钟频率 */; w0 C1 K, x* g5 U/ i2 R0 j, _
- fmaster = CLK_GetClockFreq(); L* g3 E" b8 H/ h! q! m
" {$ |( Y8 h2 w- /* 使能 LSI 测量: LSI时钟连接到TIM1_CH1 */
3 v; o. H( J! B/ H# K7 @ - AWU->CSR |= AWU_CSR_MSR;: z) a# T n4 h1 @& x- z& t& D1 L
& q1 r" s% T: ]5 ]( P2 `$ g% q+ ?- /* 每8次捕捉一次!!! */
( ^6 R7 o! B4 ~, P% N2 G3 y) I3 }) j - /* 使能TIM1捕捉 */
2 T% U* n# q' |* Q( v - TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0);6 P$ `2 y* {2 D* M& H8 n; X
-
/ \) I; G* M1 S. h) e" F - /* 使能 TIM1 */
U6 m4 Q6 [6 m; |* O; E( ]# [ - TIM1_Cmd(ENABLE);
/ s9 Y) ?: z+ z - ( n q/ v' |/ o
- /* 等待 CC1 捕捉 */5 z3 q* z$ n7 y( X0 w7 b% n. v
- while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);
% d) B5 t$ j. Z# s - /* 读取 CCR1 值*/& A! i" r/ z, n3 n/ E
- ICValue1 = TIM1_GetCapture1();* _" l7 Y9 t' o
- TIM1_ClearFlag(TIM1_FLAG_CC1);
9 B8 [/ j% I) P3 u - 4 C' H3 @0 ^* V* R
- /* 等待 CC1 捕捉 */
- o. Q' K/ H4 c2 Q% C - while ((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);- P+ ]9 c% |2 S: J e
- /* 读取 CCR1 值*/
" Y1 U' c1 X" K - ICValue2 = TIM1_GetCapture1(); G: X4 G; c" P; F* V1 k0 r: {
- TIM1_ClearFlag(TIM1_FLAG_CC1);- ] j: }% J. p
- * x+ |+ E! [& e5 z, X
- /* 关闭CC1捕捉 */
4 E+ J# Z9 f$ g4 H% g% a! o* i& W - TIM1->CCER1 &= (uint8_t)(~TIM1_CCER1_CC1E);
6 f/ `9 O2 u. y' r( j9 b2 J - /* 关闭TIM1 */- m# _* ^- W* J2 b- R* d0 ~
- TIM1_Cmd(DISABLE);, U/ j( \+ O& l' s. e2 n! L
- # D: I% E% E4 Q
- /* 计算LSI时钟频率 */8 j* z6 W& U$ k6 U
- lsi_freq_hz = (8 * fmaster) / (ICValue2 - ICValue1);
# P0 z2 i2 }0 J9 N1 u$ \ -
# r2 N9 s5 G3 z$ P/ R1 l$ ~; r# e - /* 禁用LSI测量: LSI时钟从TIM1_CH1断开 *// |5 h* _( `. F
- AWU->CSR &= (uint8_t)(~AWU_CSR_MSR);
- H# G. H0 u4 o8 l; P - /* 返回计算的LSI值 */
0 F9 K$ i8 D# J - return (lsi_freq_hz);3 @2 ^8 z' k' ^; f7 ?: s* s
- }" Y4 f0 Q7 b Z# p/ {
" X! h) i3 A. T# i t0 \8 U- /**
0 t+ I/ G4 ]! F - * @brief Delay.
8 z. [4 a* p2 w0 U - * @param nCount' I; y9 m% r4 V! D
- * @retval None2 }% X# {$ q* p2 P( v
- */7 |) E) K: t4 C+ W) D9 [6 r0 s- w
- void Delay(uint16_t nCount)
6 K. {7 Q) j* H - {
4 i' \# g, o2 G; H* W0 [4 _ - /* Decrement nCount value */9 Z/ H9 o# Q4 Z3 r) X' y+ k
- while (nCount != 0)- l0 t/ r# b$ ]& i
- {
9 P8 {, `$ V7 A1 S3 {- F5 D - nCount--;
" y+ e% q$ Y. J" P - }2 B) o6 t# o6 x. a' a5 W, P0 [2 W
- }
复制代码 , L& Z: Z& A; i2 `* ]
4、编译运行:
) D% u V; d' M6 [: Z! B! y9 z/ w y" q8 c+ w6 R, {. A
# J( q" |& q+ d3 D
4 J! i- l- N+ \" W5 x$ K
0 e9 {2 y) P# J3 G' c" F: }0 `) X
|
已收藏