本帖最后由 zhdzhd-174422 于 2019-2-27 20:14 编辑 " Q$ ^- f8 A: z
; f* ^7 O3 O; a% z3 Y
AWU是用来当MCU进入低功耗的活跃停机(Active Halt)模式时提供一个内部的唤醒时间基准。该时间基准的时钟是由内部的低速RC振荡器时钟(LSI)或者通过预分频的HSE晶振时钟来提供的。STM8S的LSI时钟测量在使用LSI低速内部时钟时,为了确保最好的精度,它的频率可以通过TIM1_CH1来测定。* z% V3 i! g; K7 I- Y+ R% o
; e- c3 n# i5 m2 b9 n9 L0 F- a$ B9 D
1、复制官方AWU工程文件:
1 ~8 y5 `! {9 E2 _& D: g- I
- S5 {, {- G9 L0 H2、打开IAR工程,先清除上一工程的编译信息:
" t& o6 X% C( t$ O% t% X U
/ L$ i9 k7 ?( D" h7 X
) }! z( i" E8 B# a3、修改main.c文件:- /* Includes ------------------------------------------------------------------*/
9 Y* e8 R( J3 b* U& e- Q - #include "stm8s.h"* x3 L' B7 n2 [6 x2 G
- #include "main.h"
% j( q$ C# g8 L& ^ - % `7 b0 z! T& B" Y8 H
5 O- }' q' S# H. H; P2 F- /**
: P D/ R! @! s - * @addtogroup AWU_ActiveHaltMode
" ^2 h+ H* ~4 p% z6 r2 ? - * @{
% ~& o8 @) E9 x8 G( E9 x8 W' F' j* Z - */
, e: o' g/ S8 \ ^4 R
9 A5 A* {" F7 Y- /* Private typedef -----------------------------------------------------------*/
/ F, R- c, [% }1 A - /* Private define ------------------------------------------------------------*/
: O3 P1 E* l/ i3 L3 k0 y. x$ b - /* Private macro -------------------------------------------------------------*/: ?$ u/ l: g: R4 Q
- /* Private variables ---------------------------------------------------------*/: g7 }4 p1 \" \( |
- /* Global variables ----------------------------------------------------------*/0 J: K Z/ P" ~! }
- bool ButtonPressed = FALSE;
" `! `: a0 W# I7 A+ o0 l - /* Private function prototypes -----------------------------------------------*/
' o/ P$ ^3 h# y+ X1 `$ _ W - void Delay (uint16_t nCount);
" l: K. p9 P& N( @% J* I5 c - uint32_t LSIMeasurment(void);; i7 `$ c* V( N# D& x/ \) s0 [9 R: @
- static void CLK_Config(void);) B0 D9 d" i9 P
- void AWU_Config(void);
( O" X. H* t7 A2 e - static void GPIO_Config(void);, L% ]! O4 c1 }+ N" a9 _
- 7 l7 }( e$ M" K- D3 [4 \
- /* Private functions ---------------------------------------------------------*/! \+ `0 r4 G; \/ R
- 5 I, f- d! s+ j3 H. s/ {$ W
- /**' W) K& E) D$ I; f* E% T
- * @brief Example main entry point.
; ?+ M \. h- `6 y. N. ]5 z - * @param None" g" e; R6 z, k+ y* F8 P
- * @retval None% H. n9 g) h3 w+ H7 j+ m! u# |
- */
, X, E6 X) t, s" N- p - void main(void)
& u- C0 a" h) ^: v - {
, Q9 ]+ }6 c$ k - uint16_t i = 0;1 }) L j* P1 g) g* e. J/ u% s
- uint16_t j = 0;
9 Q, Z- g9 Z4 ~$ i) Y9 y - 9 F3 i. S& a9 |. {; k
- /* 时钟配置 -----------------------------------------*/' F* F' d5 _. a' a& U6 l
- CLK_Config();% }9 l* t& }0 U0 e5 `9 Z
-
y9 j# N; H1 T! f7 @ - /* 端口配置 ---------------------------------------*/
- Q2 Z$ T7 X& ], u) b2 |/ a2 K3 ~ - GPIO_Config();
4 G6 Z: u' j! R& U2 R -
( U5 A( t8 |; c! B6 M4 F9 y - /*AWU配置 --------------------------------------------*/
1 g" h% A/ j8 k- C% ^# Z - AWU_Config();
) i8 Z& r5 D4 B* o) ]7 ] - 1 O: f4 C, ~; D
- /* 使能总中断 */8 H k/ J. D" Z7 n d
- enableInterrupts();
6 \7 W4 L- f! g9 e
* x" \! T" F4 m- while (1)
5 B7 q1 y' F, _0 l( P T! q - {
9 G8 }/ @& x- T% y5 q% ^ - /* 按键扫描 */
# _+ G5 i6 ^8 \' F& X5 ? - if (ButtonPressed == TRUE)7 h" B! F: c1 z4 R
- {6 Z! c$ f! i# S
- % d) a! C3 T9 V$ ~' j; f
- ButtonPressed = FALSE;: H+ f* ?4 W3 @$ d
-
' n; f w9 x( K& n - /* LED快速闪烁 */
: n) U! L7 d) I+ v: [7 O - for (j = 0; j < 20; j++)9 {- k# Y1 U. ]- q6 _
- {
' }/ c& Y; W! \ - GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);3 ~9 F9 j" k2 m$ g7 o& O
- for (i = 0; i < 5; i++)
; {7 }, v: V [( v, X/ k' H - {( B; I: V; Q' y
- Delay((uint16_t)60000);( n6 V# K/ d# ^2 p
- }, @1 @$ ]9 i) l# L
- }: C. R$ t6 o9 E% I
2 c% t) r& B) e$ {: T- /* LED熄灭 */
( \' o8 I. d( e" s! ^/ l - GPIO_WriteLow(LEDS_PORT,LED1_PIN);; J; U: a3 H& I, r5 o& S, d0 ]
- /* 进入停机模式 */! }$ t* Y6 V' W/ X& m [+ u6 x
- halt();
( w( S! M# r- w8 j7 K" {( D; R4 h - }) k4 N& b( D/ B8 l
- else
: I/ t3 w2 }/ \; x0 K0 o - {
* k( X6 O% A- V2 q. @ E' l - /* LED慢速闪烁 */3 S! `9 w: e( d6 l
- for (i = 0; i < 15; i++)% Y7 N" X( e R1 \
- {
& V( w. }4 F1 S& ^# G) [& T( t - Delay((uint16_t)60000);
" W" N8 L3 M3 S' v$ j$ ^ - }
1 U; s+ ?0 @/ V7 X) t - /* LED反转 */+ `. t1 Q% p1 \8 L: F) a, N7 @5 x
- GPIO_WriteReverse(LEDS_PORT, (GPIO_Pin_TypeDef)LED1_PIN);
0 E$ ^0 ?& q5 i3 X9 K, W - } n `" O3 h3 e0 B0 L2 s" `" L
- }2 X+ D, R; H' p& k
- }
0 Y0 U# S& u8 [2 d2 ]
1 d: M1 F9 R3 |7 h# Y- /**
/ E. a1 z2 F( i' h - * @brief Configure system clock to run at 16Mhz7 ~1 x5 Z4 W. ~5 V8 y
- * @param None
7 o5 F6 d# H* e, v$ @* {* ~ - * @retval None* L7 L7 ^ r( i2 [( x5 U
- */- Z, ^7 ], ?( F
- static void CLK_Config(void)
) ^0 |) e) U( A/ r - {
8 b/ x M1 j, t& ^) M - /* Initialization of the clock */- F! h% j1 t( t `6 i) ^5 U
- /* 配置HSI分频率,CPU分频率1 */6 O$ o2 Z) m6 D7 h! }( W: w
- CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
% Z+ A9 u0 x6 s1 m# Z: s6 F3 k9 H - }
0 i3 J0 } k0 t9 u( I
1 c b' t" r6 ?4 Y/ o1 x- /**
6 }& [# n) ^% r, c! M- Y+ ], ]/ A8 \ - * @brief Configure the AWU time base to 12s5 ^* a$ A- h. U
- * @param None- l2 F9 i3 q' g. j/ U/ |
- * @retval None! J8 x* d: c7 U, I& w
- */5 S: M3 N+ ?( S4 t
- void AWU_Config(void)
h$ J) s: v8 S- X3 m+ b7 l+ e - {
7 u5 Q- f1 C1 G% Y- B9 g - /* 初始化 AWU */
Q+ K, r2 O/ ?- ]* l9 D( _3 b3 p- ^ - /* 通过LSI 校准AWU唤醒时间*/
4 L8 H3 {, E6 @7 G/ s0 B* G' e$ C5 n - AWU_LSICalibrationConfig(LSIMeasurment());
+ `& w1 M1 A6 W* c! e - . o; i4 T; n2 G7 j% |
- /* 停机12S后唤醒 */- V1 A$ H9 [& w, k6 H/ c+ h
- AWU_Init(AWU_TIMEBASE_12S);8 u' z) \! U" _% a3 w
- }- V3 H, x$ v$ k1 i' I- [
8 ?; z0 Q, `5 G8 \- /**& [* _% Z& M: X' a# |7 y7 F
- * @brief Configure GPIO for LEDs and buttons available on the evaluation board7 @7 J3 E$ r: e0 o G2 g
- * @param None
5 h6 A# |4 m( s$ ?+ C5 h* |+ ~! o - * @retval None# J7 R# z5 d* r2 ]
- */
4 G3 c4 d9 E. ?$ A q$ a% k* c+ b+ J - static void GPIO_Config(void)+ i1 A, W6 P$ X* ^/ V6 K6 G
- {
, c1 |' W X) [7 v2 y) S5 ? - /* 设置外部中断端口C模式为下降沿触发 */
* {9 d4 i# ]! a, i8 G. _- p - EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_FALL_ONLY);0 o( E2 i& K' m6 V
- i2 Y! X8 ]# T2 g
- /* 初始化外部中断IO口 ,悬空输入并使能中断*/$ d0 {! R2 i" ]7 _$ |
- GPIO_Init(BUTTON_PORT, (GPIO_Pin_TypeDef)(BUTTON_PIN), GPIO_MODE_IN_FL_IT);
9 p W4 g8 Q3 _7 `5 N' w - , z, E6 T# M0 V, ~3 x4 D
- /* 配置LED1 IO口为输出模式 */
" r8 s8 S# \2 v- x+ S - GPIO_Init(LEDS_PORT, (GPIO_Pin_TypeDef)(LED1_PIN), GPIO_MODE_OUT_PP_HIGH_FAST);
9 J0 P7 U5 V1 \1 n9 V - }8 I- h- t! e, r3 Y5 I" r
- [, @' E. A: c9 k- o5 Z6 I- /**
0 q; T2 P) b" |% U% Y2 R - * @brief Measure the LSI frequency using timer IC1 and update the calibration registers.% c6 P& d2 t9 y) P& d0 f9 Z( a
- * @note It is recommended to use a timer clock frequency of at least 10MHz in order * S; h: A) w4 u( @
- * to obtain a better in the LSI frequency measurement., x* \9 y, ] q
- * @param None
$ | E3 b: V0 A( L3 ?; d' s; y - * @retval None
! U" k1 b" e( \) K - */ w" I' E* Q5 |: f
- uint32_t LSIMeasurment(void)6 e; H" h7 C5 g+ C( t
- {
2 j; ^3 a2 H, w0 C% q - # L, F9 d! S0 K0 C. G
- uint32_t lsi_freq_hz = 0x0;3 y5 }/ A- t% X0 d9 C* I
- uint32_t fmaster = 0x0;, @/ B9 n2 u/ y5 z; ]" x* F
- uint16_t ICValue1 = 0x0;
; q/ {$ {5 d9 r7 C - uint16_t ICValue2 = 0x0;
1 B- d% Z6 ^6 ~1 T0 J9 @4 W1 T6 w
- ^7 _. o* n; d' Z& j: w; Y! j0 N- /* 读取主时钟频率 */
$ i" d. {6 o: ? ^' E - fmaster = CLK_GetClockFreq();
4 k2 ?9 |8 ]5 l; ?: @+ s
% r# Z/ T) x3 A- /* 使能 LSI 测量: LSI时钟连接到TIM1_CH1 */
2 D2 n' x f D s6 o6 y4 ? - AWU->CSR |= AWU_CSR_MSR;( G/ x0 o# s# a' e4 q/ _5 P( H
5 t l3 `" @; d3 G' l- /* 每8次捕捉一次!!! */
2 D/ f1 F: _! Z P% _3 o - /* 使能TIM1捕捉 */+ @2 D& g8 I- n3 a- h3 C
- TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING, TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV8, 0);% _$ \$ h! l; E/ o9 N
- 4 k4 K- Y3 }0 `) I4 R" w
- /* 使能 TIM1 */
- s+ D6 u& v; U) S- {$ k# d - TIM1_Cmd(ENABLE);& v' n7 a1 q2 x i
- ) l' j }4 G, }2 ?" z
- /* 等待 CC1 捕捉 */0 q1 }( m2 d( X k" G5 I
- while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);
* O/ m4 y6 `* X2 V - /* 读取 CCR1 值*/" Q8 p# S( u, G. u8 `- `5 ^* D( E: E
- ICValue1 = TIM1_GetCapture1();/ N6 y% x' P8 E& K* S' R
- TIM1_ClearFlag(TIM1_FLAG_CC1);/ c# C5 I7 w- L/ S, s
-
# y$ `/ T& P3 F/ W. z4 K6 F - /* 等待 CC1 捕捉 *// o* D% f8 U; N3 D$ q
- while ((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);9 N( B3 P: D" c) v4 d( l
- /* 读取 CCR1 值*/8 q& Z3 f6 c6 z* y0 @) z
- ICValue2 = TIM1_GetCapture1();# F: `8 Z% T: l( T0 h5 i$ z
- TIM1_ClearFlag(TIM1_FLAG_CC1);
: I: ?0 `( t, i5 o5 b+ S - 8 s! V4 S% c6 _- {7 E
- /* 关闭CC1捕捉 */( B" B( ~2 r, t! r/ f* |# x
- TIM1->CCER1 &= (uint8_t)(~TIM1_CCER1_CC1E);
( ~) O9 H0 |3 [% H6 O. f - /* 关闭TIM1 */( m( c+ g, w% c% ~+ T
- TIM1_Cmd(DISABLE);! T1 r* p3 A) f. g0 r
W1 e# q8 }# M1 G- b2 y* V: _- /* 计算LSI时钟频率 */$ h9 n/ c1 O$ I1 A/ k
- lsi_freq_hz = (8 * fmaster) / (ICValue2 - ICValue1);5 E+ M. ?( j/ g, j- e
-
a3 Y- ]( w1 k$ O* {/ L2 U - /* 禁用LSI测量: LSI时钟从TIM1_CH1断开 */. e0 m5 b; R5 ]2 E/ L# m" u) X( p
- AWU->CSR &= (uint8_t)(~AWU_CSR_MSR);6 d: s% F z ~1 V( V7 K
- /* 返回计算的LSI值 *// S. C4 L' S/ C) w/ i0 h' C& L* x
- return (lsi_freq_hz);
/ f5 l3 |& R* E* ^: i - }4 X' H1 M8 f% R% Q4 C3 [3 _
+ `2 w2 D: i: f6 d4 v5 Y- /*** q |+ v! v* f3 F3 E
- * @brief Delay.
3 f9 ^. H* t1 a6 `2 v" _# N - * @param nCount
3 X$ q' {5 p3 A3 g. C- A* G - * @retval None; t6 l4 m0 o; V' t. V6 n: N
- */) f, w7 u( P0 y
- void Delay(uint16_t nCount)
/ O. `3 r% v2 Q4 ~ - {
* {3 M& N; x/ O - /* Decrement nCount value */" u% |+ F/ c7 \& W! ~
- while (nCount != 0)
; ~2 w' H) k7 z9 l: M - {
3 e" i1 B) S! |# P6 Z - nCount--;
+ U* W0 x9 ~/ x2 t2 g | - }: J& {; F. T: j% {5 a2 ^
- }
复制代码 3 }8 X. Y" P8 P+ u; E
4、编译运行:
* z9 W; j( `5 _: x( B. ?) A0 F
$ }9 {( Y! l/ i- t& ~# a7 H$ c, b# P
N! F3 d# M3 {! j* a" y; R0 j2 [9 I+ M) Q! a. {/ a
|
已收藏