本帖最后由 zhdzhd-174422 于 2019-2-27 20:14 编辑
& C: X; F: |" T4 ~( ` w0 L, F- ^+ C# W5 l- T1 v7 ^. R
AWU是用来当MCU进入低功耗的活跃停机(Active Halt)模式时提供一个内部的唤醒时间基准。该时间基准的时钟是由内部的低速RC振荡器时钟(LSI)或者通过预分频的HSE晶振时钟来提供的。STM8S的LSI时钟测量在使用LSI低速内部时钟时,为了确保最好的精度,它的频率可以通过TIM1_CH1来测定。2 e! v5 W) s& T. Z# s# [
( q, }, `1 K6 }( D$ T% I1 W1、复制官方AWU工程文件:
+ T1 y8 S$ \) D; \! P F
1 _; t6 w) I( J1 j2、打开IAR工程,先清除上一工程的编译信息:$ h3 A4 _7 W1 b# K/ I) r
' [) e1 j9 X6 a# G
C0 n& N) V7 }3 W; G/ F3 ~8 Z2 _3、修改main.c文件:- /* Includes ------------------------------------------------------------------*/
9 m/ T6 V W% w: o9 ^. {+ Q - #include "stm8s.h"6 C/ W. Y8 d$ G5 z0 K
- #include "main.h"
. o) V. z% u3 [
& t O8 s$ X% ^- p9 A
& B1 j+ `% i! L5 ]8 z r8 F/ _- /** g" b/ m- @$ o
- * @addtogroup AWU_ActiveHaltMode
4 s! K4 M; L# I! k - * @{
8 {7 K" x K+ V. ^ - */+ s0 |. p& l- F1 ?
- 5 q5 s6 h! P2 b7 T
- /* Private typedef -----------------------------------------------------------*/
% @: W5 @& m" T5 K& |7 _- X, ~( }2 @ - /* Private define ------------------------------------------------------------*/
! C& K) j" ~; v4 x" X. x - /* Private macro -------------------------------------------------------------*/
0 G5 ? o5 X1 ?, } {" v3 P - /* Private variables ---------------------------------------------------------*/
3 ]3 E) H$ _" u+ O" ` - /* Global variables ----------------------------------------------------------*/( y3 x6 m( g- T! |
- bool ButtonPressed = FALSE;
9 ^. }7 j4 M9 ]* m$ X - /* Private function prototypes -----------------------------------------------*/ u4 D5 P. I0 F9 m8 b
- void Delay (uint16_t nCount);
6 I3 M. N9 [( f }' ~$ w0 d - uint32_t LSIMeasurment(void);' e& |3 K2 g$ E3 g' M0 l
- static void CLK_Config(void);3 A `, W, E7 s
- void AWU_Config(void);9 }. d2 b* z0 b
- static void GPIO_Config(void);" T' ~3 F, E% ]4 H* G4 w
3 |& b2 w6 l" W6 P5 f- /* Private functions ---------------------------------------------------------*/& O$ T" w( T0 ~7 z; w
1 R& Y# g) J, Q8 Z: w- /**
; p' u$ f! h9 E' ]( U; y8 N& h) m$ a - * @brief Example main entry point./ A, P2 ]6 | G# b7 ?3 _
- * @param None! a' a0 l ?7 s+ t7 G. d% `
- * @retval None
+ H! ?: Z5 L7 I3 A0 H' C! }2 g) H - */
/ f' k, B! V* L6 |( z$ r) h - void main(void)
, }- w* _7 u' a% F4 c; v - {% l: T+ n( P1 _! p6 Q/ d! o) G4 H
- uint16_t i = 0;
6 Z1 `0 e$ I6 [$ ` - uint16_t j = 0;0 z4 F& f) Z' B- ]
-
, `3 c0 z" M. a" p! S; Y0 j - /* 时钟配置 -----------------------------------------*/
+ T, `, f% g8 P - CLK_Config();
/ B3 T/ o4 K* w. T) p - 6 O4 V; z, A0 C. l5 i5 @
- /* 端口配置 ---------------------------------------*/4 H7 V" i6 O* r3 ^% a$ c
- GPIO_Config();. E& v) J) k0 s: L
-
7 o- }0 c, d5 r4 f& ]4 ? - /*AWU配置 --------------------------------------------*/
+ o; ^ V" W6 v9 ` @8 y, c - AWU_Config();# d! U9 K' l! _5 B* a% z
# T p) b: |. p0 n" _- /* 使能总中断 */2 J2 k5 h- Z$ S/ X& r
- enableInterrupts();. V/ f: h. ^8 d7 K: y. [9 N
; `# ^* J; Z* A& k- while (1); q( l! k5 q& _3 C* z- ?
- {; H! l& o2 T! g x9 |
- /* 按键扫描 */6 y8 W0 |* m7 F! s/ w% ^
- if (ButtonPressed == TRUE)' D5 j0 m# c+ s( R, h+ F
- {
4 f( c+ w# I \# ~3 S+ `
8 L1 a. C# [ M$ Y/ ^4 H4 g8 w- ButtonPressed = FALSE;. X9 ?( N) m0 A: v# W* N/ |" l
- & g- f7 N' n+ J4 W( F
- /* LED快速闪烁 */2 X0 h+ S b$ o E# z
- for (j = 0; j < 20; j++)1 M/ k) a0 r6 d G9 D8 R
- {
* X$ W6 v- H8 ]; N8 V - GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);
5 o8 f3 x" e. j. L1 j7 F3 S - for (i = 0; i < 5; i++)
$ U/ R' V% J. `) D( I7 o8 s* e - {
9 i5 X+ [ E0 H9 A, n4 h. g4 p - Delay((uint16_t)60000);
/ H1 F: V1 f# U7 q! V0 i9 Q - }
% t! ], p2 N0 J - }
. b: k3 A% s! d! R2 S/ t' ? - 8 V$ x- N( F1 ^1 n, f$ D% E
- /* LED熄灭 */
0 F& @9 d8 C" S - GPIO_WriteLow(LEDS_PORT,LED1_PIN);6 i2 ~' J0 {2 c4 j
- /* 进入停机模式 */: `& n) D; ~8 W
- halt();# w* ` x- t) k/ H3 M9 u
- }
( _" V; `: f# m7 b, T" X. y6 W. Z) F - else
( A% J9 C3 i: \( `4 [6 a- N, H - { w# ?5 L( Q' [2 n3 b- W8 d
- /* LED慢速闪烁 */
; T! }: ^( W( O5 D X( P - for (i = 0; i < 15; i++)0 U* e+ u" Y) W5 F; j. E
- {
9 ]: G* i. A5 S - Delay((uint16_t)60000);" U4 @# X; {2 W9 Z0 V- ]& w! G; Q
- }
+ m4 b6 H2 E+ `8 a4 n; | L - /* LED反转 */0 R* X1 A: V9 C) O
- GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);5 v* U: o! }2 L2 r g
- }( {3 E2 e# n- j7 ^6 D
- }
Y$ ]3 }; d! G$ H; M4 e - }
4 U" w1 ]: W0 S" \: ~; {2 L
. ]# H. n7 l& ^5 L! T- /**
# S, m, X/ }7 v* v. Z; J - * @brief Configure system clock to run at 16Mhz
: q+ g' V) |" t3 J7 A - * @param None/ _/ ]3 C- ]; ~: K$ }
- * @retval None
% J, R' O. \- ]* f5 Z - */) \4 M, r# c2 _/ v& V& a4 z
- static void CLK_Config(void)
5 G: C$ |# Y0 @ r' P& C, D - {: T3 ^- w. A2 m1 F4 L; a2 _0 Q4 L1 L9 q
- /* Initialization of the clock */8 z: w+ x+ X$ m( t, g f; O: e- m
- /* 配置HSI分频率,CPU分频率1 */
, r6 Q0 p* H/ w, ^" V - CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
# \+ s0 S; X7 G1 J' H& f - }
' G: k% y b% a( ^; Y2 A1 G( W - % V& A0 P( \5 V) t$ y
- /**- X) U( E; K3 H
- * @brief Configure the AWU time base to 12s5 h8 i8 P% n2 L: Y: R9 G
- * @param None
, i3 Q r; Y1 Y# x% ]' _ - * @retval None
4 r5 _7 L M2 P1 v& P& K/ n0 ~ - */
1 M, p8 C3 s0 | Z2 A1 ? e( ^ - void AWU_Config(void)
. J' l7 y% \1 ^ - {- e0 b) r2 @ k! o
- /* 初始化 AWU */9 D5 }0 d! J4 {) T, J9 S( T
- /* 通过LSI 校准AWU唤醒时间*/
' R1 u8 z4 z- W; |( H0 d3 L - AWU_LSICalibrationConfig(LSIMeasurment());8 S4 v2 b% r$ p% m4 ?
- $ J/ O* N! |+ ~! @
- /* 停机12S后唤醒 */
( Y8 a9 ^. U" T: l - AWU_Init(AWU_TIMEBASE_12S);- T0 n# M8 Y, c! M
- }2 p: s( h* m0 O H* o. }4 C8 K$ s
- % h0 j3 V* m; ~. p
- /**
: L' A1 T; Q6 l" Q - * @brief Configure GPIO for LEDs and buttons available on the evaluation board; S* a6 F% L: |& r: J! L
- * @param None
% s1 X h( F) P2 X - * @retval None" R; ^" z- Y% d {
- */# j# T v5 X- C l3 s
- static void GPIO_Config(void)
" O* Y+ i4 e. E1 N1 f - {# a2 O, d5 q9 H
- /* 设置外部中断端口C模式为下降沿触发 */3 L% r2 n$ {8 c( c$ \% r) d( V2 C
- EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_FALL_ONLY);
3 l8 [2 I) k6 b7 H - + ^8 C3 |4 v# E8 j* @
- /* 初始化外部中断IO口 ,悬空输入并使能中断*/
" W: [! b7 f9 X8 a$ {! s - GPIO_Init(BUTTON_PORT, (GPIO_Pin_TypeDef)(BUTTON_PIN), GPIO_MODE_IN_FL_IT);( ?$ T! y2 C+ Z& f K# x; k
- 6 S' U* Z5 A5 T' e+ }3 K/ c
- /* 配置LED1 IO口为输出模式 */
' W. R4 M1 o% B) x4 c+ U( v; k" U - GPIO_Init(LEDS_PORT, (GPIO_Pin_TypeDef)(LED1_PIN), GPIO_MODE_OUT_PP_HIGH_FAST);! t% N- S& r! B( t/ N3 \
- }3 ]; B$ ]! w2 u) ^, l
- % [( H/ Z$ M% P w3 L
- /**( \* l# J1 V; _/ S" R* g
- * @brief Measure the LSI frequency using timer IC1 and update the calibration registers.
& J3 J+ C. h9 s5 {' P' T, C8 l3 M - * @note It is recommended to use a timer clock frequency of at least 10MHz in order
2 q' X ~6 g4 e9 p$ u' u4 ~ - * to obtain a better in the LSI frequency measurement.' U0 [+ u6 d6 r; d, @
- * @param None c; ~1 V* D0 D' G
- * @retval None' Y" o# d& k# L/ k1 h) P1 K5 ~7 z
- */
e$ |( P7 P K2 F# X0 S - uint32_t LSIMeasurment(void)8 H) F/ y" B5 i" W
- {3 E+ r5 S$ G; ~3 l+ p! S
- W6 @/ s N5 q9 C2 H) `3 l& k9 y
- uint32_t lsi_freq_hz = 0x0;
' m$ U: `! } O4 T - uint32_t fmaster = 0x0;
8 h: z4 A. D. ] - uint16_t ICValue1 = 0x0;9 a" x" ?/ U* B( H& I) }+ K- H' ]
- uint16_t ICValue2 = 0x0; z" [6 H1 A2 m8 E0 q' }+ \' ?" F
- T5 b( \( _& i5 X0 Z: z- /* 读取主时钟频率 */% o0 M( d# e4 e* |% i( G
- fmaster = CLK_GetClockFreq();' y/ F0 p' F! j$ E
- " p% Q4 Q; [: d' z6 `; \5 O" f
- /* 使能 LSI 测量: LSI时钟连接到TIM1_CH1 */, Y& N9 P9 h9 [$ l
- AWU->CSR |= AWU_CSR_MSR;7 |" J3 w2 F; I+ M: w$ P5 z# Z$ H" {
- ( S$ o8 g; x1 Q; @5 ^
- /* 每8次捕捉一次!!! */6 o" [3 M# d3 n
- /* 使能TIM1捕捉 */5 O) X' G( z3 S' Q; w$ M
- TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0);2 ~* O5 U) G# q# D
- 6 d) q# x; u) H4 O/ g5 P& y: `
- /* 使能 TIM1 */) m# V- p {( P4 m7 ~% ^
- TIM1_Cmd(ENABLE);
6 G9 T+ \* n& { -
& C# Z: ^% ~9 @' G) T; U. z - /* 等待 CC1 捕捉 */
7 j L) E! }8 p - while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);
; w j$ s. D1 L8 F$ ? - /* 读取 CCR1 值*/
5 f8 i/ h5 I2 W1 S% p - ICValue1 = TIM1_GetCapture1();
" F- z+ S& C: x, B& d - TIM1_ClearFlag(TIM1_FLAG_CC1);
. @( a5 ]2 X& Y( V o% t - % ^" C- C' Q2 P* U# ^# Q# r/ s: `! {
- /* 等待 CC1 捕捉 *// b7 V, N; N6 W' B; E
- while ((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);
. Y7 c% T ~5 b - /* 读取 CCR1 值*/
i$ K! r1 E' e) T' n - ICValue2 = TIM1_GetCapture1();: k% |1 }( |$ I
- TIM1_ClearFlag(TIM1_FLAG_CC1);
+ |8 c; |1 O) c. w- B: D7 D3 I -
8 |" l$ O5 i! l9 e) b: l7 C4 O9 N - /* 关闭CC1捕捉 */
" l9 x: q: g' [% k( I0 o5 ? - TIM1->CCER1 &= (uint8_t)(~TIM1_CCER1_CC1E);
+ C6 k7 ?) L2 B - /* 关闭TIM1 */
0 U F5 B, W* U% d! ~! Q - TIM1_Cmd(DISABLE);: B, ? L: D$ d$ b" j! L4 a( ^
9 G2 Z# N2 U9 m9 w j- c- /* 计算LSI时钟频率 */
3 [6 P$ m; p. F5 X) n* }, ^ - lsi_freq_hz = (8 * fmaster) / (ICValue2 - ICValue1);# g( D) ^/ `! f* B- W8 M
-
* e- k- U0 m9 A( C2 |( `0 s8 h - /* 禁用LSI测量: LSI时钟从TIM1_CH1断开 */
( P( v' S# D3 |) J9 M - AWU->CSR &= (uint8_t)(~AWU_CSR_MSR);
) @% R& H. {- f% L$ v$ _8 T/ z# \ - /* 返回计算的LSI值 */2 o" Z: B5 d* A9 F( M0 N
- return (lsi_freq_hz);
4 m! @% G. O3 W9 x3 X* I* E - }
/ J: {) |! l! e - " H- q- V2 K) t$ b: @: m3 q
- /**# Q3 ]6 l. @1 `1 c i5 _# r: k3 l
- * @brief Delay.5 x' F& a+ s1 O
- * @param nCount
* |7 V7 y7 [% W6 p: C/ X5 O - * @retval None
& p, }0 D7 s5 A; Y' A - */2 ?& Q1 K. w1 L% ~
- void Delay(uint16_t nCount)& y& Z) b# h1 w0 x
- {
$ |" x% b) L. h7 V - /* Decrement nCount value */: Y, l, C5 x% Y8 }, {
- while (nCount != 0)
6 [# @9 D% B7 {' B7 r& j2 i- R - {/ e0 P! R+ j" D% N
- nCount--;) g5 C( Y( L0 w6 H
- }
3 v0 s: a1 ?% {" J2 B' W - }
复制代码
- I" @! l! V- _9 X0 n, `* `4、编译运行:5 i6 `* s4 V( R$ R" q* ], `( g' m
; @4 ~' M/ ~2 m* u0 d
$ U0 @1 J1 M# u
5 Y% F- K1 f. b# {% O/ R$ B
; A% W1 b+ ^ X9 @) E |
已收藏