一、题目
( ~# [$ e, O7 c. H3 ?+ Q+ T* E0 F. t! p" B
k* c0 @& G/ I) _, {; t
* t8 a! b, Z- T! f, _# m6 s& H- Z! Q
* P5 x# z H" E# P
% y0 v- F0 b. _; {
9 _& ^" U% Y/ V& r2 O5 ] I! `二、模块初始化- e; \- H0 L' a! R8 C$ ?! z
这里就简单描述一下模块的配置方法,具体方法到基本模块中有描述。* ]4 n: O* B, i4 l- ~- P/ S+ r
1.LCD这里不用配置,直接使用提供的资源包就行
* z: K$ n& O' ^& F4 v2.KEY, 四个按键IO口都要配置,分别是PB0, PB1,PB2,PA0依次是B0,B1,B2,B3不要弄错了9 m/ }! \! A1 U( ]
3.PWM:这里使用TIM16的CH1作为发生通道,TIM16→PSC:800-1,ARR:100-1,Pulse:80
1 [6 V9 g- ~$ |" s9 y+ X# t( @4.LED:开启PC8,PD2输出模式就行了。; H# d+ M0 o, p
5.定时器:TIM3(按键消抖定时器) SC:80-1,ARR:10000-1, TIM4(控制时间每一秒流逝一次) SC:80-1,ARR:10000-1,TIM6(控制LED灯闪烁) SC:80-1,ARR:10000-1。
% q. n% L7 C& M" F, M
y0 w9 l3 X9 M, r M2 ]9 w7 y r
三、代码实现% b1 m9 ]! ^5 U! f2 z
bsp组有:& ~5 J. ]2 v9 |& l, ?3 U' K
& D: c6 G0 _" U/ V' C3 m- ]
: u* [" }7 `7 V: C2 n
7 M7 N8 c$ t" m: M+ X, J; W, @4 y4 K- {在这里只展示interrupt.h,interrupt.h,main.c,main.h的代码,其他文件的代码可到基本模块篇获取。4 b& C! N/ E7 @3 S) f% |
interrupt.h:) a0 c& ?1 R9 t1 u* s& D4 [
- #ifndef __INTERRUPT_H__4 @ G4 d& q( @% h& g# L
- #define __INTERRUPT_H__
9 C# X5 b$ k: z' t( N+ M3 U - $ k* [! x* w+ u, \
- #include "main.h"
5 X6 }5 J2 f3 Z! ~6 c$ K - #include "stdbool.h"1 i) j; {6 w# C+ k) h) `1 G3 v) ^
- 9 d' g( _* d% L W. W
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);+ g# W0 c7 ]# c/ }6 l2 z
7 U! d* q) L' o0 a2 i- struct keys2 ~% j4 k6 H( g% m# E
- {* F6 h. z$ g6 W4 w
- unsigned char jug_Sta;
3 I1 z: V! k# u6 | - bool key_sta;2 Z9 u7 v+ T9 K
- bool single_flag;
/ L+ ^/ q! o9 B8 d( D' ] - unsigned int key_time;7 n$ n/ {# [7 A3 b2 T5 l. p# C
- bool long_flag;
/ v1 }- \& @; B! q8 l9 x& O: c; j - };& {- s: s: b1 S/ P, E! A; p
- ; \: E4 v e0 A! W
- #endif9 g7 c2 E1 `$ P1 v P3 ~
, x6 b4 \. w8 {+ J
复制代码
- Y7 S7 R; s7 H f' y' l0 Q( uinterrupt.c:$ t6 Y2 Z$ I: b
- #include "interrupt.h"
: I8 ?& V2 o6 {, o2 Y7 K - #include "lcd.h"
5 R8 O7 \: f$ Y2 ~$ j6 O - #include "tim.h"2 ~7 W+ P( X# n' E
- #include "i2c.h"
1 l% ~: b, d( h3 M" n) J - #include "led.h"2 E6 q0 V% v( g5 {1 E, y
- #include "stdio.h"( ]) m# ~: k& |/ y; j. Q
- ! A: M' [7 E* k! }( y
- struct keys key[4] = {0, 0, 0, 0, 0};% n% b2 m6 A$ f6 m# v, G% Y* [
- extern int TimerDisplay[3];5 U+ ~9 a! Z/ F/ j4 H3 X, d+ l/ s
- unsigned char InternalTimer = 0;
+ U- Y" V r- B8 i/ L+ P' ~4 e7 Y% \ - extern unsigned char TimerMode;
: Z1 _2 Q7 O) j+ ?1 f6 f9 z% m3 ~$ ^ - extern unsigned char TimerStoreIndex;* ^1 l( G( m. i5 {3 K b- h
- unsigned char disLED = 0;% Y5 F7 |( N6 q& O* m0 d
- unsigned char LEDTimer = 0;' B) z k3 Y2 O9 B* r" }, B
4 f! P) \; x2 z& x" F/ A) h- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)3 [) ~1 k: F d9 i2 P9 H
- {- u8 D: j4 I- t( H, H
- if(htim->Instance == TIM3)/ K9 [/ P5 T4 K! ~% J
- {
/ ~$ _' }' f7 t2 ]8 ^) E - key[0].key_sta = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);
C# a; D9 b1 U6 Q, Z - key[1].key_sta = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);0 n8 t2 Z/ H, x' `
- key[2].key_sta = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2);1 ]5 p* H! I' G; k0 [7 l) T
- key[3].key_sta = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);
& a% w6 N( w. R5 }2 ?" {) Q - + h: x' E2 Q# k! v, W
- for(unsigned char i = 0; i < 4; i++); V0 K3 H# S3 i1 b3 u. u4 [
- {8 e$ ?; n; E3 T& K9 K
- switch(key[i].jug_Sta)4 Y) v, ?2 l" I* f
- {2 u( y) b/ S9 J
- case 0:+ m+ ?/ |2 I- n' p5 a
- {
* J$ \- w, Q! E) ]/ U; P* {4 e - if(key[i].key_sta == 0)
, k: r4 j' v; o! d/ K& B - {
5 `# G# \% J1 y, |1 {2 J - , U1 f9 M+ A* T
- key[i].jug_Sta = 1;
: C9 @/ F( x9 X2 X. a/ K7 n7 U - key[i].key_time = 0;
# T- `0 Y S) M: S# D - }
7 i4 g+ D0 c# B6 [( b. e; A" Q - break;
$ [! h6 _4 m; q* Y" y - }5 {1 @0 r4 ~. Q# K( {, F7 t! ~
- case 1:
) I [. y( r2 f1 `6 V1 ~) f - {" b& c6 M9 d. k) v6 a; B
- if(key[i].key_sta == 0)
1 d# }. f7 `1 W* Q2 e - {% k+ b6 K5 ^/ c/ T' B6 L$ M+ A/ q
- key[i].jug_Sta = 2;% M6 q: O+ e6 G8 X& n+ m: Z& }, O/ [
- }
: P' Y8 i- C% D0 o4 l$ H - else8 {5 Y$ z' d l' x6 N3 _
- {
, F! y8 z: m/ Q+ N - key[i].jug_Sta = 0;
8 i/ V( N( {9 t% f. P/ ? - }
, g/ G, \ }4 q6 ^ G1 X* n/ R" ~ - break;
. F& Y Y6 j) ^) c( [% B - }' W5 s. [1 K) v& x
- case 2:
1 p: q- C! S' h. h- K - {
# B& b0 [( H4 A- t9 V& _% e - if(key[i].key_sta == 1)
0 d+ l/ h3 S, \% N# L - {3 M) `& F: g7 ]
- key[i].jug_Sta = 0;
& K; h0 P A4 s8 i) @ - if(key[i].key_time <= 80)
( {# Q: V" w2 o3 ]. i# ~3 M6 x9 ] - {! X. r' D' |% u) q
- key[i].single_flag = 1;. y( ^" }% R4 ?, x7 ^, ~
- } g- d" l/ V( [1 `$ @+ w4 z
- }
0 H3 I+ _4 Z% K1 ^6 o - else
( M$ T" T- O( F3 S, b' t! z/ f - {
) {, v" a' l, v# W* B - key[i].key_time++;) r5 U( P; ^+ P& W& R+ w
- if(key[i].key_time > 80): m) [$ P* U- @9 d
- {; x; g) h( B: N. d: v
- key[i].long_flag = 1;$ a A, b/ o4 K& l( ~
- }
- i5 ^; e' v. {% ?: f' ?1 e - }6 I% s' D J M! i( ?8 r" m
- break;
4 f& V% u' V# v. L+ s/ {1 C - }' S/ O& g6 Z5 A
- }
! }8 @8 n. F: f; O* V9 i y* s& H - }
2 o- |5 m1 @4 X - }* h) {* @* V% F' ~) U. x) Y. D
- if(htim->Instance == TIM4)7 Y+ b% h0 V* ?( `
- {
- t$ R- e1 q0 {$ I' Y2 [ - if(TimerMode == RUNNING)' G) b j, d. E$ H2 c8 o4 B
- {
% Y* S" k, p. Q* \, ?# K L - InternalTimer++;' A7 ~& ]0 o4 W8 I6 h8 F
- if(InternalTimer == 100)& ~4 N4 P" K( N4 q5 B. W* G8 s$ Q
- {
/ ~; u" V3 O5 n% X - TimerDisplay[SECOND]--;
; b. }. W1 t' s) }% {6 l - if(TimerDisplay[SECOND] == -1)$ O- _# J0 d4 A2 `( f8 A8 v
- {$ }% E* w' K9 h* p
- TimerDisplay[SECOND] = 59;
+ Z- I8 y; m, g* O+ o - TimerDisplay[MINUTE]--;% P5 g; J% B+ m) A) a/ ]: ]
- if(TimerDisplay[MINUTE] == -1), k, o- ?; t! L
- {# v8 O! x, c/ |" B4 Z* w |3 {
- TimerDisplay[MINUTE] = 59;* ?0 i! K( Q) {7 A' {- g
- TimerDisplay[HOUR]--;2 |& u4 C, _2 S r8 }9 q& W2 P
- }& z6 U$ ~8 R) L/ N! b4 q
- }
" E7 `& Y- V8 I0 l - InternalTimer = 0;
" L6 @8 D q" g - }
% l8 f# [% k; Y, e( m+ c' T6 T' Z - if(TimerDisplay[HOUR] == 0 && TimerDisplay[MINUTE] == 0 && TimerDisplay[SECOND] == 0)! ?5 |2 f' Q- F6 s
- {
1 z' f; t" u* K) {% T! k: s - HAL_TIM_Base_Stop_IT(&htim4);5 O9 o& {) n: `# h7 W5 @
- InternalTimer = 0;
8 |% U" m3 L, W# e0 k - TimerDisplay[HOUR] = eeprom_read(TimerStoreIndex * 3 + 1);
6 ~' X, b; X" p3 F) j' G - TimerDisplay[MINUTE]= eeprom_read(TimerStoreIndex * 3 + 2);- Y1 b4 @9 v) O* R/ f/ U
- TimerDisplay[SECOND] = eeprom_read(TimerStoreIndex * 3 + 3);0 }. X/ l1 P; W4 T# f
- TimerMode = STANDBY;
. a) W9 i1 C% z4 J- r - }, e* h) |8 Y: s1 R% n: s r9 }
- }8 R N! n- ?: {3 q: X1 N, l
- }2 }0 {6 M7 O( I; N8 [6 f
- if(htim->Instance == TIM6)
9 H' @9 {+ ?# O, W9 B% @$ U - {8 @; A( }$ o* n5 ~' k3 ^
- if(TimerMode == RUNNING)! { H) e2 C+ K3 f0 q" y1 f
- {. o( ~+ G& \( @. o) j+ _$ W6 {
- LEDTimer++;
1 W! m; V6 k1 J1 I- Y - if(LEDTimer == 50)
/ _) o& k& }: R3 x - {
1 H ^8 N& F2 t$ k9 i2 x5 N7 ]8 ` - disLED = !disLED;1 I! O5 S: r! \6 @
- LED_Display(disLED); a# Y0 e- o/ {! I: y
- LEDTimer = 0;
1 s0 u! P1 U% L - }
! b/ r C5 c) }3 d - }
; b" u0 E, q# T - else
6 ?( o0 U5 D2 Y - {
& J9 G. |9 p! N! {1 ? - LED_Display(0x00);2 B6 _0 y! [; w( m
- LEDTimer = 0;. b' O$ P7 s p; t& |4 ^& y9 F/ A
- HAL_TIM_Base_Stop_IT(&htim6);7 _8 k I' T- Y( M5 }
- HAL_TIM_PWM_Stop(&htim16, TIM_CHANNEL_1);0 u* y# C* C* W* v4 Q" d, W
- }
1 J- g7 M# p& q2 Y- J - }) {; F$ ?& ]; L
- }
* l8 [- { |; f" U. ?% S
( L8 S2 P( ^$ }- y0 w
复制代码
; |: P6 u2 a0 A3 N. s5 z. ]/ w. x9 cmain.h:
2 t% B/ Q8 T! A6 j- p- /* USER CODE BEGIN Header */# d2 V$ A7 L! y& E" J# U0 \
- /**
4 @; |5 }* u% S) z% c - ******************************************************************************
, z6 Z3 A' k; o1 C& z2 b - * @file : main.h. z4 y) z* P( Q/ l
- * @brief : Header for main.c file.& X+ K3 _) X' Y) C6 O+ M: t" G) k! \4 V
- * This file contains the common defines of the application.
0 a- d) }- q4 i( w" ]: k - ******************************************************************************, S+ Z! G/ |1 k; Y
- * @attention6 Y. Z0 p+ b# W0 z, N( H! y% [
- *2 F' A4 Z' h" x; n
- * <h2><center>© Copyright (c) 2023 STMicroelectronics.5 m0 m) x6 W b* @# {- ?4 ~9 u# I
- * All rights reserved.</center></h2>
9 r8 _6 H9 _8 t - *9 D8 Z x# o1 t4 i& x
- * This software component is licensed by ST under BSD 3-Clause license,6 ~8 [( y3 |: M4 S7 Z
- * the "License"; You may not use this file except in compliance with the7 l" h& {/ h( T5 \/ U
- * License. You may obtain a copy of the License at:8 V) ]7 |$ ?) G6 B: M
- * opensource.org/licenses/BSD-3-Clause
2 G4 T/ m. y, o! k; G1 M' P - *
5 N5 t! p! I3 r N - ******************************************************************************
" ~) g/ o8 ~: E$ P6 q' w+ b7 A- K - */2 ^( G# h! B6 _ s
- /* USER CODE END Header */6 s# h" _0 ^7 G5 P+ Z3 i8 u; A, ?
9 C/ ^) q; E' U1 {+ p" I- /* Define to prevent recursive inclusion -------------------------------------*/
0 m# k% {' `, y4 D {# N% T8 }% O& z - #ifndef __MAIN_H
0 d1 U, L0 g% k U$ L. u' N - #define __MAIN_H
! A5 \3 B# L4 b, ^( t6 t - 6 D P3 a) V6 T" F6 P2 z9 w
- #ifdef __cplusplus
/ |" p1 G6 A% O5 U% ] w8 e - extern "C" {
. a" l. V w- B4 h8 X* s* r/ g - #endif
. n$ [4 X9 M- B - ! K3 c1 I4 Y3 Q( Y
- /* Includes ------------------------------------------------------------------*/
~* t+ ?' A4 K, I3 k - #include "stm32g4xx_hal.h"
: y! v1 j3 _6 m" M1 S5 J
2 E! ~# Q7 {* [! c C- /* Private includes ----------------------------------------------------------*/$ C: o- f- Q2 S% m/ [ V$ I* G
- /* USER CODE BEGIN Includes */8 v% A7 U. h6 L7 z4 W) C( K
- # u2 G& y$ q H, Y1 Q8 S/ g4 e
- /* USER CODE END Includes */9 T9 x" d+ \) O( S7 \: O
- " x: _/ K. `+ n) O
- /* Exported types ------------------------------------------------------------*/7 p# Z5 J6 m. b( K1 u
- /* USER CODE BEGIN ET */
. v2 Y5 t5 }+ u) ^+ k; `# D. t - ! |- b4 u4 p2 P& P" b8 t
- /* USER CODE END ET */
`& f6 f! a3 h- b6 x9 h0 N
7 u; U; W! g; X: T$ K+ \9 ~- /* Exported constants --------------------------------------------------------*/) L. ]) z# ?, N7 e. O- D* J! k w7 ~( H
- /* USER CODE BEGIN EC */
: S7 s8 L; ]) F4 M0 R8 B
3 j! ?# |. G2 h. m- /* USER CODE END EC */
3 W, M7 \4 O: n2 N+ z0 e - * b" Z& d ?, d
- /* Exported macro ------------------------------------------------------------*/# B; j! ]% [4 [+ c* a. W
- /* USER CODE BEGIN EM */
( P2 \2 s9 t7 Y - " k/ k& G0 M; s) E( }( g6 v# Z
- /* USER CODE END EM */5 Y2 R' n# a3 T: w3 g
\$ P$ N" ~6 j8 P7 ?5 {- /* Exported functions prototypes ---------------------------------------------*/
3 j. g; }5 M3 y* b9 [* A2 B - void Error_Handler(void);
/ D+ l( P& k0 `; F - 6 j% j( q, Q, F) Q6 R4 [& z
- /* USER CODE BEGIN EFP */% E- k3 ~* p* n( U7 C; f
9 `# p" q4 z' g1 Q- /* USER CODE END EFP */1 x+ J' A/ }; R R8 U0 Y6 `$ s
% a6 ?3 t5 [' P. u0 @. \1 j8 k- /* Private defines -----------------------------------------------------------*/7 c, d7 u+ f! U$ v( m; Y: I
- /* USER CODE BEGIN Private defines */( ?7 ?( [7 z2 g/ B
- #define HOUR 0
' j) i; Q( W$ \ - #define MINUTE 1; _. K5 f2 v" @# m) B
- #define SECOND 2
7 h' D7 |% J4 F4 q - #define STANDBY 0
, R) u$ o. G, ?/ h - #define SETTING 13 ~' X! h, r" z% }9 [
- #define RUNNING 25 `8 b( m+ s& W2 k9 a8 j! b: J
- #define PAUSE 3* j9 I* Q% j& y
- /* USER CODE END Private defines */
- ?0 @4 Y- \6 ?% u9 h! P
8 Q, M/ t9 a0 G- #ifdef __cplusplus& U- i$ Z! Q9 m5 O% j; h/ }6 l
- }
1 m4 n: {4 Q+ l5 }% f5 R - #endif
7 j0 F5 R3 P2 x# g7 _
6 |9 X4 H! F6 U- #endif /* __MAIN_H */8 A9 X7 j. j& r! X5 U/ l
+ `3 n. T. `: ` l# C- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/) i1 m/ ^* o9 F1 R& U, s, L
( D: A$ n6 T( M3 b- n
复制代码 9 }5 R! K9 G: | U
main.c
( v& b# f7 ?" x) Y# i' h0 V- /* USER CODE BEGIN Header */
6 N/ @. J1 {* e8 D k9 m - /**$ ^& l9 B; ~; X; o' R& Q
- ******************************************************************************
2 f9 _0 L5 D2 Z - * @file : main.c3 ? p1 S. a2 G( F2 W
- * @brief : Main program body6 W r1 O$ M0 x/ c; n
- ******************************************************************************9 Y- S( S8 G! p" i
- * @attention
" t, L0 p9 I; L$ @ - *
9 r& m H9 L6 } - * <h2><center>© Copyright (c) 2023 STMicroelectronics.3 G( F! b0 t$ N
- * All rights reserved.</center></h2>
' c* d9 w5 u, B8 n4 h - *4 e t% [1 _- F7 n d
- * This software component is licensed by ST under BSD 3-Clause license,
* B! w# C8 Y$ U8 I; V4 Y& n - * the "License"; You may not use this file except in compliance with the
9 X% p& ?7 T! J: a5 l' I( \ - * License. You may obtain a copy of the License at:1 l. }" }2 s) n1 H
- * opensource.org/licenses/BSD-3-Clause; c, V6 B: v4 l- |) \7 C
- *
* b! v' m; B% R, N8 u* h- p - ******************************************************************************6 {4 O" B6 r: R& F; X7 a, w
- */
5 g) X: e; C* p" n - /* USER CODE END Header */
! Y! _- A7 e$ e& p, E, ?5 s& M - /* Includes ------------------------------------------------------------------*/) q. | b- e. ?$ V
- #include "main.h"
7 z1 V% M! B6 e$ v, f& Y - #include "tim.h"
. P6 t- Q: N+ z* v( G$ d6 M - #include "gpio.h"$ P" T$ `; X$ ?3 a2 Q- X1 d2 V
- 5 b5 d% b7 m& y0 v( | ^; U
- /* Private includes ----------------------------------------------------------*/
! S+ K! E: u! u" [8 T - /* USER CODE BEGIN Includes */
2 v, A. K* z% k2 W# v k' M X0 T' {0 W - #include "lcd.h"
& s* X& L! Q! m0 |. I - #include "interrupt.h"" W! Q* Z2 f' m( V- }
- #include "stdio.h"
: u/ L7 a& z- q# f# w - #include "i2c.h"
9 D/ U& w" T; z$ q5 J/ v4 S& N - #include "led.h"
; N- }: I6 I. L$ ?! K: O4 U - /* USER CODE END Includes */) S0 r* ^, v7 N3 p' A
! ?' g- T/ g# J! v" S! n- /* Private typedef -----------------------------------------------------------*/
# y( e6 o; r" H) I - /* USER CODE BEGIN PTD */2 Q! ~7 @: a3 ?4 a! E
+ y# R6 j C% l+ r3 c7 x- /* USER CODE END PTD */
. V" `9 V+ `( s' K* S - _$ W1 \6 R/ g5 S9 q
- /* Private define ------------------------------------------------------------*/
. A# f9 U1 j6 O1 X- H$ j2 F - /* USER CODE BEGIN PD */3 ~- f* s9 B2 ?& o! d
- /* USER CODE END PD */% B8 H) ~" ~4 S0 p' C/ |* {
- 7 r& ^! `' Z# [9 {7 @
- /* Private macro -------------------------------------------------------------*/
; X4 ^% u! \+ Y8 M$ U - /* USER CODE BEGIN PM */
3 z1 Q7 c2 T4 c" }8 f9 p1 M - v- S5 x: `3 k9 @
- /* USER CODE END PM */
, v5 N& b x/ v
6 `* v/ }4 Q. o" ^3 _( j0 u- /* Private variables ---------------------------------------------------------*/
3 l- b+ g4 H- ~* f+ o+ |% S
/ e" @) h- z7 \# x2 D6 j( D9 {- /* USER CODE BEGIN PV */
" P5 x& h: {) d& G# ]3 J& Q. [ - extern struct keys key[4];
7 D1 r: F+ I6 g! b3 W - unsigned char TimerStore[5][3];% s* }( S9 @4 u4 { L/ a. [
- int TimerDisplay[3];
2 z4 X" U: V" B4 R v- E) h$ O - unsigned char TimerMode;$ H- J3 K% } U
- unsigned char SettingTimeIndex;% G1 S- U5 p$ w2 k, C+ i
- unsigned char longPressBufferTime;
* o' ?. S$ [$ m3 m" n+ T g6 R - unsigned char TimerStoreIndex;7 c/ {6 o; m* `" c
- extern unsigned char InternalTimer;
3 B( H6 ]& D2 u& `4 w5 C$ _6 _3 w - /* USER CODE END PV */# ]" b& R, c: ^! d- D
- Y' f! E- }7 r# T7 S$ r2 g- /* Private function prototypes -----------------------------------------------*/2 H1 f* e7 \4 _
- void SystemClock_Config(void);% f, x) C% ~+ l" C) {* @
- /* USER CODE BEGIN PFP */
' t. e- {% l ^& D" E* D* s - void LCD_Display(void);6 [7 L1 L* X2 G- J
- void DiseposeKey(void);/ L8 \& w9 Z; T* R! N/ y
- void LCD_Flash(void);
0 O2 V5 g& A' V/ C% P/ w& G! J% r - void Store_TimetoEEPROM(void);
m3 I+ P3 \. n) v" T - /* USER CODE END PFP */
' Q7 r4 }% o6 z - & T1 M0 D9 z1 v9 H! C r" x5 p
- /* Private user code ---------------------------------------------------------*/
2 i2 Z, d! V. w - /* USER CODE BEGIN 0 */
1 ^7 W0 `4 N4 S - . ~3 m# f3 R+ M$ U& l2 O0 h
- /* USER CODE END 0 */7 b& s) X; j, ^- A* {
- 9 V. Y0 y; a8 e
- /**2 Q1 k# a+ v$ ?, a% d' l
- * @brief The application entry point.* ~4 ~7 T& C- b
- * @retval int
2 ]1 X# |( |- D$ t6 } - */
; J l5 {, w3 o8 T w - int main(void)6 a& O% y/ D% q5 r s' \
- {
( X7 b+ r9 g; r2 m$ Q" l - /* USER CODE BEGIN 1 */7 W$ M) z- ^3 \2 S3 `
- : r) T& x# Y9 ^" ]$ d7 v* [; b
- /* USER CODE END 1 */
2 Q) r+ Z7 ~# C, o3 {% ]
$ K% a, }8 W( g& w2 R1 p- /* MCU Configuration--------------------------------------------------------*/
1 y, @) K6 C \" P* a( r" y8 ^' k - 8 g2 ^$ {2 d4 t* F
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */8 [9 b2 {1 W" |- G% E
- HAL_Init();) Y* P. ~ e- f9 b. \
$ ~ `: a' x4 R2 |+ W4 o7 I+ T+ Q9 X2 v' @- /* USER CODE BEGIN Init */
8 Z1 f2 m7 c5 n" a, J0 [4 D - 8 r) d' \2 Y! j2 }* R
- /* USER CODE END Init */# i! Q; l0 R, V; k S
- ) O. V ^/ M- c' B, r' Z. Z, y1 u, a
- /* Configure the system clock */
0 C9 S* m$ F6 E1 G. N. }- t - SystemClock_Config();
! B' p; n2 b Q! E/ u& o - 3 I: S3 `+ j j, k
- /* USER CODE BEGIN SysInit */
+ y, t- v& _ _1 \4 H) e- U6 q, S - ! x' T* o! N; {+ j* Q3 e' C) x
- /* USER CODE END SysInit */5 J$ V& E" x: s9 F0 u
$ J3 o" j$ a( c: D$ Y1 j- /* Initialize all configured peripherals */
) |1 N t+ z0 E3 W# V. k/ e t - MX_GPIO_Init();. p0 |# Q! Z: W! F. C
- MX_TIM3_Init();
: B" B! |/ l# x! |9 M3 N2 S - MX_TIM4_Init();
+ A2 l& W r: k, `( O j5 G - MX_TIM16_Init();
6 a& o) P' ?! M/ j4 b, v* X- u - MX_TIM6_Init(); t5 V3 f5 f6 y W; w
- /* USER CODE BEGIN 2 */, R9 X( J% k5 c
- LCD_Init();
) h/ I8 H- {& o - LCD_Clear(Black);
$ Q3 x! H" W# V/ ?* r, p! ` - LCD_SetBackColor(Black);
/ J% B) G: B, Z j - LCD_SetTextColor(White);* ^# ?$ H2 U+ H' |
- HAL_TIM_Base_Start_IT(&htim3);
; S" F8 W5 \7 P% E c" | - LED_Display(0x00);5 E; K' a! R" j: q/ e! [9 P
- TimerDisplay[HOUR] = eeprom_read(1);
- J% T6 [5 \9 G4 O" I+ j - TimerDisplay[MINUTE]= eeprom_read(2);" m$ s4 e0 u( P
- TimerDisplay[SECOND] = eeprom_read(3);. T- C- B: X5 W" \& j
- /* USER CODE END 2 */
2 j. B8 V* l5 t) D
+ I( U; r: z9 K. \- T& j5 c/ I9 y- /* Infinite loop */
3 r; Q: K% n. A" x - /* USER CODE BEGIN WHILE */# Y* g' b o3 J( P2 o% S
- while (1)' H' H) V6 P* K9 _2 P
- {
, ~& `& T: f* U3 ^! l1 a' a7 u- g - /* USER CODE END WHILE */* X2 I5 }2 P4 M0 n8 K
5 F5 x3 @! }2 s) D8 Z8 Q+ B* r- /* USER CODE BEGIN 3 */
: b* g% U: ^+ d - LCD_Display();
' g; d& T. l) |/ {9 E! f - DiseposeKey();" \% K" ^9 R7 |" B' X. U+ v& X) @
- }1 f* r' D: U. t* C4 ?
- /* USER CODE END 3 */
% f/ ?/ M+ j& d H1 u3 x" n9 w - }4 _8 g6 l4 G, k/ M; Z
6 C1 n1 C( i8 X- /**
4 L" @' E" ~( ? - * @brief System Clock Configuration
, I4 v- p, Y4 @4 f - * @retval None
! d! O, b0 ^; {7 C4 I, k - */
7 u$ |5 N: p: y; m - void SystemClock_Config(void)
3 X* w9 {6 r- y4 n. I9 r5 p - {/ y) r0 A( Z8 ?' O2 C( r
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
$ s( C. h9 U: g - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
; \; ^ G* G: D2 r - & s$ h/ b/ [8 T0 Y3 ~
- /** Configure the main internal regulator output voltage) i- C: }' t- f) q( ]! T3 X
- */
: C: }6 G2 c. w+ x ~4 p" L, L6 H - HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
5 ^# N/ W* G2 o - /** Initializes the RCC Oscillators according to the specified parameters$ u I: ]! C, y$ m* u: r1 L0 L( P
- * in the RCC_OscInitTypeDef structure.+ v9 W1 f) ?% d) E
- */% ^3 U- a. Y/ u" Z+ B6 Y" Y
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
1 X/ H3 c) V" U& m) B/ g q; x$ M6 T - RCC_OscInitStruct.HSEState = RCC_HSE_ON;
" L6 X! F: g' @. `7 g - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;* z9 u9 h7 q; V/ c$ _4 \
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
( S0 {1 ]: ?# U# V0 y - RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;1 d0 P7 v+ w9 r$ y
- RCC_OscInitStruct.PLL.PLLN = 20;# ^6 ~, G- W* T! i. f0 o( t$ O3 m0 _
- RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
% f8 n6 o( k l( G$ {, X - RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
0 v) `' L- {. z C - RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
; w l" v, n% r - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)( }' X8 ?" R9 c) ?
- {
: Z+ J. G5 R( @( n' n2 W, ^2 \ - Error_Handler();
$ F6 A8 C) P) S2 N0 P0 @ - }2 @) \, Z a# z2 f/ i j2 T$ E
- /** Initializes the CPU, AHB and APB buses clocks( R6 s8 Y) v ?1 @# t
- */
* S( ~7 h! ?/ Z& l2 }! l4 a - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK1 |7 J/ K( p! i
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;1 u0 R4 h' V4 Q; s) K) D0 r3 y
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;: v2 s/ Q+ [$ N' }. U
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;( A7 d. ~# j! g
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;5 z/ |, R$ ?$ N4 C% K
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
0 W/ Y% g( W. M6 x& {) b( e
' W- d% _1 A$ E' ]* c! O3 y- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
, ]# P) H; g. d; J0 U5 L. I, _0 u - {: G6 U9 I; w( `+ ^) _+ U
- Error_Handler();+ l) t% _% U7 {1 t5 `2 x m+ g1 a
- }
8 ~! J6 H2 B$ g; w/ Z3 P - }
, F0 G- Q' R4 U3 p
. l D/ G: I: b @( B, g- /* USER CODE BEGIN 4 */
0 `3 M# o6 Q& n* I6 [! d% e4 @, n g - void LCD_Flash(void)# Q) m$ C+ q m
- {
9 G! R. ^7 \4 q" ` - switch(SettingTimeIndex)
+ y% e: S$ }$ r$ L* A - {
' V4 [1 L$ k; H/ c) K) t* i) O - case HOUR:2 R, _7 D" f$ g7 {. t2 N+ ` n
- { }' C& N4 f+ i' r
- char text[30];; V& Z. t+ g+ u
- sprintf(text, " %02d: : ", TimerDisplay[HOUR]);
3 c* ^" M/ D1 @3 S - LCD_DisplayStringLine(Line3, text);
& C: z; o6 \: g s: _/ ?* G - break;; M* ]; ~7 z! j. z
- }2 F$ _9 F9 C, |' V6 V
- case MINUTE:/ N: Z2 D d/ Q3 t% |2 ?% k# Z
- {+ S" K1 e5 e. @, Z# {# w, B
- char text[30];
' }- `0 h# S. X! `' ]( c - sprintf(text, " :%02d: ", TimerDisplay[MINUTE]);$ h# N8 v# d+ ~$ y3 X
- LCD_DisplayStringLine(Line3, text);* F* X+ r1 M5 P+ R. {7 b0 S
- break;
8 x N7 ^- Y# N* I- | - }
" {: N! f% C) Q. k- s - case SECOND:
. |6 L; I1 T% T% {6 n$ ~2 G - {
5 K( K# i5 N" H5 e$ d+ H: U |3 H8 ] - char text[30];1 N5 ?9 ?7 S7 a$ `) `9 F
- sprintf(text, " : :%02d", TimerDisplay[SECOND]);, d) K* L \0 L W6 L) W$ i, ^( P
- LCD_DisplayStringLine(Line3, text);
8 N6 i1 _6 ?" b @2 [/ n - break;- b4 O& k; U) t. _
- } U* n, E* m/ l W6 r& p1 s+ C
- }, a' L" N: t% S
- }
1 p e6 |6 {/ Y: w
1 x) g7 t0 y) ]7 ]- void LCD_Display(void), g9 F0 K! f1 s: O5 a
- {
1 N8 q) n7 E' l0 S7 x- _ - char text[30];
% m: X3 p$ Z8 e4 ? - if(TimerMode == STANDBY) [% @: \$ ^ ^
- {
' e9 x0 u' B5 j4 Y( `, Y) y8 I - sprintf(text, " STANDBY");
: b8 }+ S# I6 y& L - }" e7 J+ h J9 i4 f0 \( j8 k1 h
- else if(TimerMode == SETTING)2 {) z O2 e6 E* \; v# M
- {7 i0 X0 I7 e# `* Q
- sprintf(text, " SETTING");: \# m, c e$ e; V4 i' Z
- }
! ^1 H; O% ^* Y - else if(TimerMode == RUNNING)
* H) x( k9 c& \. e8 ], n - {
2 G4 _+ f" L9 m - sprintf(text, " RUNNING");# H4 q& `5 B- R; B' ~
- }
. Y% B, b" ~* q) j% n6 a6 e- u( ^* } - else if(TimerMode == PAUSE)
. ^$ t3 s% h" I4 ^ h - {. i7 ~/ J8 p( m
- sprintf(text, " PAUSE "); $ a: ^6 Z8 {" x
- }$ o, z/ _2 ~: K- ~
- LCD_DisplayStringLine(Line5, text);
6 q" _( P5 H, I. c6 s - sprintf(text, "NO.%d", TimerStoreIndex + 1);$ c0 N% r5 x: i+ ?! e
- LCD_DisplayStringLine(Line1, text);+ G8 H! ^& Y! t" K
- sprintf(text, " %02d:%02d:%02d", TimerDisplay[HOUR], TimerDisplay[MINUTE], TimerDisplay[SECOND]);
( D8 y9 V, `/ g9 D' Z# t2 Q - LCD_DisplayStringLine(Line3, text);" H: l% w5 L) O" U
- if(TimerMode == SETTING)! d0 E( T! v9 Y8 o& W
- LCD_Flash();
' G3 a- s& f; Q: N - }# s, R7 } x4 r0 B
- ) j M' |; h* v. y" \
- void Store_TimetoEEPROM(void)
$ T& c# c; l. n3 b/ f9 k4 f - {1 z: l a+ m/ Y( f( f" e( p" t# O
- eeprom_write(TimerStoreIndex * 3 + 1, TimerDisplay[HOUR]);8 U* x0 w9 s7 g9 B! g
- HAL_Delay(2);3 j- k( T$ P& c; c' Q& J
- eeprom_write(TimerStoreIndex * 3 + 2, TimerDisplay[MINUTE]);/ I! P7 r& Z' I
- HAL_Delay(2);/ ~1 o* ?/ l$ f
- eeprom_write(TimerStoreIndex * 3 + 3, TimerDisplay[SECOND]);6 s6 c% d3 h: R. W+ Q3 Y1 C
- }* x( Z6 q: e& G4 J0 e
- 9 q, ~8 l3 j) q4 B
- void DiseposeKey(void): p& c& _. q3 |1 h2 X0 }* ]
- {# E6 c8 b' K2 u$ V; @! o( s
- if(key[0].single_flag)
9 ^# c, V! v4 u% h0 { - {" Q2 _ T8 l+ V5 |3 n
- if(TimerMode == SETTING || TimerMode == STANDBY)+ p* |* E( Y, U0 q
- {
2 ~9 ?& F3 x9 U - TimerStoreIndex++;9 P7 W6 b9 C8 D; m: u
- TimerStoreIndex %= 5;
8 B- c8 _! T5 w' N# ] - TimerDisplay[HOUR] = eeprom_read(TimerStoreIndex * 3 + 1);
1 [" t5 A3 Z9 C/ K, c& F, t4 T3 P - TimerDisplay[MINUTE]= eeprom_read(TimerStoreIndex * 3 + 2);4 j( h& O I/ q- {1 [, _
- TimerDisplay[SECOND] = eeprom_read(TimerStoreIndex * 3 + 3);
$ i" R4 D6 E9 u1 \! } - }8 @" \' X# l# V0 p B
- key[0].single_flag = 0;: t4 B6 n0 q5 x" |
- }
: T, [0 x- Q, |" r - if(key[1].single_flag)" ]3 w2 Z+ |' E2 U( O& @3 D6 v
- {
: K' ^: O: F1 \ - if(TimerMode == STANDBY || TimerMode == PAUSE)! O( S3 e' X0 B; {0 H
- {( _' h: q$ ]7 L" Q, v( g- e q% N6 t
- TimerMode = SETTING;
* S3 ]8 ]7 x: C) l- ] - InternalTimer = 0;* _; m: Y1 b8 q5 D. s
- }3 f" X8 s) y) r+ C0 r
- else
. j z! G) i- }* d - {' F% J; D2 s$ W. ?
- SettingTimeIndex++;
/ W7 T: T2 w( ~6 D# t - SettingTimeIndex %= 3; 9 k% T E& F# w8 n
- }+ u5 V5 ]9 x3 b& t$ c
- key[1].single_flag = 0;" ~' h) K Q! O5 H- X N3 i9 ^; X8 B
- }
" n7 s2 T, c8 e. g6 H - if(key[1].long_flag)3 w$ E- s- q+ U: B8 ^: w
- {+ D6 m2 A1 v' _
- if(TimerMode == SETTING)
6 a6 @2 ~' a2 x& q1 v7 I# ~ - {$ A- O4 | z, Y4 T! [5 B$ W; h
- Store_TimetoEEPROM();
5 v& h/ ^0 g% f( B - TimerMode = STANDBY;6 I( P! X; z6 K* F$ Q- Z0 G# t
- }
7 X6 h Q$ Z- v8 u2 h - key[1].long_flag = 0;
+ p# i( p! F2 @: I8 W - }
& N8 ~* G0 }$ o5 J3 C - if(key[2].single_flag)
6 M6 M8 ~' r+ [% k - {2 z. T5 U0 L& u# E2 s. P# y
- if(TimerMode == SETTING)7 L/ l: c8 ~0 m( b+ t! W& [
- {
( W; s1 r3 a- L9 N - TimerDisplay[SettingTimeIndex]++;% l% D3 L' c e4 Z* a; a
- if(SettingTimeIndex == 0)
' H: g( e, h- d9 a - {
$ L+ I9 @* w5 ? P& _) f% K - TimerDisplay[SettingTimeIndex] %= 24;
0 Q0 q9 z/ w/ t. c% b( K1 Q" Y - }
/ [7 ~, Y* N" w# e$ N6 P, f+ M - else
0 i7 }* }. u7 N8 [- Z: V - {
- G6 a5 g" g2 ] - TimerDisplay[SettingTimeIndex] %= 60;
P: L+ L% W0 X0 ?8 E - } y; g( u3 K5 w' O& r
- }
3 B. k7 s8 Q$ F. p0 u5 M - key[2].single_flag = 0;
5 ^8 S2 T6 J6 E5 r. e; Z - }; J7 }. h+ d0 D: ~- e2 p( S
- if(key[2].long_flag)
$ Z4 ~% K0 ~ f* _; R" ?+ k - {* t# i* D! [& U8 c* g4 W4 T
- if(TimerMode == SETTING)
9 i z* o3 Z4 O7 b1 A1 e - {0 X# M' @( i- O% l* H
- longPressBufferTime++;
% o V9 f$ u& _# I* v* g1 O6 B - if(longPressBufferTime == 10). m% x: j$ T6 e; J5 e2 d% N
- {' E! h3 S1 Y2 N0 b& Z
- longPressBufferTime = 0;! N, `4 R. G" j
- TimerDisplay[SettingTimeIndex]++;
5 D1 z7 |$ W$ h1 q0 G& ~ - if(SettingTimeIndex == 0)
6 [, \" c0 @- D0 W8 ~ l - {" a2 Y$ ^ d, b o. ]
- TimerDisplay[SettingTimeIndex] %= 24;
# v# ]3 T- Z! f' s2 C; w# N - }
. R" l% ^0 k, |2 u+ R6 z - else
& T3 h1 t1 S3 X- ~1 G - {# p. G( y- U4 k
- TimerDisplay[SettingTimeIndex] %= 60;
- z9 f% k5 m6 ?! c! L - }8 k$ Y6 I4 d3 R% C, M) Z% K' W
- }) C1 U; i: J; U5 T( b$ {
- }. |8 [" Q* m+ [1 V5 c8 V
- key[2].long_flag = 0;/ V. L$ ?4 e' [9 Y
- }
2 o" `6 p% l) ?9 Z& Y8 Z% [8 r - if(key[3].single_flag)1 n1 J2 C ~- b1 p
- {
: d( |+ {( \' F - if(TimerMode == PAUSE || TimerMode == STANDBY || TimerMode == SETTING)4 h% w& e1 ^# @% I' U9 h8 ^5 H
- {
9 q1 B7 W8 B& s! Q - TimerMode = RUNNING;6 v% V- G4 ~9 y* x& O$ N
- HAL_TIM_Base_Start_IT(&htim4);5 f( N/ j. {8 N- _% W$ J4 _. a
- HAL_TIM_Base_Start_IT(&htim6);
7 C' ^" O! Y- V9 ~6 F - HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);
' F% s( ]3 |( @ [: A, J" h; X. ] W P - }
0 x9 y1 e5 ^% r - else if(TimerMode == RUNNING)& t4 H3 N7 X$ F3 X, b+ i
- {
( X L+ |* @- i- Q* g2 {$ L6 ~ - TimerMode = PAUSE;, D& b' [( v# R" V9 j2 g+ A
- }' L8 [& h& s7 p$ x6 y9 f1 G
- key[3].single_flag = 0;
( @ T0 p# h. k4 c1 s& @ - }
& H( Q/ F( Y* B+ a9 y7 T -
4 L+ Q4 x* ?: g - if(key[3].long_flag)0 j- y) u8 U& c2 {" s
- {
" R; M$ i0 A7 u! |3 H - if(TimerMode == PAUSE || TimerMode == RUNNING)* K/ P& H7 C3 d% E" v
- {+ Q: X# ~6 f/ G7 N/ I- [4 M
- TimerMode = STANDBY;
& ?% f4 Z g, ]7 Z - InternalTimer = 0;
# a# u6 V6 u" K: n8 d - HAL_TIM_Base_Stop_IT(&htim4);- t4 D% y `" W% f4 L
- TimerDisplay[HOUR] = eeprom_read(TimerStoreIndex * 3 + 1);
# I V( n$ l% m; u - TimerDisplay[MINUTE]= eeprom_read(TimerStoreIndex * 3 + 2);
" ` B$ U9 f1 J3 p4 L( W, a - TimerDisplay[SECOND] = eeprom_read(TimerStoreIndex * 3 + 3);1 i. U) I. R4 R; C: m
- }. C y* z& l, G% F3 f1 v- l4 P. Y
- key[3].long_flag = 0;, |% F/ s* D8 F
- }
1 e1 H, N/ N, Z9 v; e7 z - } D% W0 y) I7 b7 j" y! W4 I% y/ e
- /* USER CODE END 4 */
, ^- s( D/ t% X. E) Z7 ]
! B6 @, r! m+ f6 N" R" v* d, ?- /**) ~; w+ E' |. X3 h% t6 E
- * @brief This function is executed in case of error occurrence.
* o K! w% J9 }6 B" c1 ?2 ^& v - * @retval None
# ]$ y' P- U7 \) ^. \ P - */
/ n# O' h9 X8 L - void Error_Handler(void): d- P3 d/ q- c2 d. ]
- {0 E2 ]- x+ `3 Y$ W3 l6 b2 |
- /* USER CODE BEGIN Error_Handler_Debug */
0 `9 f+ D- {" H) W6 w- l - /* User can add his own implementation to report the HAL error return state */5 B. r, p" b# B/ b
- __disable_irq();
- E1 w; G) l8 @2 W7 K8 \ - while (1)& N/ t* a" J0 \3 }, G+ z% O6 x7 j
- {+ K' A, u7 f: h
- }
" {$ x% N1 v6 Q+ ?- u W - /* USER CODE END Error_Handler_Debug */+ u$ q0 D8 U Q. m
- }$ G. a' g" i( a- S
- ) c6 @& s5 Y8 b; a4 U3 k$ i: v0 [
- #ifdef USE_FULL_ASSERT
+ B3 d6 N+ W% N - /**
, m" {: b. e3 D4 ]% [' A2 z* c j - * @brief Reports the name of the source file and the source line number! P' f, @# n W
- * where the assert_param error has occurred. d) T: E+ t5 J8 Q$ t [
- * @param file: pointer to the source file name
3 T2 f" ] [4 m) Q6 ]9 I - * @param line: assert_param error line source number4 P; u/ ~! c. z" k
- * @retval None8 ?5 P- c! F0 q. I% j
- */3 V! u& p) @) U- W' r; Y7 J# p
- void assert_failed(uint8_t *file, uint32_t line)
6 d# {3 n# ?3 A4 t/ s - {8 o3 ]7 v+ t. q( Q; k3 d
- /* USER CODE BEGIN 6 */
2 s+ _8 |6 Z& r" q. K - /* User can add his own implementation to report the file name and line number,4 C8 r2 ?- J' n/ n
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
: y. m/ c0 i1 }# a4 i$ {# f - /* USER CODE END 6 */9 a R, g; `8 @7 E9 }. i, G; P: ^
- }! u+ E0 Z- i% l$ R9 s: T
- #endif /* USE_FULL_ASSERT */
Q: j+ }- W, o1 [3 N( \
. _% v" o3 e, L; [2 L0 _) H) r' x9 V) t- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ \/ g; p. W1 n5 ? O1 n
复制代码
% S! a4 [) t J7 F4 x' J0 |9 q7 ]* W————————————————
/ K& Z8 B, @+ b6 C6 Y9 d7 D版权声明:火花页.$ o `0 D9 D+ s6 o8 a+ Z
n6 O+ Y# [. t- i% J
; y5 N. i! ]. X4 F
|