本帖最后由 zhdzhd-174422 于 2019-2-27 20:14 编辑
) d2 x$ G. _- L/ o
8 ~$ n$ s" |! ?8 A9 V AWU是用来当MCU进入低功耗的活跃停机(Active Halt)模式时提供一个内部的唤醒时间基准。该时间基准的时钟是由内部的低速RC振荡器时钟(LSI)或者通过预分频的HSE晶振时钟来提供的。STM8S的LSI时钟测量在使用LSI低速内部时钟时,为了确保最好的精度,它的频率可以通过TIM1_CH1来测定。; M7 g/ }% f# h# n$ h1 Z% G5 X$ }' E- k- n
: I5 Z* D% K# v! Z3 f- q r
1、复制官方AWU工程文件:
# K- p6 L' F, Q. O# [
: E, ~. ?8 J8 P" |" M: z
2、打开IAR工程,先清除上一工程的编译信息:
/ S3 E( ^& g6 D9 }! _
6 P7 [6 Z' r- u3 K, J1 Y$ m: T! r& s
3、修改main.c文件:- /* Includes ------------------------------------------------------------------*/
+ U, f3 s( t" D& M3 ^7 s - #include "stm8s.h"
w, U/ h1 E D8 u+ O - #include "main.h"9 S% ?( |% t4 M0 S
, u' C2 e, {$ t8 v& W1 N; l! m
; z7 p. j1 I: }. w# R, ~% ^8 T- /**5 \3 t- Z0 x& j+ A/ d3 t
- * @addtogroup AWU_ActiveHaltMode
4 z+ L! |! Q4 B - * @{
/ h+ ]# |! q0 f5 w% A. p# m P - */; c7 r1 a2 I0 T5 A; I$ A& w& a* x
- 7 l3 m! q3 C( z8 W Y% r d
- /* Private typedef -----------------------------------------------------------*/2 ^. O0 P' f' ^5 z$ l5 O+ _
- /* Private define ------------------------------------------------------------*/
+ D, n; n' \3 w9 g - /* Private macro -------------------------------------------------------------*/% {! ^/ ~/ X! w6 ^, g1 J
- /* Private variables ---------------------------------------------------------*/
* n3 k( o9 _- r8 v' D; w - /* Global variables ----------------------------------------------------------*/
- ], i- H8 @; w: l - bool ButtonPressed = FALSE;' K8 }4 j, M1 z6 Z P
- /* Private function prototypes -----------------------------------------------*/$ k% [' C: `6 d
- void Delay (uint16_t nCount);. _1 w- r4 u1 j4 }% O+ a
- uint32_t LSIMeasurment(void);$ b- K$ i- k8 o
- static void CLK_Config(void);
$ u6 ~5 P2 E. L: i& O, s4 F: @& Q X - void AWU_Config(void);/ [7 y6 E9 @0 ^6 n+ E
- static void GPIO_Config(void);
D- U8 o* V, m/ n8 k f
L" O5 @. h, F% l4 n- /* Private functions ---------------------------------------------------------*/
$ U% T2 E, C; ^2 M, r6 v
4 X3 `5 D9 w! }3 M1 p! q- /**
7 A- K+ S, x' Z* c5 u6 E; q - * @brief Example main entry point.- k3 b6 g3 \* |8 s
- * @param None
: u% j- q( d4 K1 p, @ @ [. g7 n - * @retval None
$ }1 L- r: W5 _6 t" x - */
% B8 o- p4 j0 E6 C' ]' o - void main(void)* h4 q: @. o" O/ A0 G$ J
- {; r8 N# b2 `- n! e
- uint16_t i = 0;8 a1 i5 S/ O# D7 t' V
- uint16_t j = 0;" Z! t% q/ B' H
-
* r- T. [. P/ ~6 h: y( s" ~: @ - /* 时钟配置 -----------------------------------------*/
) ~; J0 k5 y7 W( l - CLK_Config(); B c" g v1 [3 n# I
- . }, P; ]" r: F: p; F
- /* 端口配置 ---------------------------------------*/
c8 f# D- E* i1 O! h, z4 ` - GPIO_Config();
# a- d6 |5 M$ G3 \$ U - ' p _3 _5 B4 k$ F9 {6 Q# ?1 Z9 g6 P3 c
- /*AWU配置 --------------------------------------------*/
9 G# Z. d3 x* h& f$ X7 e* |" G4 H - AWU_Config();
% n( A5 k- a3 ~8 O* X' k. t/ r7 B
# H; z4 H3 C" z2 g! o- N( V) F- /* 使能总中断 */( p) `0 a9 g' u: J( R5 s' }# ^
- enableInterrupts();9 b. c0 a+ M2 \. t8 K G4 }: Y
3 s8 ? M0 a$ ~8 I7 _5 I1 O- while (1)( B9 U3 _- b8 c6 I& u# M
- {3 @4 I2 W2 E1 [) J
- /* 按键扫描 */
8 k* K; V$ A" I, ~6 W5 h - if (ButtonPressed == TRUE). l8 P, m! E6 J1 w3 R) Y4 t9 n
- {
- B3 _# x8 k; V1 q6 p% E# G - ! `3 U5 D1 @- Z# m3 ?' @5 W0 n; |
- ButtonPressed = FALSE;( u8 C" V$ D1 P
-
2 k1 v& s6 \9 V; F - /* LED快速闪烁 *// l5 W0 d4 j; [! p( ?
- for (j = 0; j < 20; j++)
5 `; D; f R) r: E4 M* \4 ] - {) Y; K* m( Y8 I A' w0 [
- GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);
0 `3 \- D8 Q# i8 G' P2 ^5 { - for (i = 0; i < 5; i++)% C5 \! i# e) F( a
- {
( `& L1 {& t4 d9 g - Delay((uint16_t)60000);
7 f$ `9 w+ `$ j/ F - }# P$ P3 w8 J) F+ [1 d# ~2 @6 P/ V1 l( ~
- }: ~8 [, {( s/ @7 F' h# I% Y/ j9 z
- 1 F2 E1 l4 U9 h- C# S; I
- /* LED熄灭 */
1 U! Q8 q3 s7 l/ s: G9 O - GPIO_WriteLow(LEDS_PORT,LED1_PIN);
' S8 b" ^1 U' ?, X* [ - /* 进入停机模式 */
% z0 w' h' s0 L. ? - halt();
7 U- r6 k4 M( d0 q3 I. _- c5 Y9 H - }8 Y& r7 _, J' d3 u
- else
8 O( ]/ W* j4 T1 F$ a f% y - {
/ y p0 C4 [7 a+ p( k" b - /* LED慢速闪烁 */& n/ @1 o% S0 r# |( |
- for (i = 0; i < 15; i++)
( k2 Z; {0 Y- W* ~. n |! g - {
6 S p- X7 n! ?3 j+ {" ] - Delay((uint16_t)60000);) {, \" O9 o1 V" I5 ^* w$ L! I2 f
- }& L) @5 v: O' j& a
- /* LED反转 */0 d! Z8 w6 a. s9 T; s8 p
- GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);
' Q3 {6 k! r8 {. y9 ]6 O3 m" S - }& d* `# x6 u, K: @& U6 L7 L
- }
$ [( N( L7 v, C - }
2 [! Z- c* x- z9 W3 p0 j& q
2 w- e g$ O3 T9 S) A6 B' W- /**
9 o" y k4 @, i7 v" r - * @brief Configure system clock to run at 16Mhz0 F0 s2 D( O+ ]2 q; L9 H: x- F
- * @param None2 b% m! n/ I" x, | E* o# o
- * @retval None( d) H6 w/ h: M" X1 D
- */" z6 p8 D2 Y" F8 i+ t4 k
- static void CLK_Config(void)- f6 ~8 \6 P: }" {
- {: A# a' H8 G+ a+ W: s, J
- /* Initialization of the clock */1 s- o% I, S+ {
- /* 配置HSI分频率,CPU分频率1 */
2 s- }& W I' X; O - CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);; @2 h; w( ]8 _4 Y3 D' U+ p
- }5 k V, I. b, G& p8 v! e
- 1 J# i1 V; @3 Y
- /**
( `' Z* O. a$ M. _ - * @brief Configure the AWU time base to 12s J8 Q* Z f4 _
- * @param None
# z% Y% ~* p% h! p3 c - * @retval None
; Y, @) W( k1 D0 [" K* Z; l - */
& u6 c1 o0 f3 V9 L/ e4 t - void AWU_Config(void)1 T' G( o4 D6 @5 C* l8 P0 o
- {* M: d( c2 Q8 e& n0 `& l g Q
- /* 初始化 AWU */
' N" s+ ?0 J4 }7 l: I - /* 通过LSI 校准AWU唤醒时间*/
' \; U7 N) F, q; z+ r8 U - AWU_LSICalibrationConfig(LSIMeasurment());
$ b* d* c% S) T9 C* }0 a! ?8 @2 x -
5 G" Z% {1 ]+ ]% |9 S' x* | - /* 停机12S后唤醒 */9 U- v. }& o9 q2 g3 ^9 d$ }
- AWU_Init(AWU_TIMEBASE_12S);4 r8 C( L; o. M- ?% X5 Z9 R. T2 j
- }
( C/ t4 E i' t: P
- p" [7 p: M; c! n) U- m- /**8 K+ U/ j3 A0 M m- M6 n5 U/ h
- * @brief Configure GPIO for LEDs and buttons available on the evaluation board
) {' X# L; U7 ?, i! L4 Z4 c9 I - * @param None
. t& q/ G" _# j, M' l - * @retval None) `* g) O9 n* \+ u7 V8 r
- */
: H+ O5 ?. G+ d" g( c - static void GPIO_Config(void)
- S, u, B1 O4 e$ y) w+ G - {2 }2 }; G2 \) {0 H& k
- /* 设置外部中断端口C模式为下降沿触发 */
8 x. N' Q! [0 F- P. I5 m; X - EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_FALL_ONLY);( z7 y0 |# z8 F. |
- . K% o6 F E1 L1 d) O
- /* 初始化外部中断IO口 ,悬空输入并使能中断*/% v f* p5 p# n3 v8 ^
- GPIO_Init(BUTTON_PORT, (GPIO_Pin_TypeDef)(BUTTON_PIN), GPIO_MODE_IN_FL_IT);& @4 b4 ?% k+ H1 V
- ) i0 K; X5 F% v1 [+ X
- /* 配置LED1 IO口为输出模式 */
) z5 F, ^0 m, a) c$ l; f - GPIO_Init(LEDS_PORT, (GPIO_Pin_TypeDef)(LED1_PIN), GPIO_MODE_OUT_PP_HIGH_FAST);
) e& K5 C( E9 M0 L - }
, o$ a- |1 D/ |5 ^0 ^/ j& |
5 v$ U$ ~$ E( J. e. v- /**
- \2 q9 w7 x; M0 Y0 e- B - * @brief Measure the LSI frequency using timer IC1 and update the calibration registers.
( D; U- E; u+ n8 M - * @note It is recommended to use a timer clock frequency of at least 10MHz in order
" {2 [& Y7 L3 @1 s8 l - * to obtain a better in the LSI frequency measurement.
) t w8 ^4 n1 b" c - * @param None
2 L$ ?# F; t: M& C6 b6 d* q$ A - * @retval None
4 m, T; x+ } W3 u - */* a8 b. Z6 O& }# @+ M8 X
- uint32_t LSIMeasurment(void)
* e% x+ D# h7 }& J0 f+ B' a% d: u - {5 H2 J8 H( g( m( D
- ( Q5 q5 O7 _; l7 z; r8 ?$ p
- uint32_t lsi_freq_hz = 0x0;4 _1 m w( d# m) p1 g8 m
- uint32_t fmaster = 0x0;
0 ?/ l( ~5 K/ B- ]9 |/ x - uint16_t ICValue1 = 0x0;0 \8 p, @- \6 D D* b! j
- uint16_t ICValue2 = 0x0;' g, B& X) k% C. w0 {6 J
; @2 i, x% E; H& l; {, f" r# T+ T- /* 读取主时钟频率 */
) V2 l8 i$ ^, L - fmaster = CLK_GetClockFreq();
3 A* j6 @- [# r' a! t$ [
, `, w1 Y0 m; W+ j- /* 使能 LSI 测量: LSI时钟连接到TIM1_CH1 */. B; ~& O, n5 J/ b$ o- H, i
- AWU->CSR |= AWU_CSR_MSR;
6 p7 V/ J, S3 o& F1 {: R8 v
* B2 ~. e/ Q' b9 Q2 I- x- /* 每8次捕捉一次!!! */: K: D# b9 }+ r% I4 v+ Y
- /* 使能TIM1捕捉 */& B# Z; J$ S1 _( I
- TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0);
I' Z; r* W# p8 q# L* [ - # ?/ ~; z3 I4 P7 ?( ], e; f( M
- /* 使能 TIM1 */+ _% F0 U- v0 g. S$ K' H
- TIM1_Cmd(ENABLE);# z5 z& e, R2 E9 S" w8 W
-
! f2 `1 z7 I- ^ - /* 等待 CC1 捕捉 */
% x6 [& y0 e: r3 x' L - while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);0 s( B" y6 ]: {/ l7 c/ p) d
- /* 读取 CCR1 值*/
. T* C$ R. @% V, @% A0 m5 v - ICValue1 = TIM1_GetCapture1();
! L( ^. U3 D3 ]. U3 E: z6 p e* L# L { - TIM1_ClearFlag(TIM1_FLAG_CC1);, @) Y/ c/ C$ {# {; p1 x
-
# y1 |/ N2 c. ?6 I" ~1 d7 ]7 m - /* 等待 CC1 捕捉 */9 }- a8 L3 R, s. I( ~
- while ((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);8 M2 B8 n1 Z) E0 M
- /* 读取 CCR1 值*/
) f W2 F4 q0 q. f5 a - ICValue2 = TIM1_GetCapture1();8 v1 J; g3 ^2 Z( Y, a5 j# X
- TIM1_ClearFlag(TIM1_FLAG_CC1);
# l* a5 a; S/ |; B( x4 k! b - 9 }. W' \+ R9 p, x1 o2 @+ W& @ A9 k
- /* 关闭CC1捕捉 */
; X B& B* G/ D - TIM1->CCER1 &= (uint8_t)(~TIM1_CCER1_CC1E);. e* w! [$ O# `& J( Y; q9 Y
- /* 关闭TIM1 */
! q) g5 W& u: u" S8 W - TIM1_Cmd(DISABLE);
8 k0 H/ Q9 O& C3 \- N8 Y. E: b. M - , e% ?; ]' s- u% [
- /* 计算LSI时钟频率 */
- L M$ P7 I5 X6 a+ ] - lsi_freq_hz = (8 * fmaster) / (ICValue2 - ICValue1);
5 t$ _7 Y" ~8 B y( x C( k5 l - 4 j; K. B8 m, w( i8 _
- /* 禁用LSI测量: LSI时钟从TIM1_CH1断开 */
" k; Y1 Z" P) l8 E, Q5 x3 p* A - AWU->CSR &= (uint8_t)(~AWU_CSR_MSR);
' b2 u1 }6 X, ? - /* 返回计算的LSI值 */
& {- d3 U1 j. @* ~ - return (lsi_freq_hz);
2 r o$ y6 {0 m - }3 a! {7 S% z% }# w0 J3 E
- 8 \2 G/ G- X8 Z6 u3 {2 a* W
- /**
3 h$ o7 z% X6 l. C4 M) l - * @brief Delay.
* C) H, J2 i+ | x! k0 M5 W - * @param nCount7 Q% P m8 F5 z/ p5 j- s
- * @retval None
6 h: h. w k9 {% o3 E - */% r6 h& s) O% O" Q8 ~; K
- void Delay(uint16_t nCount)
, ^5 k5 s4 I( m( ^7 D" z - {
& H4 b2 I+ K# m - /* Decrement nCount value */
}/ o6 m0 M' q; H - while (nCount != 0)- t7 s4 |: i; p5 S o5 M# i) {" S" ^
- {+ @7 C3 W) J+ K( O9 b
- nCount--;) q, f3 ]1 K2 b; `9 }
- }9 A) M. y& g% D5 k/ w& E! _, @
- }
复制代码 : X$ E' ]+ w. P, ?. s
4、编译运行:
' C5 J! y6 M; H& I `+ p' s& u+ Y4 G
4 c5 H5 J4 J% n! m' ?# c
L; [ @* s9 I. _6 S* h( J
9 |! S5 R& a# p. R" ?) O- W3 Y
|
已收藏