本帖最后由 zhdzhd-174422 于 2019-2-27 20:14 编辑
* [+ [' q- X( G/ c+ k- A4 u2 i
, a4 Z' K# H6 }5 w* H AWU是用来当MCU进入低功耗的活跃停机(Active Halt)模式时提供一个内部的唤醒时间基准。该时间基准的时钟是由内部的低速RC振荡器时钟(LSI)或者通过预分频的HSE晶振时钟来提供的。STM8S的LSI时钟测量在使用LSI低速内部时钟时,为了确保最好的精度,它的频率可以通过TIM1_CH1来测定。
3 ^# L: Q% c0 p$ T8 p7 ]
1 Y/ ]- W, L/ Q: Y9 Q+ r. S1、复制官方AWU工程文件:
6 [3 x7 y; v/ |8 e# ]7 z& }7 _
' r9 f9 Z' }3 c. I) ?6 {
2、打开IAR工程,先清除上一工程的编译信息:. Q: [4 c3 W# [/ \8 V3 p* b' q
+ r0 |) w, W' s" |; w2 K8 \, G4 T8 ]3 Y
3、修改main.c文件:- /* Includes ------------------------------------------------------------------*/
4 [; j$ {& R. R! j6 L! k" W - #include "stm8s.h"
3 i: S( B* K) Q# {) L4 U! @ - #include "main.h"7 l5 H% w/ G; v1 ^$ p0 i7 T
# e/ e8 x: u8 P5 K c( n7 O) ? j
# R+ R0 X/ Q6 d, d7 l! Q7 n& w- /**6 F% Y5 U0 m* Y7 Q1 N
- * @addtogroup AWU_ActiveHaltMode1 `- k/ l( \1 w/ K
- * @{
- X3 P9 H( E' u/ i1 a - */
0 ?7 }0 D& S) z3 Y: V3 V8 r
b) V# i2 I: _' v# `) t0 t7 u- /* Private typedef -----------------------------------------------------------*/1 C( r9 @, D& a
- /* Private define ------------------------------------------------------------*/9 B7 q$ j5 w1 o# c# S
- /* Private macro -------------------------------------------------------------*/. ~ M; w& w4 P* n
- /* Private variables ---------------------------------------------------------*/
L- N# Z! c) C4 e1 ?2 x1 r- | - /* Global variables ----------------------------------------------------------*/8 X; u; l2 E- z' X' B
- bool ButtonPressed = FALSE;
& c2 u- }) B% a; R) J - /* Private function prototypes -----------------------------------------------*/
0 j$ D+ l& j6 j$ L( d+ J - void Delay (uint16_t nCount);( V) [! ^4 L. Q5 e% S6 B
- uint32_t LSIMeasurment(void);3 q+ L g' w* j7 U7 ~( E: g
- static void CLK_Config(void);
+ B5 @( Q# v3 ^& e! R" M - void AWU_Config(void);# E9 _- Q1 B$ g7 k, c
- static void GPIO_Config(void);
6 C* o8 r. F1 J2 t - 1 P0 q+ z7 b0 w2 _: W
- /* Private functions ---------------------------------------------------------*/, U: f' l& M U" o1 }8 R- O
. W9 U- j: B) E) j- a8 p f- /**2 T; f; d: y/ N p m' M5 y
- * @brief Example main entry point.+ w' Z6 l a/ x+ e
- * @param None2 p5 C$ l ]& J8 s& \" d+ K
- * @retval None8 j j5 u! \! ~. e" f# `0 R
- */3 }8 o# T- G# {# J: e
- void main(void)) T& V: z8 j! _4 P' f
- {
. Q* R: k% o1 o5 ~7 }6 d" Q% X - uint16_t i = 0;4 v/ a2 z3 O* C# C, }9 y4 \9 m
- uint16_t j = 0;
+ s9 c; q: O; B1 ^: W( ? - , o6 ]4 C5 I$ j5 Q6 |" B
- /* 时钟配置 -----------------------------------------*/ z `8 @+ C& k0 o5 B) J# A p
- CLK_Config();9 i' J5 W u4 L" V( ^
-
4 n' K! t% Q, P3 l - /* 端口配置 ---------------------------------------*/
. T9 g1 ^% p9 @, w - GPIO_Config();; H: y' c" E. F7 V! k
- 1 u, X+ e8 P) M' h
- /*AWU配置 --------------------------------------------*/
; t- W6 i2 \+ _. f - AWU_Config();
( M( b: J: M0 D0 P2 Q8 t \( u - 9 s4 I# n1 k. ?* y6 N: X
- /* 使能总中断 */" E/ A0 h3 f3 ` \5 L! E
- enableInterrupts();
0 b. q1 E" g( |$ j; `
* a* h8 @, I. V/ C2 ~6 S1 s3 G; t- while (1)" @1 Z4 V& z: g0 F
- {
, X9 Z/ X/ w. }. m4 T' |" [ - /* 按键扫描 */
$ W' N2 r3 h; a - if (ButtonPressed == TRUE)
& B; E' Z9 x/ Y) [ - {5 X( f+ @8 k( \9 T3 r& `' M- i' R
. i% J/ r6 {: E3 r- ButtonPressed = FALSE;
3 l6 J8 ?- `! W3 { -
2 z) Y/ Z* b$ ]- j; N/ j5 T3 N+ X: j - /* LED快速闪烁 */) \7 o. f, L( R1 F. Q/ ]
- for (j = 0; j < 20; j++)% K( F1 @: M W* ~0 e7 W
- {" S- Q" I7 \3 s& s7 l7 {
- GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);! X/ C4 \# n" j! O. G, o
- for (i = 0; i < 5; i++)# v2 W/ ?4 u& ~7 ]8 |
- {
7 t Z& R4 d3 x4 ? - Delay((uint16_t)60000);3 |2 Q( D4 K6 Q6 S |
- }
0 R ?; z0 d: V% R4 ] C( W# f - }
) \! `1 L" p$ r5 p: T2 F8 A H6 U
B" ^4 G; b% w" O- S9 X* o: B- /* LED熄灭 */$ _. f# ~9 \0 z% h
- GPIO_WriteLow(LEDS_PORT,LED1_PIN);
* ]2 b1 W1 _0 u) m( F - /* 进入停机模式 */
8 n A! o& I4 r8 N: W - halt();4 B6 q7 o f) n. B
- }1 e% R3 y% W; a7 D5 a
- else2 ^- R$ f2 a n! F2 Y7 i
- {! b Y# A. \. y1 y/ X
- /* LED慢速闪烁 */
5 s8 l0 S" T+ T$ L+ U. v - for (i = 0; i < 15; i++)
1 v' u' Y& ]2 X. J) \: d4 _, j - {# |2 B' `( X X1 E$ Y. Y
- Delay((uint16_t)60000);
p# o6 |/ p& o3 u+ j - }! k; |) E* W1 M- V
- /* LED反转 */% U j5 o: r7 |. k: `$ p' A
- GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);5 m# H8 b/ o# L+ L! h5 r
- }5 I, H: b1 `$ q( H; I, {
- }; G- B" w1 ~; X- c5 x
- }
. _! Y0 e+ W4 q) q - 0 j! M( A- U# E2 o( h# g$ b4 m
- /**
; }3 ~" T! o, K& N+ Q - * @brief Configure system clock to run at 16Mhz
% a$ @ B2 q$ d - * @param None
( B/ J8 r! c" M" H% e2 G5 @ - * @retval None
7 ~% m+ }9 Q3 G& W& z+ y - */
" Z$ N* E2 d, C: [6 K$ U - static void CLK_Config(void)# ]- _6 e( i. \2 ^, g4 P4 j5 Q0 j o
- {
8 }% U5 n( V+ {* ]* u) q - /* Initialization of the clock */
; H( s8 m F' e# P - /* 配置HSI分频率,CPU分频率1 */
7 X+ w: h$ s- O- J& F9 V% L - CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);+ \1 `% p# y5 K' s/ E% p" z
- }2 j6 a' C& x+ t
- : I! `2 x% Z6 @7 y
- /**$ ]. N7 p' n; R! W
- * @brief Configure the AWU time base to 12s; i/ l. M# ~' l, ~! u6 B. ~6 A0 }! U
- * @param None
( Q- x/ @* \3 w2 o$ H! o( @/ U - * @retval None
; n. d J/ R+ C. f5 A: \8 G! W" P - */
# t+ }7 b6 ~; n4 z - void AWU_Config(void)8 m& f: P! C. f1 @. b0 i
- {
@) X6 g( A3 M: M/ }0 e; h - /* 初始化 AWU */
* v: ~3 w. W) p - /* 通过LSI 校准AWU唤醒时间*/
0 N4 D$ P; ?+ f g/ O9 x. @; }% B - AWU_LSICalibrationConfig(LSIMeasurment());
% d/ z% s* L) n c( z; a -
9 X; b8 L- ~; ~ - /* 停机12S后唤醒 */) L: `& F% Y; c$ T: p5 d. e$ `" d
- AWU_Init(AWU_TIMEBASE_12S);6 o$ T% n# H( ?, }
- }, i: B9 u/ F$ K* O, B& P3 x3 C
' J6 L7 D# u, d8 P" l7 Z9 K; C- /**$ @# @/ b/ J: l7 v5 ^) P( m$ @
- * @brief Configure GPIO for LEDs and buttons available on the evaluation board; D+ ?# i o3 k8 Q
- * @param None
. {) e9 f& e3 U2 w$ Y! w - * @retval None
. x# ~9 J: M9 l: L8 n - */
7 }3 o8 }: ]! S - static void GPIO_Config(void)
( a3 A: E4 z! J a8 S/ z - {
) |6 h" H4 a5 I( R - /* 设置外部中断端口C模式为下降沿触发 */. |1 D1 p% R0 j5 v! @. g
- EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_FALL_ONLY);. u/ W9 ]; ]% k; ]4 U
- ' R: y, k, |/ h* P
- /* 初始化外部中断IO口 ,悬空输入并使能中断*/
0 i( l. H4 X& R* J$ g9 i! A - GPIO_Init(BUTTON_PORT, (GPIO_Pin_TypeDef)(BUTTON_PIN), GPIO_MODE_IN_FL_IT);
) Z; }. K- `0 k# J' Z3 { -
: w" B% {: t& u- P$ b - /* 配置LED1 IO口为输出模式 */5 S8 d& ^1 p' F& f& j) v5 w+ E
- GPIO_Init(LEDS_PORT, (GPIO_Pin_TypeDef)(LED1_PIN), GPIO_MODE_OUT_PP_HIGH_FAST);
, s& C, m/ Y2 k; ]% U - }
0 j4 I& G- J/ E' B% g. ~
: f X; z3 J: C( e$ {- /**
4 d1 I- P. C6 k9 j - * @brief Measure the LSI frequency using timer IC1 and update the calibration registers.
- V/ Q7 _6 t& g! V - * @note It is recommended to use a timer clock frequency of at least 10MHz in order ( K( Q8 Z# L) E. U
- * to obtain a better in the LSI frequency measurement.
% H" n* q9 r# s9 f, Y# p" | - * @param None
- U# A! C" f9 W - * @retval None9 _) Z$ v3 e* e2 Y5 y4 I% r
- */
r7 ?: d3 p1 p6 C1 e - uint32_t LSIMeasurment(void) t; d# v. \, H7 z4 \7 z
- { Q q5 J, w' g7 X
- . c% ?' Z; J: g2 o
- uint32_t lsi_freq_hz = 0x0;
# S8 ?, e! [ l2 T/ W - uint32_t fmaster = 0x0;
5 A) P3 @+ I2 I' a$ u - uint16_t ICValue1 = 0x0;7 E* n/ Q+ x- c7 ~5 w3 R) E
- uint16_t ICValue2 = 0x0;6 p" x% p8 [7 H4 A0 [9 P3 [8 b
8 w7 V+ k8 r7 t* X- /* 读取主时钟频率 */
1 H: A H0 c" D$ J; s; ` - fmaster = CLK_GetClockFreq();
% b5 h& ?: f. J( C8 }: S - 7 N9 \; A/ O; @9 R
- /* 使能 LSI 测量: LSI时钟连接到TIM1_CH1 */6 j6 s/ o* {5 A1 H& p3 R9 ?' h( r& T
- AWU->CSR |= AWU_CSR_MSR;8 i. N" A7 i' R" i* s/ V& A$ [8 n5 g
5 O& a' Q) K {$ e- /* 每8次捕捉一次!!! */
3 Y, H1 X; u# _) [ - /* 使能TIM1捕捉 */
% f, M; B P8 x- k* S! @ - TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0);! e9 U2 X5 w+ O0 z" p: B0 W
- / ?0 F( c R/ U2 f* l U; u
- /* 使能 TIM1 */+ b3 u$ r) D: P
- TIM1_Cmd(ENABLE);
" C3 z- H, I, F" j( j5 \ - ' ^8 E& F7 B2 R+ S
- /* 等待 CC1 捕捉 */0 w. O1 B3 Y* _) N; ^! R: D
- while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);
7 u# x& x2 g2 t4 c7 A - /* 读取 CCR1 值*/
3 W* e# P, i p- s - ICValue1 = TIM1_GetCapture1();
/ U# d' V) T* @# u6 a! Q, P3 q - TIM1_ClearFlag(TIM1_FLAG_CC1);
: K0 I* c" n% t5 z; S -
3 P8 C/ \' N& ]3 v7 s5 H - /* 等待 CC1 捕捉 */
2 P) ~7 f9 V7 |9 j) n) R - while ((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);
9 e Q+ o; c6 v l - /* 读取 CCR1 值*/
" f( g5 C# `5 z6 @ ^$ P% ] - ICValue2 = TIM1_GetCapture1();
! E( G$ k5 T s( K) W6 L& R. l7 Z - TIM1_ClearFlag(TIM1_FLAG_CC1);* {7 h6 a% _# S7 k8 t
-
1 X3 O+ E6 c8 `1 n B - /* 关闭CC1捕捉 */
2 O5 k' L% e ]1 y0 Z - TIM1->CCER1 &= (uint8_t)(~TIM1_CCER1_CC1E);$ H) r; a( n, O7 R
- /* 关闭TIM1 */
* v K) b+ [9 K7 g" D/ z7 T! J - TIM1_Cmd(DISABLE);
& I; @, K/ J" A& M- O2 v9 H - 0 O1 H9 |1 d- a) J- b' t5 P3 ?
- /* 计算LSI时钟频率 */, ^' N c. M t# }7 {: w# n" X
- lsi_freq_hz = (8 * fmaster) / (ICValue2 - ICValue1);
9 b% `6 J- D* R5 b5 J# I W -
+ O" | e# d" f) H, A - /* 禁用LSI测量: LSI时钟从TIM1_CH1断开 */
" Q& Q4 W1 Y- ^# T- z6 O - AWU->CSR &= (uint8_t)(~AWU_CSR_MSR);
0 }, A$ w) x0 P+ ^# m. s - /* 返回计算的LSI值 */
/ [7 e7 d5 s6 j% [, u - return (lsi_freq_hz);5 O+ F3 M1 Q' A/ b* k7 v
- }
0 q, K5 _+ j, k8 J8 ~
1 b: S8 |. m& k* C4 F- /**
6 J; I9 P* a# `7 T6 T; f - * @brief Delay.( A: T+ s& j4 ]6 J$ B% }
- * @param nCount
& q3 J- M# s7 e9 O0 T A3 t Q7 M - * @retval None1 I# C3 H# a. I8 w: U( L
- */
9 V8 W5 C0 ]# p2 P3 z - void Delay(uint16_t nCount)) f: _1 d! o. O- \' D s' ?- ^
- {/ }1 H3 i- f& g( x+ W4 B
- /* Decrement nCount value */
3 |% F1 a8 q) Q - while (nCount != 0)- p& K: H" v6 U* X9 a6 w
- {4 n/ m( q6 \ Y9 {
- nCount--;* K- r) d4 h( f6 N9 @4 w5 b7 J
- }' T7 D5 |3 A+ I1 @: E
- }
复制代码
9 I" v- s5 @, R' w4、编译运行:
% {; ]2 a8 o6 i |! E I6 L8 ^; Z; [- I- ]. j& o
; `/ Y4 n6 u9 R6 h3 I$ M
; D* r4 N; t" ~- o; o% }' ^
" z/ |8 J' I5 I9 i% l+ |
|
已收藏