EDA365电子工程师网

标题: 华大M0+低功耗MCU RTC模块示例程序 [打印本页]

作者: deepskin1213    时间: 2018-2-9 16:53
标题: 华大M0+低功耗MCU RTC模块示例程序

) B+ o* i0 R$ [. y' x4 X
/************************************************************/

6 e9 M, d; l( P2 G; B6 H0 p0 j+ |
/*******                 样例使用说明           *************/

  {% d! |4 o$ q- j) @
/*******                    版本历史            ************/

& q: C1 z+ G$ j$ d7 A  f: X
/*******  日期       版本    负责人  IAR   MDK ***********/  

6 J6 J0 G# @2 N8 q) n
/*****    017-07-14     0.1     CJ    7.70    5.14 **********/
6 w4 U+ `8 |1 x. N2 v2 N1 @; D
/*******  QQ:3386208645                       ************/

7 O& a% X5 g- u& m8 v4 p3 y

: J- f1 w0 P2 ?9 |9 N1 H
/*******               功能描述                  ***********/

& t0 W/ d: e* L5 y# v
/*   本样例主要涉及时钟模块计数寄存器的写入和读取**********/

. \- j, m& ?& a4 Z" |
/*说明:                                       *************/
/ u0 m/ @9 T7 _" L: j
/*计数初值写入计数寄存器                       *************/
; Z& B' c- K) {$ J- `+ ^9 {7 E
/*启动计数                                    *************/
- F4 u# ?0 j% p1 t5 w
/*读取计数寄存器数值                           *************/

: Z1 N* g! ~6 K& ~( @  B
/******* 测试环境                              *************/
/ k/ a) A, H6 s3 N$ V
/*     测试用板:                              *************/

7 U+ u$ T) ]6 @& C& u% l( G
/* SK-L110-TSSOP20 V10                        *************/

+ A% P9 E3 S( W! y# r
/*******辅助工具:                              ************/

; _/ x' q8 p# l1 T" [! \+ J- s* i
/*  JLINK调试工具                           *************/

  a; F1 Y, ?- w
/************************************************************/
" R/ f) }, j0 F$ U- O3 t+ A5 ~
#define IS_VALID_CLK(x)             (RtcClk32768 == (x)||\

7 ^4 u0 m' h+ w
                                    RtcClk32768_1== (x)||\

- k( A+ }( L* _
                                     RtcClk32== (x)||\

, D4 B5 v9 R' k( e4 }
                                     RtcClk32_1== (x)||\
) p3 i5 L( ?' n4 F) m" v# J: i4 _
                                    RtcClkHxt128 ==(x)||\
5 N- a( L; J  M, d. X( z' M0 B, y
                                    RtcClkHxt256 == (x)||\
! `: s& o# U, S1 j" h/ F
                                    RtcClkHxt512 == (x)||\
/ e, K0 J, {8 L
                                    RtcClkHxt1024 == (x))

. _  T1 f6 v5 h$ q6 O

2 Q$ ]/ W% H; i' \. _' z4 ^# z
#define IS_VALID_CYCSEL(x)             (RtcPrads == (x)||\

6 Q6 B" q0 _" _' F, o# B
                                 RtcPradx==(x))
% I" e* L8 ~* m; c
* g6 R# ?1 b- @! u  F& r
#define IS_VALID_PRDS(x)        (Rtc_None == (x)||\

/ h5 `8 v4 z# b; C1 I
                              Rtc_05S == (x)||\
+ w- r/ y$ L; X8 x5 @# f0 e
                              Rtc_1S == (x)||\
9 c0 T$ c* @/ |$ D
                              Rtc_1Min == (x)||\

& j7 v3 C1 x% b& o! u/ M+ N* M
                              Rtc_1H == (x)||\

8 f7 v- u- c: B9 b) b
                              Rtc_1Day ==(x)||\

1 j! G1 `, H  n4 I0 V
                              Rtc_1Mon ==(x)||\
% B9 t( r9 d/ a6 E
                              Rtc_1Mon_1 ==(x))  

8 d0 _( G- e0 i" x& c
4 a" J. U( O) z5 }
#define    IS_VALID_IRQ_SEL(x)      (RtcPrdf== (x) ||\
" C) n1 T6 X/ e8 ^9 u0 [
                                      RtcAlmf== (x))
8 F/ W6 p3 f) {
9 W5 {/ }9 Z+ d& H5 @- K3 T" k
#define    IS_VALID_FUNC(x) ((RtcCount<=(x))&&\
8 q- ^2 E7 l; S/ g) Y
                              (Rtc1HzOutEn>=(x)))
+ J  h" w( h4 q
#define    CkDateTime    0x7F

' v, W  }# |4 @2 ]
#define    CkDate        0x78

2 g7 N, `5 D/ V5 y
#define    CkTime        0x07

2 m$ c# d" E9 \$ K9 Y$ r% b
#define RTC_TIMEOUT             1000//test 1s

/ b# Y) w! t# X% E5 u
#define    T1_PORT                 (3)

7 ?) ]7 y& H( D1 x
#define    T1_PIN                  (3)

2 ~1 ^& j" {3 w; A( S
uint8_t cyccnt=0;
$ v- R: b$ j9 ^$ Y: ~2 A
uint8_t u8Alarmcnt=0;
( j, U& I* x# M
uint8_t flg=0;

4 p2 P5 m- a% O
stc_rtc_time_t  stcReadTime;

3 n- u0 k- h9 y  t

' b+ r" F/ B4 ]/ r$ g
/********************************************************************************** \brief  RTC计数时钟选择

0 @( _. b, U6 z& N+ b( R- O& y7 C- |
** ** \param [in] enClk时钟源
' i% i& b: e+ ~$ J6 l5 m0 }
** ** \retval Ok

0 R, b4 s$ F" T) q4 W
******************************************************************************/

( n  j" L& G, X& j% F
en_result_t Rtc_SelClk(en_rtc_clk_t enClk)

* Q4 m9 q4 w' \
{
% z" `6 n' N( o6 v
   en_result_t enRet = Error;
* l5 M+ `. z  ~- ^, R% Y4 [
    ASSERT(IS_VALID_CLK(enClk));

) d, ]3 F6 ]; H0 E
   M0P_RTC->CR1_f.CKSEL = enClk;
+ w/ u# r# I5 H+ {+ e
   enRet = Ok;
% i4 d3 f" y: y/ [$ w, r7 ~9 `
   return enRet;

5 l# a+ L! G7 m6 `; o+ d. t( K
}
4 z# b" ]3 s# ^! X6 c
/**

, B/ x% n9 N/ t) N! f: r+ j. k% ?; f
******************************************************************************
* F; u5 f" q  ?3 E
**\brief  RTC周期中断方式选择
, r) E1 `7 s) s7 P% @! ~2 H
**

/ G. ]2 X6 \$ a( |& D% p
**\param [in] pstccCyc周期中断方式及周期间隔选择
' g  Q' S% q. m6 s$ ~/ ]9 N
**

7 a1 g( z7 z9 K2 G. V' V4 E
**\retval Ok

+ B3 a2 H7 m) e/ d) ^
**

$ c4 i: J7 X1 k3 M! b; x  J
******************************************************************************/
3 `, O0 ~- E! X" W
en_result_t Rtc_SetCyc(stc_rtc_cyc_sel_t*pstcCyc)
4 G) {* Q+ ]$ N+ f3 f
{
0 H6 [+ s; A: P- S
   en_result_t enRet = Error;

' T+ b; ~) D+ ?8 I% y! S0 }
         ASSERT(IS_VALID_CYCSEL(pstcCyc->enCyc_sel));

, u% W; w5 N: R3 F* I
         ASSERT(IS_VALID_PRDS(pstcCyc->enPrds_sel));

& R9 O# F* m2 o2 m5 E: ?
         M0P_RTC->CR0_f.PRDSEL= pstcCyc->enCyc_sel;
4 M( f' M, T) r  e
         if(pstcCyc->enCyc_sel)

1 U/ E! v+ L& q: f& @4 b
    {
* ^9 a8 w1 E# F) h, V, P
       M0P_RTC->CR0_f.PRDX = pstcCyc->u8Prdx;

3 L5 ]/ @" y% q9 O3 {" P
    }
9 [  A3 ^) |9 I$ v$ t+ f
         else

' w, ~) b; X& h
    {
- b  Y9 v! l) d* ~
                   M0P_RTC->CR0_f.PRDS= pstcCyc->enPrds_sel;

) Q! _! Q7 l2 V  r. O+ @9 ^$ U
    }

& T; Z1 B  w: K
   enRet = Ok;

6 g  L+ _9 \& l/ E" {- \( F' O0 G
         returnenRet;

8 Q* R/ m% I! O
}
, p* W6 s+ M5 [+ o$ |) t
/**

& u9 H8 D, |9 z2 u) R1 m  e
******************************************************************************
( u9 s% {0 Z+ Z5 [1 i8 C7 h1 i
**\brief  RTC时制选择

  G. E# J/ L. x# B" w
**
! q1 C2 q# u8 b7 l. Y8 Y
**\param [in] bmode12时制or24时制

# M' ?4 S' E6 Z3 d
**
0 s: w! |" m5 J& T5 E0 c/ q1 P  i# ?
**\retval Ok  设置正常
* C: R* p! {% j2 J5 q9 b
**\retval ErrorInvalidParameter 设置异常

- `# n5 E2 F  N  ^, W0 E
******************************************************************************/

( U  Y" w$ T5 G9 U+ o3 k8 p
en_result_t Rtc_SetAmPm(en_rtc_ampm_tenMode)
  @( @/ R( v) U! _, v
{
2 q  F5 n6 b% k7 [4 Z2 I
   en_result_t enRet = Error;

/ `$ i& g3 }, s5 Q  K
   switch(enMode)
8 Y0 A! R* h/ D( w
    {
: ?5 C. g0 G* @# Y
       case 0:

! G& v8 f9 J1 I- \* `
       case 1:

; Z' U5 [: g. l* G$ t% f
           M0P_RTC->CR0_f.AMPM = enMode;
. F6 _* F1 b0 i$ B) B$ V+ ^
           break;
8 m" ^0 A- Z" B& h! e" \/ {' B
       default:

% C, p; b" G% e6 ]$ B
           return ErrorInvalidParameter;
( M% N2 W) ^3 e4 K
    }
4 w9 {' r2 W2 d) \, A, v
   enRet = Ok;

4 m8 m9 X5 a% {; y
   return enRet;

7 R. U! l+ i2 V2 F, J
}

7 o6 Y3 O" M2 e( u
/**
6 B/ K2 ~3 H% V6 M
******************************************************************************

! E& y$ [/ K% b! H  t" `
**\brief  RTC闹钟中断设置
0 a; w/ J5 k. T" N% a2 u7 c" F
**
0 G$ M- ]7 l0 p+ d3 c$ E
**\param [in] pstcAlarmTime闹钟时间时、分、周

5 J: P! s* n4 z8 G! v9 ~
**
  P$ \2 i- H* C6 Y
**\retval Ok  设置正常
/ }0 _5 ~& u# r& v
**
1 [& }4 @, Z% ^3 K0 _  b1 a
******************************************************************************/
; W, M: n) |% {8 P
en_result_tRtc_SetAlarmTime(stc_rtc_alarmset_t* pstcAlarmTime)
* Y6 U/ u9 s' H0 s5 ?% _
{

$ {+ I& W$ A4 I  t" E6 F
   en_result_t enRet = Ok;

& r1 [) A$ s9 r; a1 P  I$ u
   ASSERT(NULL != pstcAlarmTime);
( I- [8 n. d/ G- d0 h
   if(Rtc12h == M0P_RTC->CR0_f.AMPM)
9 m1 i  v! n. O) B
    {

3 I3 m8 e6 `1 r$ G. K
       enRet = Check_BCD_Format(pstcAlarmTime->u8Hour,0x00,0x12);
0 V/ V' P. V2 O) W0 f  e
    }

: ?0 a7 h4 ?8 R) |3 b
   else
7 Q4 r9 z  o6 j) H) ^# w6 {9 m1 b
    {

" q! ]5 B, ]6 E: v( y
       enRet = Check_BCD_Format(pstcAlarmTime->u8Hour,0x00,0x24);
; \2 E8 j6 |. y$ g1 f( {, p
    }
3 i8 Y* w. q" Z/ y4 d
    if(enRet != Ok)
. h$ t; j9 l: }$ L
       return enRet;

1 W8 G' Z6 |. T3 ^1 W
   enRet = Check_BCD_Format(pstcAlarmTime->u8Minute,0x00,0x59);
3 R& F0 D& t; A4 N
   if(enRet != Ok)

/ d/ d  l+ N* C$ r9 h
       return enRet;

& X; {! P0 w: I; L6 {) y" V: c5 Z' |
   //enRet = Check_BCD_Format(pstcAlarmTime->u8Week,0x00,0x06);
7 i6 X3 o1 M7 a& z. C
   if(enRet != Ok)

0 R6 s2 m  z( z9 `* J4 |
       return enRet;   
3 _$ Z" ^' c; X
   M0P_RTC->ALMHOUR = pstcAlarmTime->u8Hour;
& k2 T) `0 ]3 P
   M0P_RTC->ALMMIN = pstcAlarmTime->u8Minute;

$ L  J2 i! O; j
   M0P_RTC->ALMWEEK = pstcAlarmTime->u8Week;
( c& N3 ]. t  m3 A: S8 d
   enRet = Ok;
* V" J; v/ G) f
   return enRet;
3 @! |3 Q3 m/ g7 u* _
}
" V3 Y" O$ a* M' ]- _$ O2 c; w- G
/**
( L$ r- `0 q$ |
******************************************************************************
2 ~( C% J* g3 R
**\brief  RTC闹钟中断时间获取
* i* M7 y8 f1 V, x/ ^
**
. I3 l8 s% {' h2 O% j& ^& A
**\param [in] pstcAlarmTime闹钟时间时、分、周
: K4 k+ W( `# B0 R
**
: b. r  B7 I4 d6 O
**\retval Ok  设置正常
: g- N: A: t. Y* L, h/ V
**
" J% H% o2 ]6 u: c: y3 W. r
******************************************************************************/

/ `' V1 t6 {& t) ^( W# U
en_result_tRtc_GetAlarmTime(stc_rtc_alarmset_t* pstcAlarmTime)

# m/ Q% A; \2 E. y9 {
{
& ~  W; ]6 R8 V
   en_result_t enRet = Error;

* L( c. i: a. {7 y) ]& x& Q
   ASSERT(NULL != pstcAlarmTime);

" C; h& i- k3 @9 B1 T4 [) }
   pstcAlarmTime->u8Minute = M0P_RTC->ALMMIN;
6 t* h8 x- R0 Z* r4 z
   pstcAlarmTime->u8Hour = M0P_RTC->ALMHOUR;
' `% S  K( A7 n8 C) Z
   pstcAlarmTime->u8Week = M0P_RTC->ALMWEEK;

9 g1 q; [# f8 L2 s9 P. l! a
   enRet = Ok;
+ Z& V( R0 L$ A) k- v, P$ v* Z. p+ x: P
   return enRet;
/ t9 f( m( a  U9 S  h& K
}
6 J1 d* m' s$ W8 C5 t- t
/**
6 f: k$ d: L* G2 H; v& B% O) P8 p
******************************************************************************
- \) M4 Z& Q2 L4 |0 Q; D5 Y9 k
**\brief  RTC 1hz模式选择
" N" o; p5 H8 a% P; d- O8 a
**
: }. {1 C0 e4 S2 T' p1 P& I" q6 v
**\param [in] bmode 高精度和普通精度
8 E8 e- V3 x) z+ F7 L4 w
**

2 @" N5 l9 F, U1 U: O" D' l: E
**\retval Ok  设置正常

  I! a# H6 W# I4 R
**

; f- Z4 h2 j- s; P# n
******************************************************************************/
: O& y6 C2 O) g: y
en_result_t Rtc_Set1HzMode(boolean_t bMode)

4 d- w3 A$ m' \2 n3 y
{

- K9 d& v8 R% z/ A0 a; b
   en_result_t enRet = Error;

8 v; P" T3 }  \. I! @: P! \0 k
   M0P_RTC->CR0_f.HZ1SEL = bMode;
& _: B' [, ?# A9 X" E' k8 O
   enRet = Ok;

/ h* c7 R1 V7 o( f: N+ N
   return enRet;
$ Q: r% T7 n  H& j3 Q, M
}

# m5 G$ r1 |: f' [
/**

- k0 E8 X4 [' c' _$ }7 s5 D5 k
******************************************************************************
6 w( Q0 `, f! A0 H4 {4 h1 I3 i1 F: D+ ?
**\brief  RTC 1hz补偿值设置
0 @7 C; N/ P2 O3 h, c
**
1 o2 N! G& G# K5 h# t
**\param [in] u16Cr 补偿值
, B: z* ~  A$ g9 [
**

  L! j8 _* [- O3 x& [
**\retval Ok  设置正常
; `4 C5 V4 ]9 j1 t6 ~: Z1 f
**
$ r  O9 W2 ?' j) X4 V
******************************************************************************/
  o3 p2 W! s  s5 r. h2 y
en_result_t Rtc_SetCompCr(uint16_t u16Cr)

4 e' O2 A& G. k0 D9 Z# `
{
0 `" p3 V9 l4 |: |' k2 T
   en_result_t enRet = Error;
8 ^# D" _4 A2 E
   M0P_RTC->COMPEN_f.CR = u16Cr;

! K0 A2 g7 ]1 v  T$ Y
   enRet = Ok;
; W1 k- |+ J5 ]$ a2 a
   return enRet;
) l& B3 m; J3 }. K
}

, U3 G2 @9 l6 m$ e
/**
0 \- ?& S+ C' X! p0 c, `
******************************************************************************
0 m2 p! M. ~. N# x0 S
**\brief  RTC 功能使能设置
$ w5 E+ p2 d! M+ B5 c7 k
**
! b" {5 w  t; o$ g1 K" S/ |
**\param [in] enFunc 功能选择
2 u3 W) q$ P, d+ Z  k
**

1 k/ I8 L/ E! c' n" F
**\retval Ok  设置正常

/ h- Q! }2 i, R0 r0 U) e9 u& w1 R
**\retval ErrorInvalidParameter 设置异常
5 Z: q2 f6 t8 \+ J( \$ e& i
******************************************************************************/
- Q* m+ V& \# m; O1 S' h
en_result_t Rtc_EnableFunc(en_rtc_func_tenFunc)

! `# X/ V# {# p$ E/ T, c( L/ j
{
# s* d  v: `- ^( y
    ASSERT(IS_VALID_FUNC(enFunc));

" T) o) d/ w6 K+ c: i4 l: O1 ^; D/ L
   switch(enFunc)
' j2 X* o" T; i( r/ ^: ?( ~+ W
    {
5 C5 V2 F3 N: r0 Z# R! e  N
       case RtcCount:

& J/ S" `: p% ~5 Y
           M0P_RTC->CR0_f.START = 1u;

& \, C, @: o. w7 l! q
           break;
! i* B9 _. J5 t$ l+ [1 x# P! j3 T
       case RtcAlarmEn:

/ x( H$ i* p! \  _' u
           M0P_RTC->CR1_f.ALMEN = 1u;

# k- v  [# E& ]! B5 U4 K
           break;
. r7 G( D* Q# q. E' X9 X; P: K
       case Rtc_ComenEn:

8 x8 ~3 L  a8 D. Q
           M0P_RTC->COMPEN_f.EN = 1u;
, i# R3 ~* n" \) V. ]) U5 b
           break;

, P8 @3 X: s; i7 z* z# S+ f+ Z
       case Rtc1HzOutEn:
; O% R9 f4 m( v$ D, h+ ^9 o
           M0P_RTC->CR0_f.HZ1OE = 1u;

9 K6 h/ @9 e1 a' x4 d; p. x4 G
           break;
3 v. N/ l( r1 b) H: o
       default:
$ W1 n. ]2 Q& ?7 S# g5 W& a
           return ErrorInvalidParameter;

" @* \( U$ v; d) a) H2 w1 K* G
    }
' R+ r2 S: V7 Z& F, G- a( ^
   return Ok;
, m- G8 z8 I; T/ I5 Z8 Y4 p8 e
}

% F6 X, ~1 O. B
/**

3 n# H3 V* S. `, z( C; H3 a
******************************************************************************

9 b4 c& W  K' S" |
**\brief  RTC 功能禁止设置

/ m4 S: h6 r: a, a" X4 k, |2 e
**
1 V3 f; K" x4 k8 C- V7 U9 K) @
**\param [in] enFunc 功能选择

8 E( W+ X0 ^7 E$ S: B
**

2 T. }% `2 O: f; Q) v4 [+ f2 U- u5 V
**\retval Ok  设置正常

/ m/ S7 c) b" w9 r
**\retval ErrorInvalidParameter 设置异常

0 }) \* I0 L( r0 O+ c' r
******************************************************************************/
& I# D# Y" u6 u4 x" w' D
en_result_t Rtc_DisableFunc(en_rtc_func_tenFunc)
/ G5 h, _' A# k
{

* p. p% ?6 `% \+ o: c
   ASSERT(IS_VALID_FUNC(enFunc));

( ?# v$ X) R3 S+ G* x
   switch(enFunc)

7 e/ a" |! m0 @9 W& J5 P$ H
    {
: _% ?+ O/ ?  w1 q  [0 E: _
       case RtcCount:

( V, J3 k7 J! t& V4 M
           M0P_RTC->CR0_f.START = 0u;
7 N' U* \  J" {6 X' s# a6 a5 d
           break;

. j0 X% v" v& x. c2 y# B
       case RtcAlarmEn:
! {6 v: n9 g9 |
           M0P_RTC->CR1_f.ALMEN = 0u;
7 j/ q2 I2 t, L3 H8 T0 i  ~9 f" C
           break;

4 h0 Q8 ~4 k; I% M/ F
       case Rtc_ComenEn:
2 D" B* ]0 j6 ^! Q- W
           M0P_RTC->COMPEN_f.EN = 0u;
- O0 @: H+ ^4 q  z$ R5 |  A
           break;
8 h# X" H; \( h3 n, O
       case Rtc1HzOutEn:
0 |: o; C7 g( r3 X
           M0P_RTC->CR0_f.HZ1OE = 0u;
0 Q6 o+ o3 R, s' a
           break;
" I3 B; {5 u& D+ u& e; @! e$ \7 t1 }
       default:
& H! c* x5 ?/ `7 J' M8 r
           return ErrorInvalidParameter;

% |! N8 x6 v- C" n+ N
    }

" Z' h) y+ K+ Z$ P( Y. d6 q
   return Ok;
6 U: M7 `5 o' X8 t/ p8 R7 T! A
}

0 z1 }. D8 W: |+ s5 w3 j8 B
uint8_t Change_DateTimeFormat(uint8_t u8sr)
# _. x  B5 V* ?& H. Z
{
: m+ A( }. I/ J+ x8 c4 w: d' d
         uint8_tu8de=0;

6 o$ W% z' F% n5 e
         while(u8sr>=0x10)
. d# Y& ~2 s* P( d' x
         {

" p0 [2 ^  a& ~& K1 W  I7 \
                   u8de+=10;

( o2 e- F* e0 z0 ]  w
                   u8sr-=0x10;

9 E- b% t9 U9 f5 o2 C+ {
         }

6 S4 L; p1 T: X/ x% ]; g
         u8de+= u8sr;

  @+ t: I, f8 {7 E4 k& c6 }
         return(u8de);
) H( ^- m: R; d: g
}
7 d% F% ]$ R3 g; y
/**

) c' C! r+ J% _* q  g  s- y
******************************************************************************

4 v' ~$ N6 S3 X" ?' r$ W2 P. n
**\brief  RTC 平、闰年检测

1 D) r' O) g2 R/ X
**
2 n' t* S) f! ~9 V9 v, b8 E- D
**\param [in] u8year 年十进制低两位
3 R# b) x& }1 R8 P5 {1 X3 l  w8 v
**

$ K, M1 O7 _# {/ j7 o% S
**\retval 1  闰年

6 \$ A) u3 I! |9 s3 ]# _
**\retval 0 平年
: I: O! ?7 A& e, W( q. Y7 J
******************************************************************************/
" a' h' P% o- |, n) I6 S6 H
uint8_t Rtc_CheckLeapYear(uint8_t u8year)
' L& ]% P$ P# x
{

( S% H3 F6 Z, p/ ^; M" N, L5 o' F
   uint8_t u8year_shl,u8year_shr;

* e- q7 {( v. r1 s" \" o
   u8year_shl = u8year>>2;
% p; D8 t2 q1 R$ N1 U4 b0 X
   u8year_shr = u8year_shl<<2;
" V" W5 a/ u) ]" c( B' F
   if(u8year== u8year_shr)
2 K* K6 K+ w' K+ y" @: @, m
    {

) r* Y) D8 O1 N& s5 a
       return 1;

& D: y8 Z1 E. `; t, c9 O: y
    }

2 T2 O! `$ H. h8 o. y. _/ @. M
   else

; ]3 H# R5 b/ `! g
    {

! ?( J6 `$ w  B. h- a1 i' Y
       return 0;

/ h# ]" _3 a2 l$ n/ X
    }
  S' J8 g, t4 e
}
" \$ H, e) h; P* ?/ ?
/**
  n% \( t* |  d1 b# m
******************************************************************************
4 V8 i+ R& s! y! G
**\brief  RTC根据日期计算周数

: s0 u0 [1 M/ @0 n4 u$ j9 N# F% g2 d3 G
**
9 N' g& M9 q3 R/ k' ~$ F
**\param [in] pu8Date日期

; q3 V: B- }$ {+ t- y  j- G
**

2 B4 }; ]1 h1 d; A8 }
**\retval week  周数
* s6 ^% c6 R" i0 ?
**
+ ]# _; d0 ~9 W- f  r' A
******************************************************************************/

2 A( a) L4 Z  [7 |2 g0 j7 E, _
uint8_t Rtc_CalWeek(uint8_t* pu8Date)

0 t1 k, L& B0 I* b! I: ^! j. \( [
{
/ V$ Y! K3 S1 E/ T* n+ g
   uint8_t u8week;
8 }, w, ^! \' p4 `6 e
   if((Rtc_CheckLeapYear(Change_DateTimeFormat(*(pu8Date+2)))==1))
* W7 n" k) o% k* A4 R$ j
    {
0 D4 E" h; d% _3 ?
                   u8week=(Change_DateTimeFormat(*(pu8Date+2))+Change_DateTimeFormat(*(pu8Date+2))/4+Leap_Month_Base[Change_DateTimeFormat(*(pu8Date+1))-1]+Change_DateTimeFormat(*(pu8Date))+2)%7;

3 l7 k3 ]" _, P# |, u3 c
         }

4 i' z0 [- |* V9 P. H6 Q
         else

, ~# d( s+ Z$ v- k% g
    {
3 w8 `8 D: J- l1 b
                   u8week= (Change_DateTimeFormat(*(pu8Date+2))+Change_DateTimeFormat(*(pu8Date+2))/4+NonLeap_Month_Base[Change_DateTimeFormat(*(pu8Date+1))-1]+Change_DateTimeFormat(*(pu8Date))+2)%7;
( s* n& t4 q) X* D# ?- [
    }
, n3 U6 z2 K3 \6 }4 @% u! y" Z/ d
   return u8week;
& W; |8 w  g+ x
}
6 i: K2 k8 c! t- O2 p3 s2 Y% e, @8 J0 c
/**
+ ?' ?7 ?$ ?: `( |" A6 ?
******************************************************************************
0 h$ B! ~& P3 q2 b# O; ?
**\brief  RTC根据年月获取天数
- }# R1 Q8 o& ~9 V+ l8 ?* P) y4 F
**
2 [: _0 T  G* d1 C1 Z) g! }! V
**\param [in] u8month月份,u8year年份

/ E! U9 u' r+ O" r
**
+ ?5 K$ T! _7 p+ ~6 Q7 W7 q
**\retval u8day天数

$ h- u5 K2 R5 l: V1 J
**

. j1 w8 r8 Y' ]/ }  c
******************************************************************************/
% `! P2 D6 q: i  J, _
uint8_t Get_Month_Max_Day(uint8_t u8month,uint8_t u8year)
9 q- k; g! I) `: r( _5 b
{

* Z5 M6 i% N; W
         uint8_tu8day = 0;

& G4 e% d" l( l4 C  Q: G; u! m% q5 J
         

# R5 }2 q2 U: Z8 Z
         u8day= Cnst_Month_Tbl[u8month - 1];
( e( C( j9 t( i* n8 {( H
         if((u8month== 2) && ((u8year % 4) == 0))
9 H% Z8 h+ `7 R0 Q9 x0 p6 Q% t
         {

7 X+ ?3 B/ U& s/ O- d1 `: s
                   u8day++;
7 ?8 Y3 c) Q2 Z: W0 I
         }

6 I  K6 \1 Y/ c, I0 q! D0 |$ `  y
         return(u8day);//day的格式是bcd码,例如;日为31天,day=0x31
+ {  m8 ]; n/ u% r8 P' ^
}
% X. c: N3 s% K4 ~' Z  }
/**

* d1 Q' ], K& y( D8 w3 ~
******************************************************************************

7 }! G4 |& ^# s; o
**\brief  RTC根据日期计算周数
. V1 N6 @* {" j2 p4 r# o8 a
**
: |! J* ~/ Z( T
**\param [in] pu8buf日期时间数据,u8len检查数据长度,u8limit_min最小值,u8limit_max最大值
: y/ x  o. V) L8 Q6 P* y; S* C6 U. w
**

/ p2 a# H: M, R6 S0 B
**\retval Error 错误,Ok校验正确
, g0 l7 T% y5 n" I/ l. j
**

. ^  G6 M( J* N6 N% |' @
******************************************************************************/
! n8 W* @2 w" h5 f6 X2 J2 K8 S& n+ l
en_result_t Check_BCD_Format(uint8_tu8data,uint8_t u8limit_min, uint8_t u8limit_max)

: }* j, _% v7 n' Z9 \" X& L
{
5 D% E% P- D, e& D! P
9 B! N) J9 m7 Z4 o& k% E' S
   if (((u8data & 0x0F) > 0x09) || ((u8data & 0xF0) > 0x90)
% K1 o5 @1 @1 }$ p, m7 R1 H
   ||(u8data > u8limit_max) || (u8data < u8limit_min))

* Z# h* E" G* N% e
    {

+ K8 a/ n' [7 ?0 m% }
       return Error;

' C+ U) m5 X; f0 Y0 {
    }

& E" {* V# R' N
   return Ok;
( U% a# {9 U& a8 T
}

  s6 M2 l* Z5 R+ o2 o6 a/ p
/**

1 ?6 [' Z% E: c) p. B) M
******************************************************************************

$ H) ]  x; j: v0 d4 F
**\brief  RTC时间格式检测
) ]+ }7 x1 O; t7 i( U. t
**

+ }( ~+ ]1 j+ v: S
**\param [in] pu8TimeDate日期时间数据,u8Mode检测模式
, Q: G2 N2 [, w2 a% S$ x$ `/ s* x
**

1 |! d0 \7 I& k" `& P/ p6 x1 ^5 ]
**\retval enRet校验结果

5 H6 i1 g0 c4 F6 s5 s* X4 c2 K: }
**

/ t  N3 ~' B6 n  d1 @! S% I$ L
******************************************************************************/

$ C4 b! F  w, s" R
en_result_tRtc_CheckDateTimeFormat(uint8_t* pu8TimeDate,uint8_t u8Mode)

- }: T* k; g! d1 ]# m9 C8 @
{

( P* @( h9 U+ _; q% H6 R4 m8 a
   uint8_t u8i=0;

% m' t0 Q! \$ p2 m
   uint8_t u8mon_max_day = 0x28;

" d. D+ c% A: l! f/ _2 v1 \
   uint8_t u8date[3];

  N/ O5 b8 o2 C
   en_result_t enRet;
( K8 q. a( D- b5 u7 y, p, v
   while(u8i<7)
# b  F/ ]& Z3 B" X' V
    {

+ B! z4 d' {5 ~% ]2 x+ a; A
       if(u8Mode&&(1<<u8i))
" S% u- z  V1 }. P$ l
       {
+ J+ G( V; x' r# d
           switch(u8i)

) `( p' X" i( C5 N+ Y5 @
           {

# l# |1 a. S% E2 O" p. w, I
                case 0:
4 W8 C; }5 H  A3 U% ~  b
                    enRet = Check_BCD_Format(*pu8TimeDate,0x00,0x59);//
4 o3 d0 j- t1 j+ x+ q( x
                    break;
; ^% m& M3 R* p. u7 l  I! J
                case 1:

: J6 q/ U: s6 ^% i% N' m
                    enRet =Check_BCD_Format(*pu8TimeDate,0x00,0x59);//
: R$ `  f2 i( s- d2 P7 }5 t# H# [
                    break;
4 T! Y& A+ N2 o0 c" e0 x
                case 2:

% [6 s" {* g+ O% y
                    if(Rtc12h == M0P_RTC->CR0_f.AMPM)

8 X- n' F/ D! @" A% V1 p7 e
                        enRet =Check_BCD_Format(*pu8TimeDate,0x00,0x12);//

# q# G2 W  e: x/ f2 S: j/ B. j/ K
                    else

* Z/ \! G  c: s( ^2 O: ?% O
                        enRet =Check_BCD_Format(*pu8TimeDate,0x00,0x24);
+ n2 y3 {+ r: U" E2 [; Y" \; t
                    break;

0 S/ @3 ?1 M9 T. f! f
                case 3:
% w' S' h# ]: S* e+ [
                    enRet =Check_BCD_Format(*pu8TimeDate,0x00,0x06);
* a* Y& V; A) u+ n' Y& Y; C. y
                    break;

) f5 [9 f" @' E& R4 a
                case 4:

  {5 a6 _' c& J! H: j5 A
                    enRet =Check_BCD_Format(*pu8TimeDate,0x00,0x31);

. R  ]  c2 o6 h" t8 O
                    u8date[0] = *pu8TimeDate;
. L% `6 B' U+ h$ W
                    break;
3 H( T$ Q4 g! [
               case 5:
% o: p5 Z: t/ f
                    enRet =Check_BCD_Format(*pu8TimeDate,0x00,0x12);

" A& Z# m6 G; L. }6 N* r5 Q$ A' u4 x5 f
                    u8date[1] = *pu8TimeDate;
& o: i6 U* t4 o) ~+ _4 G  N' Z
                    break;
! V* P9 H0 [" ~" l" W
                case 6:

3 [# ?: |% r' f* c
                    enRet =Check_BCD_Format(*pu8TimeDate,0x00,0x99);
2 c. G. h& p( M/ m# v. \6 j
                    u8date[2] = *pu8TimeDate;
( _5 K# u: G# T' L- t8 G
                    break;

1 M% f' H5 C% k" T/ b) d
           }

6 \5 ?0 c& f4 d
           pu8TimeDate++;
( w7 e' s5 C. K9 U; R8 _
       }

: m7 X, ^3 Y- a' N8 Q
       if(enRet!=Ok)
0 `: R) e0 Q, Q. E' H5 Z' k/ l
       return enRet;
  v2 P1 Z: g, {6 ^, a( n
       u8i++;
" \0 }, Q& H/ ^' @
    }

+ b. r, l: E* E* F/ G- b
     if((u8Mode&0x10)&&(u8Mode&0x20))
! ?7 P- O; G+ a% g& N
         {

: D+ g- r8 ]* ]2 w
                   if(u8Mode&0x40)
. @- d0 Y& ]1 I9 D
                            u8mon_max_day= Get_Month_Max_Day(Change_DateTimeFormat(u8date[1]),Change_DateTimeFormat(u8date[2]));
$ s- T) i1 l& _
                   else
# y" t8 i  O" K3 R: X" F; U
                            u8mon_max_day= Get_Month_Max_Day(Change_DateTimeFormat(u8date[1]), 1);

8 I7 v  n/ P( [' ?- G
                   if(u8date[0]>u8mon_max_day)
* K  j1 P" X* Q+ W: Y/ \
                            returnError;
* z2 [8 C6 ^  M# H& \
         }
1 e- l$ y8 ?4 D  N
         if((u8Mode&0x10)&&(!(u8Mode&0x20)))

! k$ ^, L+ K) ]7 e" P" _
         {

$ }+ v) L$ f, h0 c- D- j
                   if(u8date[0]>0x28)
. Z4 @+ u+ }, x; [2 Y
                            returnError;
) i" M; ]# c+ G* \1 V! _
         }

8 \' B' L$ I8 v! ]
   enRet = Ok;

* M+ A2 j$ J& A1 G, N% u( ~: n" \
         return(enRet);
6 W$ |& N4 Z7 f- T7 A
}
% i, b' a0 I9 ~% N/ s1 T' A
/**
) W7 b/ V# f* R" O2 Q
******************************************************************************

0 Y& T9 M/ i. U# y# Y, a
**\brief  RTC设置时间函数
0 E( Y1 n; }2 `, I* z7 b2 ~
**
9 g8 _, ?1 b* M0 o
**\param [in] pstcTimeDate日期时间数据、bUpdateTime是否更改时间、bUpdateDate是否更改日期
  z8 p. ]' X7 e* P" G7 H# Y% s
**

2 u) h: f% P6 u
**\retval Ok  设置正常

' s) T& N2 V8 G4 w2 e  y- u
**\retval ErrorTimeout 时间溢出错误

7 X$ {6 y1 s) t0 q
******************************************************************************/
  r+ }+ F; T6 Y1 ]* s/ y$ o  X
en_result_tRtc_WriteDateTime(stc_rtc_time_t* pstcTimeDate,boolean_t bUpdateTime,

/ ~3 S9 p8 ?' b7 G! w6 a
                            boolean_t bUpdateDate)
" }7 p/ R( M% u3 v5 N
{
2 H2 c1 q* }9 q" [! b5 Q# Q/ r
   int32_t u32TimeOut;

7 ^' G7 h. d1 A" F/ U
   u32TimeOut = RTC_TIMEOUT;

' c. t4 \% U* _' g) G" w2 X' `
   uint8_t* pu8TimeDate;

% L* |. v$ V5 E+ F- x
   en_result_t enRet = Ok;
/ I  T) o- n3 x/ A% \. d$ l0 r
   pu8TimeDate = &pstcTimeDate->u8Second;
& B) A. g( d% E4 r9 p1 D+ Z
   ASSERT(NULL != pstcTimeDate);

* v$ @( y1 Q! H) ?; r
   if(1 == M0P_RTC->CR0_f.START)
4 x/ n& F* n, M9 l: o' \
    {

1 t: M7 O& `5 i: N2 Z
        M0P_RTC->CR1_f.WAIT = 1;
* N7 u. K9 x& K" r$ ?0 V
       while(--u32TimeOut)
: A, d+ C1 l8 }. E7 r
       {
2 p% F, p, Q% r1 W% I
           if(M0P_RTC->CR1_f.WAITF)

9 D/ R0 w9 h2 m' n' E
           {
9 {* {. M3 i! N! {" _
                break;
& D) U1 W2 I" h6 u3 s3 s( }1 J
           }

$ q0 W! [& n) E9 Q, v
       }
5 s* E3 u# y8 d& q: ~* P
       if(u32TimeOut==0)
5 l& `. x  Y* U. [7 t' v4 @* ^% K
       {
5 U2 [) k( ~0 ]4 {: `
           return ErrorTimeout;

* Y  a# H% e7 U) w2 x) n$ z) b
       }

; f+ v" ~6 i9 a
    }
" w# T5 c$ ^' A1 o' h+ P
    if(TRUE == bUpdateTime)
7 o" z9 p3 a& ]0 ?. Q& l
    {
& K& v* l  k) A) ~" j
       enRet = Rtc_CheckDateTimeFormat(pu8TimeDate,CkTime);

# K3 C$ W9 L" G: Z3 o
       if(enRet != Ok)
$ y+ S8 D0 N, m9 b, J
           return enRet;
# m0 B* y* H4 [# \/ b4 q% `. D
       M0P_RTC->SEC = pstcTimeDate->u8Second;
6 U& x3 F& p8 P' b7 w
       M0P_RTC->MIN = pstcTimeDate->u8Minute;

" g/ X, T+ |% m  B
       M0P_RTC->HOUR = pstcTimeDate->u8Hour;
; Q1 }# y% b  g5 m
    }

5 M% ^7 K% i* E1 N& y7 I
   if(TRUE == bUpdateDate)

8 v6 ?( G) r& G- q
    {
* g) z; p" t2 T8 r/ H5 c. O6 ]
       enRet = Rtc_CheckDateTimeFormat(pu8TimeDate,CkDate);
# @/ h/ b; ~7 `) n5 r
       if(enRet != Ok)

6 s( w6 T; X) O# a
           return enRet;

" Z) N0 g+ K$ q: v
       M0P_RTC->DAY = pstcTimeDate->u8Day;

& x( ^: R, u* B- V3 R2 x
       M0P_RTC->MON = pstcTimeDate->u8Month;
0 t4 S1 @8 w# a; P5 i3 L8 u
       M0P_RTC->YEAR = pstcTimeDate->u8Year;
4 `- o- z- {3 ]6 b4 a" i4 {
       M0P_RTC->WEEK = pstcTimeDate->u8DayOfWeek;

9 |+ b, _8 k4 c9 e# z
    }
: R7 D$ |6 v, Y3 W4 u" \& L' {7 K
   M0P_RTC->CR1_f.WAIT = 0;
" i7 ?2 Z- i: ~- @! q* o
   if(1 == M0P_RTC->CR0_f.START)

" b7 V# z- e$ s3 g
       while(M0P_RTC->CR1_f.WAITF);
' h) {; I$ v, v- n4 v- T
   return enRet;

/ Q. |. }& s& X: w
}

; _0 c  g+ M! D. v' X- W
/**
* K9 A; v( s' s. X$ P3 K2 o% [
******************************************************************************
% S8 S8 p/ P, ]8 q
**\brief  RTC获取时间函数
! u) K  }  L" [+ W3 Z
**

/ H3 u7 a2 g; O  V( z
**\param [in] pstcTimeDate日期时间数据

& @6 Y. `% s5 ^1 V. d# H
**
% y* M( x6 m% o
**\retval Ok  获取正常

9 z) O0 _& ~/ y9 s  I/ _+ h/ M
**\retval ErrorTimeout 时间溢出错误

8 u" O8 b% U9 R2 I* _# _
******************************************************************************/
- r, ^8 K5 p/ l3 T
en_result_tRtc_ReadDateTime(stc_rtc_time_t* pstcTimeDate)
: F! {* n9 F' m, v7 N% D& F
{

1 j. \8 W3 |0 x% m( ]
   uint32_t u32TimeOut;
: G( f4 Y! u7 ?% i5 |% W* C; _0 X1 x
   uint8_t  u8DayOfWeek, u8BcdSec,u8BcdMin, u8BcdHour, u8Day, u8Month, u8Year;
; f1 T/ f5 X9 ?6 {
- G- U' ?; F3 P3 X; ~6 d
   ASSERT(NULL != pstcTimeDate);  
5 A" Q. a0 `" i+ ?
   u32TimeOut = RTC_TIMEOUT;

1 c+ x) F# m' Q  e9 U5 E1 `8 v6 D2 V
   if(1 == M0P_RTC->CR0_f.START)
5 V3 q. I# u& X% W4 R. n
    {
& F: q# i5 J4 ~0 c9 m9 W4 i0 n' `, w
       M0P_RTC->CR1_f.WAIT = 1;

- z5 [. p; T7 u# z
       while(u32TimeOut--)
" K: |+ q  x) ?2 d1 R0 {; r
       {

  Q5 g. w% t+ M- t! b! D5 _
           if(M0P_RTC->CR1_f.WAITF)
: J! E5 z5 b; X- d
           {
+ F' k5 `* u8 k5 T( D9 X' s
           break;
/ v( X& o' q3 l5 p0 m
           }

4 [, B8 f+ |# ?& `3 f8 M0 V
       }

- O: L$ ~+ m3 F+ u2 @+ X
       if(u32TimeOut==0)
0 o, b7 E9 p1 A$ G* u" S
       {
# `1 Y0 D$ ?+ `# B9 I  T4 S! r
           return ErrorTimeout;

# O* K7 p' j8 d; R6 B
       }

, C9 H; [* a0 D* m
    }
, X2 O6 J/ t: q
   u8BcdSec  = M0P_RTC->SEC;

5 Z  P* @% ~+ u8 [% _
   u8BcdMin  = M0P_RTC->MIN;

6 o( o) b  ]; B. \6 K
   u8BcdHour = M0P_RTC->HOUR;
2 h9 u0 V# M7 N$ F
   u8Day     = M0P_RTC->DAY;
# _: p1 w% X; f! r; M% o
   u8Month   = M0P_RTC->MON;
) @% R4 |1 v, @9 P0 Z% h- D
   u8Year    = M0P_RTC->YEAR;

! ]6 }. V( V& V, @; A# B, Q
   u8DayOfWeek = M0P_RTC->WEEK;

. H9 H  s7 w. K. h# C
) e6 W  J, p# i  @8 j% O3 T" v& I
   pstcTimeDate->u8Second = u8BcdSec;//BcdToDec(u8BcdSec);
% K' W! q3 K" h0 g' o
   pstcTimeDate->u8Minute = u8BcdMin;//BcdToDec(u8BcdMin);

+ K% \3 F6 U3 q7 o/ d0 D- [6 J
   pstcTimeDate->u8Hour   =u8BcdHour;//BcdToDec(u8BcdHour);
: d2 K$ h$ m' y! L
   pstcTimeDate->u8Day    =u8Day;//BcdToDec(u8Day);
0 Q- {  ]7 ]! n
   pstcTimeDate->u8Month  =u8Month;//BcdToDec(u8Month);

, n2 w3 n/ {2 ^7 ^  w) p
   pstcTimeDate->u8Year  =u8Year;//BcdToDec(u8Year);
5 Q) Q0 F0 D& g% }6 g( M4 q' Y
   pstcTimeDate->u8DayOfWeek = u8DayOfWeek;//BcdToDec(u8DayOfWeek);
# h- m* ~. S$ g7 X. S/ x1 j# s0 f
   M0P_RTC->CR1_f.WAIT = 0;
) @5 g6 X: m6 N" z& A* w; v
   if(1 == M0P_RTC->CR0_f.START)

- ~# I/ Y: `) Q. w& c
       while(M0P_RTC->CR1_f.WAITF);
* i- T1 Z5 z/ F4 ^
   return Ok;
: S; G% }- e/ Z5 C7 k( L
}
& O3 y, ?, e6 l9 l
/**

' g5 n- M8 w. Q0 {5 x( g( c5 ]
******************************************************************************

7 F4 ^' [0 D$ g1 o! t- @, G) T* `# X$ ~
**\brief  RTC计数or读写状态获取
/ k  D" ]6 a/ Y
**

8 c5 _4 q# M' @- C8 G3 R3 R! @
**\param [in]
# ^& z& c+ E* j; j% D. t
**

5 x$ _- A. C, Z+ y4 V
**\retval 计数or读写状态
8 _+ Q7 G; @( {1 X" @' z" ^8 b
**

7 U! m. b* Z3 F4 G
******************************************************************************/

9 t% Q5 X7 X; k8 J
boolean_t Rtc_RDStatus(void)
" K6 U7 t: x( r3 Y  m* t
{

: J3 k2 f# C' y4 j
   boolean_t bRet;

  @, y$ ]% U# Y* ?3 E8 x
   bRet = M0P_RTC->CR1_f.WAITF;

) L/ {8 \0 c+ L' e: ?
   return bRet;
) d/ f) O  L) A: X# }& F& c1 F
}

' s# ]* O2 Z; ~
/**
( Q. ]$ B- z; m1 |8 @. W# A; y
******************************************************************************

- y' S9 {9 X/ J+ Q0 _7 P
**\brief  RTC闹钟中断使能
8 `& V% `) P0 G; v$ G$ u
**
' C: z" v( z( Y- S" }/ j
**\param [in] enordis中断使能or禁止
0 H! H: t: t7 Y/ V( R% D( ~3 R2 T
**

3 U. ~0 ]. l6 I# `7 c3 l& j
**\retval Ok设置成功
2 J1 A( h7 |5 f
**
* H' X) k7 g; e/ P# l) ~  s
******************************************************************************/
# V- `7 D  ?4 l3 O! Q
en_result_tRtc_EnAlarmIrq(en_rtc_alarmirq_t enIrqEn)
) f6 F9 i( a2 V% d- G
{

* h% U) T  y( D$ I( A
   en_result_t enRet = Error;

, F5 a4 h: t8 {  ~
   M0P_RTC->CR1_f.ALMIE = enIrqEn;

  D; v( m" `7 z/ _
   Rtc_ClrIrqStatus(RtcAlmf);//使能中断后清除中断请求标记

& P, M, v  A4 G( ]( [; F6 |2 K
   enRet = Ok;
8 f- ^/ `! f+ M
   return enRet;
* ~" X5 q2 `& H; |# E8 ^* h
}

( I6 M2 O0 R- ]; ?* A; ?
/**
' a" t1 m1 b/ f  l( f$ l
******************************************************************************

% }& K4 B7 |: ~+ ^
**\brief  RTC中断请求状态获取

! Y2 v- H; v3 y/ _
**

2 Y. g) z( V* T- s- B7 W
**\param [in] enIrqSel获取哪种中断请求

/ I3 d! g" u+ m
**
- D4 L! W" l" ?& e) h2 D$ {1 W
**\retval 中断请求状态

- o& M2 u3 [8 ?3 B; I5 C  S
**

% f4 U( u* N" h7 p* t/ g+ h
******************************************************************************/
8 H/ z+ K- J& w* P) y, |6 ~+ P" n8 M
boolean_t Rtc_GetIrqStatus(en_rtc_status_irq_tenIrqSel)

* z0 ^8 t+ f9 ?) T) S
{
. Q( j8 J$ `4 v% @7 T0 [
   boolean_t bRet = FALSE;

4 ?% J8 H8 U* P+ b- S. P7 ^
   ASSERT(IS_VALID_IRQ_SEL(enIrqSel));

4 V" c2 a% t8 `" A- s2 E
   switch(enIrqSel)

5 e9 @0 X) Q( d2 X7 h5 i) Z
    {
+ |1 }' J2 P4 ^2 v
       case RtcPrdf:
, Y, D5 B0 Y/ s3 E( I
           (M0P_RTC->CR1_f.PRDF == 1)?(bRet = TRUE) : (bRet = FALSE);
2 E1 O$ T: E9 D2 U
           break;
# ]& b, T& k. f% ~% d; b2 h# D2 Y5 f
       case RtcAlmf :

- X2 u, @$ x" i$ G
           (M0P_RTC->CR1_f.ALMF == 1)?(bRet = TRUE) : (bRet = FALSE);

; K: n- o; e, Y5 ~( r, W; J; g
           break;

- t9 U5 X! c' g: M7 R# M
       default:

% R5 U- S. p2 T; L# }" c
           break;

0 {( e1 i1 a0 q; `* v
    }
5 y( r0 M+ w# T8 R4 @6 O7 Q
   return bRet;
; N! G" V$ [) K- S1 x& F; f
}
1 \# ~3 B0 M% w6 T
/**

2 r6 Y* i( f' [0 M2 U; d5 K  u) u
******************************************************************************

: r1 O; h4 e( `
**\brief  RTC中断请求清除

) Z! ~9 x% N" \; q0 c) R
**

) |( p! S0 ^& \) U" p' x7 Q
**\param [in] enIrqSel清除哪种中断请求
) y. f8 V3 h6 v
**
% _3 K1 ?  S; J* {
**\retval Ok 清除成功

3 z* f8 ~) ?& D, M; `- p
**\retval ErrorInvalidParameter 清除失败

/ X% B9 O+ m# @, X" I
******************************************************************************/
( V& d. g% y" `% A0 R+ Z4 P
en_result_tRtc_ClrIrqStatus(en_rtc_status_irq_t enIrqSel)
9 k: v( U5 k4 X+ R6 q  b. e/ \
{

" H: d3 u: S( s) A: E6 R
   ASSERT(IS_VALID_IRQ_SEL(enIrqSel));

, H6 s( v' G  p+ y$ ^/ C
   switch(enIrqSel)

+ |- J6 Z& F. a' {9 b
    {
; j! R: N8 D- F8 g* D  F# I1 \
       case RtcPrdf:
# H- @4 B. X' b8 H, I
           M0P_RTC->CR1_f.PRDF = 0;
0 h) W) M7 z) m1 _
           break;
+ I. p3 Z' u" D5 [" x
       case  RtcAlmf:
9 c8 f, Z3 v, X& k
           M0P_RTC->CR1_f.ALMF = 0;
/ k! [6 e3 x# G  T
           break;
# A: }5 w/ m  ?( K( h6 b' O# }
       default:
/ i; s) l1 u+ m+ c: y! q
           return ErrorInvalidParameter;
- m( ^7 E' O, d5 N, n. Z3 R% i3 w
    }

8 F# f+ @( D3 v7 v/ @$ n
   return Ok;
' x. l* ]* ?" \: ^" P, G) E
}
( T$ m' d+ S+ L

9 x) a, n) U+ f2 Y) C2 f
/**

7 O1 g0 G  |* v8 f7 T8 r9 i. x
******************************************************************************

* e4 c0 K6 I. B- Z* t* W4 U
**\brief  RTC中断处理函数接口获取
: p7 C. n% X" i
**
2 h! e' ?2 K6 }6 v/ u% X
**\param [in]

0 R+ [) q8 H/ {( r8 w
**

" S5 p  {% z+ F% L8 s
**\retval 接口函数地址
. m- C* T) z2 E; Q+ G. w+ @
**

8 D9 h" h7 U# Z
******************************************************************************/
: u) ]  I9 ]& U+ |- I( k' B
static stc_rtc_intern_cb_t*RtcGetInternDataCb(void)

2 N& I/ a$ u6 \4 m) }" S
{

+ |9 H" S4 ~: }, {# Y; _
   return &stcRtcIrqCb;
6 y" u$ }" e2 O- v7 I5 l' l' W
}

  Z1 _& b8 a0 y9 K6 ~8 D* ?; T3 l- w
/**

$ Y/ e- B  U3 d$ _
******************************************************************************

3 f( Y* N( y7 D8 H0 S
**\brief  RTC总体初始化函数

+ `- S) W, B+ d1 \' s& o* {6 `
**
3 I1 g# Z6 l0 r/ @9 S8 I5 S) S
**\param [in] pstcRtcConfig初始化结构
2 |& y' u% T/ Y% k: {# _$ |
**

8 P8 _, r7 W* V1 e6 u5 P- O
**\retval Ok初始化成功

8 J: {7 y7 N- o( A" L9 a
**\retval ErrorInvalidParameter 初始化错误

6 w) \9 q- V: H' ]& w* x
******************************************************************************/

; g( a( |4 I( @# z9 t
en_result_t Rtc_Init(stc_rtc_config_t*pstcRtcConfig)

. C$ O3 s6 Z4 G+ i) I
{
, `/ t2 p' L% M+ F* j" M  D9 J2 o
   en_result_t enRet = Error;
3 s7 T( A& i- j& \: w
   stc_rtc_intern_cb_t* pstcRtcInternCb;

+ s( `: G) c, W0 t6 S/ G
   if(NULL == pstcRtcConfig)

. D) s8 t. ~1 v* D, d/ H9 I
     return Error;
2 R  r$ R9 |( G4 z2 M7 C! K
   pstcRtcInternCb = RtcGetInternDataCb();

6 L/ b+ b* a6 s) v9 k
   enRet = Rtc_SelClk(pstcRtcConfig->enClkSel);
6 j5 f9 O* ?* h4 V/ p' ]; C- S
   enRet = Rtc_SetAmPm(pstcRtcConfig->enAmpmSel);
" L3 s# C" X) ~) h7 \; K1 P( T- ^
   if(enRet != Ok)

3 o4 P# Q! N  z
    {

( D5 ?. K1 x# ~( ~) {  b
     return enRet;
" Q) {0 e2 s* {/ y9 R
    }
2 \0 b, F' R! t0 j2 C
   if(NULL != pstcRtcConfig->pstcCycSel)
; ?& K+ }$ [. g/ z, s3 ]5 n  Y
    {

' C7 h" d$ ^8 f% H* [
       if(Ok != Rtc_SetCyc(pstcRtcConfig->pstcCycSel))

" O3 l1 g+ c% F+ S( `1 a9 R
           return Error;        

" F4 m' h, J( c* L9 N
    }
  t, }6 H) b/ l/ g/ G
   if(NULL != pstcRtcConfig->pstcTimeDate)

6 G" Q- a: n( U. I! l5 ~
    {
- f" E* Z$ e( i8 R& ^
       if(Ok != Rtc_WriteDateTime(pstcRtcConfig->pstcTimeDate,TRUE,TRUE))
' C4 R. I! `$ H1 _6 D
           return Error;
! m1 \- o9 |8 O) |) \
    }
$ e$ H) [9 \+ \2 @+ R8 W0 P* W( I
   if(NULL != pstcRtcConfig->pstcIrqCb)

/ h; Y7 r& k' r, ^( x- t
    {
+ [, n4 H1 [8 j5 X. D
       pstcRtcInternCb->pfnAlarmIrqCb =pstcRtcConfig->pstcIrqCb->pfnAlarmIrqCb;
$ T' O0 t, X4 a
       pstcRtcInternCb->pfnTimerIrqCb =pstcRtcConfig->pstcIrqCb->pfnTimerIrqCb;

; Y& |7 o* U( @* i; F
    }

$ I1 S; }( t4 g5 j0 ^6 e: c
   if(TRUE == pstcRtcConfig->bTouchNvic)

) W( w& @* B. x' g
    {

+ r, k: b4 j# |( J  l/ P
       EnableNvic(RTC_IRQn,DDL_IRQ_LEVEL_DEFAULT,TRUE);

% ]- H  s* `1 \6 @2 ]3 I
    }
. o2 t8 t0 n; v8 G
   else

+ B' n' a, `! c' s
    {

0 K: O' A& E; b+ @; Y+ f3 B, r
       EnableNvic(RTC_IRQn,DDL_IRQ_LEVEL_DEFAULT,FALSE);

7 |( D$ t& k4 k/ U5 q. v1 d
    }

7 {, B% ^/ s9 `3 `, ~
   return enRet;
2 L, R9 v' o$ Y8 K
}

  p" z& m  x+ M4 W/ F. C* v3 T
/**
: W: A8 {' F6 k7 t" p* f: O
******************************************************************************

/ ~7 ^" c; G! `7 v
**\brief  RTC计数禁止函数
4 [* m# u3 M% V# u0 U! O+ s
**
* p" E% H# v  `  U9 i- x
**\param [in]
' L7 f- W* o9 s
**

* `& Y  O4 F3 x# u. H0 M# z
**\retval Ok禁止设置成功
% }* Y  }+ f% G
**

# ]* `' o3 ^: M+ @$ ?
******************************************************************************/
) `. e; W! q# D; k6 X7 o
en_result_t Rtc_DeInit(void)

* h8 Q8 `$ [- o" @; r
{
7 i( P- X: h. F- Y- P
   EnableNvic(RTC_IRQn,DDL_IRQ_LEVEL_DEFAULT,FALSE);

: B. r6 b# v7 F8 S2 S7 K0 s
   Rtc_DisableFunc(RtcCount);

2 F! l! C" ^8 T4 e1 r8 K, G7 @
   Rtc_DisableFunc(RtcAlarmEn);
9 G, u: R, b) l. @2 B
   Rtc_DisableFunc(Rtc_ComenEn);

0 g: Y' v  o6 X  k! \
   Rtc_DisableFunc(Rtc1HzOutEn);
3 W- h" \4 o  Q* I$ `
   return Ok;

3 Q0 K4 ]. B! L& _& @
}
8 h  W$ R6 `% A+ n. t0 \! d
/**

: k1 Y# ~' H9 X# P# ?
******************************************************************************
( K* [  d7 b" t# W1 i
**\brief  RTC中断处理函数

# h7 c( ]! H' |
**

5 k# f% n: W0 [- {: B" @2 R
**\param [in]

; R0 k, {6 Y: i) |# @
**
6 j& [5 D' c4 L  Y4 y0 S
**\retval

+ D4 G4 J9 P+ H
**

2 F4 S/ e: [  Y' c
******************************************************************************/
; E" T# w( d4 S0 F& N5 p. e; u
void Rtc_IRQHandler(void)
2 l$ A' j6 p4 T& a% U5 [, e# V
{

% G/ P9 q4 R$ |. M$ X1 |' E
   stc_rtc_intern_cb_t* pstcRtcInternCb;
" U8 ]& z" R+ _: E
   pstcRtcInternCb = RtcGetInternDataCb() ;

' ?$ k( p# _2 t2 K" o, _# P, Y
   if(TRUE == M0P_RTC->CR1_f.ALMF)

+ o( A' [: ^7 a/ R) w0 l
    {

) {0 i/ Q% h. Z+ h
       M0P_RTC->CR1_f.ALMF = 0u;
  P" S& u* K4 J
       if(NULL != pstcRtcInternCb->pfnAlarmIrqCb)
5 q/ E& ]# |4 d% c4 z
       {
/ c: e* q7 h; G
           pstcRtcInternCb->pfnAlarmIrqCb();

6 z# f% x! w+ x$ X+ D
       }

+ Z6 |# ]3 v/ \, \0 S+ h! ?
    }

# g9 r$ f$ t, }( ^
   if(TRUE == M0P_RTC->CR1_f.PRDF)

$ B  Y* c0 Y( C. p9 l1 `7 `! ?' Q
    {
" p' ~: a* Y( Z4 }
       M0P_RTC->CR1_f.PRDF = 0;

) u( ]% {# g* V% T9 Z
       if(NULL != pstcRtcInternCb->pfnTimerIrqCb)
0 d0 V) @7 Q9 `
       {
6 |8 P, l* Z# \2 d( n! V0 j
           pstcRtcInternCb->pfnTimerIrqCb();

( N3 ^3 S! r5 B% T  O' S9 w( I
       }
* t/ p1 i' Z+ m; b7 B
    }
: {9 Y* [2 C0 ?+ l7 G4 k
}

. w( q1 D8 ~% ^" n( v9 j

$ {/ q3 [9 X% A. d: ]

; V4 b0 F$ ?0 p: b0 w3 v
static void RtcCycCb(void)

  Y/ N; x! u, ?& b& p
{
* m6 ~5 l* o; W
   cyccnt++;
/ u: N) C6 g% i% I
   flg = ~flg;
1 j" a* v1 A, o( C
   Gpio_SetIO(3,3,flg);
# c  e- f& L3 N! {+ X: O
}

7 V' v6 d; x6 D% T$ @
static void RtcAlarmCb(void)
2 f* l# w0 n- m% n6 U+ k6 T9 U+ V0 x
{
( W; Z  _: o! \" i* x' _
u8Alarmcnt++;

. s4 ^; G$ L& ?
}
' ^/ n" e* Y; Y6 X3 T
int32_t main(void)

3 E1 a5 I3 f0 `& C
{
5 V: T5 K5 P. r9 F1 _1 z' z
   stc_rtc_config_t stcRtcConfig;

9 \4 a- W& w( ^  S
   stc_rtc_irq_cb_t stcIrqCb;
) ?5 ?+ k, w" d- Z& Q" r" Q9 j
   stc_rtc_time_t  stcTime;
) N( \$ K8 V" ~: r
   stc_rtc_alarmset_t stcAlarm;

/ T( |# B" l+ }! l# s
   stc_rtc_cyc_sel_t   stcCycSel;

* j9 \0 m; L: D/ c0 F5 ?9 s
   DDL_ZERO_STRUCT(stcRtcConfig);

- D6 d- T5 k$ H, ^0 T- G8 X& V
   DDL_ZERO_STRUCT(stcIrqCb);
& C" Q; K9 w$ _! V+ A$ s" }
   DDL_ZERO_STRUCT(stcAlarm);

8 t! [1 j, _4 |0 v/ h5 u
   DDL_ZERO_STRUCT(stcTime);
6 H/ O1 i& e' ]
   DDL_ZERO_STRUCT(stcCycSel);

1 J0 Y7 \1 t5 x( d4 e
   
0 w1 u. }8 I; w0 P$ u/ c$ D  ^/ }
   Clk_SetPeripheralGate(ClkPeripheralGpio,TRUE);//使能GPIO时钟

/ c& |( M% S9 L/ @) i
   
4 D8 U% d* T6 `0 k' p; ~  M
   
0 T' |* b4 m3 Y* G* K, z. l
   Gpio_SetAnalog(1,4,1);//配置成模拟端口即为晶振口
: f. [4 G+ e4 }6 t
    Gpio_SetAnalog(1,5,1);
8 D* ]( u8 E+ k4 ?% o( k/ y
   Clk_Enable(ClkXTL, TRUE);//开启外部晶振32.768   

; o8 M  v. W$ u: {# j- u1 `' q
   //Clk_Enable(ClkRCL, TRUE);
: z* J/ ~' C9 Z  S+ i3 [
   //Clk_Enable(ClkXTH, TRUE);

$ t- d% A8 d+ u7 v$ F0 N' c
   Clk_SetPeripheralGate(ClkPeripheralRtc,TRUE);//使能rtc时钟

0 A" D7 v8 U% r; Y; V* w. t
   

% E, z" `/ p: ]0 E! @
   stcRtcConfig.enClkSel = RtcClk32768;//RtcClkHxt1024;//RtcClk32;//
! x/ C0 B: I) a+ d9 }  H# r1 D8 k
   stcRtcConfig.enAmpmSel = Rtc24h;//Rtc12h;//
; }1 q6 o; z! O
     

% {2 P) Q) D/ m; Z  s: E
   stcTime.u8Year = 0x17;
( ?' |, W- ?, G8 J* M
   stcTime.u8Month = 0x06;
! M; _' R, T& h& J0 E5 @" p
   stcTime.u8Day = 0x07;
. g+ f: F5 Y2 l0 [% z
   stcTime.u8Hour = 0x12;

% [; s) i% |  d  ~" V4 X0 S. d& v
   stcTime.u8Minute = 0x59;
* t' {8 C$ J2 F) t" \8 O( V
   stcTime.u8Second = 0x59;

% u  j* x1 {$ O; @5 V
   stcTime.u8DayOfWeek = Rtc_CalWeek(&stcTime.u8Day);

8 f1 r) }( o' u% [7 r7 I
   stcRtcConfig.pstcTimeDate = &stcTime;

. t) X' R; ~$ g! I& f
   

: K4 I1 [6 V5 N4 S* N
   stcIrqCb.pfnAlarmIrqCb = RtcAlarmCb;

: }0 d- G; z0 h' h6 F5 Y0 `2 |+ C& @- J
   stcIrqCb.pfnTimerIrqCb = RtcCycCb;
# @2 [* Z  ]% x; r) V% T
   stcRtcConfig.pstcIrqCb = &stcIrqCb;

/ N1 Y( ?8 ?4 j/ X& J
   stcRtcConfig.bTouchNvic = FALSE;

4 ]) Z' i0 ^( [/ [
   
5 Y# I5 H6 L  Z* n" s1 Z
   Rtc_DisableFunc(RtcCount);
& `" c# z- J8 l/ g, e0 ]
   Rtc_Init(&stcRtcConfig);
; `/ F1 V: q' V7 L% T( y# s( @

, c& H# q: V  ]  d7 J* c( [4 l
   
! {9 D5 h$ }9 P
   Rtc_EnableFunc(RtcCount);

2 I/ h/ v, H, r- {2 v0 z
   Rtc_ReadDateTime(&stcReadTime);

+ d9 q2 n  N& @, O
   while (1);

. ^$ C1 O( V6 {9 v' F/ p* t
% G1 q0 h" I8 R0 k0 I; ]3 R* ^
}
" f/ P) C8 x1 s7 w/ X" k7 Z; H
* b" A4 H' m7 R# }2 _/ n
/******************************************************************************
- K9 V, k' ~1 u; |* B
*EOF (not truncated)
" k6 r5 _3 s, W
******************************************************************************/

" {  U$ [( g! C0 }0 Q( ~
! s; {8 s5 e$ @7 L. W5 V8 F& y





欢迎光临 EDA365电子工程师网 (https://bbs.elecnest.cn/) Powered by Discuz! X3.2