你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

NUCLEO-STM32F767+PWM呼吸灯

[复制链接]
队长shiwo 发布时间:2017-7-27 21:01
本帖最后由 队长shiwo 于 2017-7-31 17:49 编辑 # C0 l9 F! v! M% ^2 ]( \
( u: z# e4 k: B7 Z0 `/ T7 }0 ]3 W
       脉冲宽度调制(PWM),是英文“ Pulse Width Modulation” 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。 tttttt.png ' i0 k$ |* A: _  n$ f% L% {
        图中,我们假定定时器工作在向上计数 PWM模式,且当 CNT<CCRx 时,输出 0,当 CNT>=CCRx 时输出 1。那么就可以得到如上的 PWM示意图:当 CNT 值小于 CCRx 的时候, IO 输出低电平(0),当 CNT 值大于等于 CCRx 的时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率,这就是 PWM 输出的原理。
) ^- G' R$ c9 l7 _' v( j      使用NUCLEO-STM32F767ZI的PB0输出PWM,实现LD1的呼吸灯效果。板子上的PB0可以控制LD1的亮灭,刚好PB0是定时器TIM3的CH3通道,可以用来输出PWM信号。 tt.png
, _7 O& v0 ~# [+ g ttt.png t.png
& X; O4 @$ N, r
% G8 \" l0 i* e9 U& I% [$ G6 V" l  XCUBEMX配置初始化:4 V1 m7 i( @5 _5 h& {
tttt.png ttttt.png
6 \. K' w8 P0 b' b3 {  m; Y3 i; J$ [! b5 j6 E  Y5 O( R) G" E2 H' f4 M
主要代码:) j, j3 x2 ?7 v9 _
  1. TIM_HandleTypeDef HTIM3;9 r% _7 p/ U, l! j7 E, d
  2. TIM_OC_InitTypeDef sConfigOC;
    0 x  ]6 }3 ]2 \! X
  3. /* TIM3 init function,APB1 Clock:108MHz*/
    + _# }/ E6 [9 j: U) b) X/ u2 A
  4. void MX_TIM3_Init(void)
    8 M% D* D, o* I( u. j
  5. {
    ) F% ?; U0 R5 l8 g' ~7 H
  6.     TIM_ClockConfigTypeDef sClockSourceConfig;
    / M- I5 ^9 ?7 ]% M& K+ t( I9 J
  7.     TIM_MasterConfigTypeDef sMasterConfig;' k7 Q# r" \5 r* {
  8.   ; c2 {4 K+ B; L# _

  9. 0 c& y" e1 b: c- |4 D5 D
  10.   HTIM3.Instance = TIM3;" R" K: s: G- x5 U+ l& J
  11.   HTIM3.Init.Prescaler = 108-1; //预分频值PSC                                108MHz/108=1MHz6 T5 }1 s1 e+ \
  12.   HTIM3.Init.CounterMode = TIM_COUNTERMODE_UP;//向上计数  ?: H& Q- P! P/ }+ a
  13.   HTIM3.Init.Period = 500-1;  //自动重装载值ARR                    PWM频率:1MHz/500 =2kHz+ ~' C" a2 Z* B+ U
  14.   HTIM3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;//设置时钟分频因子* h" D: v% _% N9 x+ ]) W9 H5 Z
  15.   HTIM3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;//
    . P/ b! r! {0 T! L. K
  16.   if (HAL_TIM_Base_Init(&HTIM3) != HAL_OK)//初始化定时器 3
    6 M9 O' t$ r' @) S% v
  17.   {5 N, ~6 Z% d6 U6 v$ G1 I
  18.     _Error_Handler(__FILE__, __LINE__);9 l- c4 I; u1 I$ r' Y, R
  19.   }
    % @! t( f4 ]4 f) K4 ]8 u: l
  20. 8 Y. i1 @* S& r- M5 i
  21.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;//时钟源使用内部时钟APB1
    , F4 M: ?4 s! U! u
  22.   if (HAL_TIM_ConfigClockSource(&HTIM3, &sClockSourceConfig) != HAL_OK)
    ; k' s( K* D9 j
  23.   {6 i, n4 i9 ~4 I
  24.     _Error_Handler(__FILE__, __LINE__);
    / j. l. p5 j) c
  25.   }
    : D: N  T  }3 J" h# ^$ ]- q8 f

  26. ) c7 p! l6 e9 [8 M2 Y8 t* R, l: h" B
  27.   if (HAL_TIM_PWM_Init(&HTIM3) != HAL_OK)//初始化PWM$ G( Q. W. X" P, e7 f
  28.   {& {! h& q. r! P7 {- }
  29.     _Error_Handler(__FILE__, __LINE__);3 z2 l0 Q+ m, r* a
  30.   }
    : O9 e4 o5 S+ I0 v. H" _  `3 w

  31. . Z4 f' z: p4 R& }, U: B7 T1 C. |
  32.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    ) I, M) ^8 u3 j5 z
  33.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    & Q+ A: Z- r/ P& @1 Z4 D
  34.   if (HAL_TIMEx_MasterConfigSynchronization(&HTIM3, &sMasterConfig) != HAL_OK)//" f. [( z! E" q
  35.   {
    + [: P8 g: ~3 k& t, }& s  G
  36.     _Error_Handler(__FILE__, __LINE__);% J' Z' T, n( A( Y) H% ?
  37.   }6 M, \/ j* s3 ]+ Q  C" Q% Z

  38. ; S) G, L6 H7 a1 A% s; u
  39.   sConfigOC.OCMode = TIM_OCMODE_PWM1;//PWM1 Mode8 P- B' W2 _- V: E  R; s
  40.   sConfigOC.Pulse = 0;               //捕获比较值
    ! m9 ?& K' ~7 q% @7 @
  41.   sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;//输出极性高
    4 _. m: R; Q& S; b. X' R6 k
  42.   sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; //快速模式9 ~5 S/ B$ j- \2 ?6 V0 q" g% K
  43.   if (HAL_TIM_PWM_ConfigChannel(&HTIM3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)7 H1 k: @5 K' e7 t# T0 a
  44.   {
    " b: O  p% ]3 w+ |8 i( B( A3 O
  45.     _Error_Handler(__FILE__, __LINE__);
    / n, h+ G# V; G% p+ v, v2 Q- S
  46.   }1 e+ F5 h8 f" S# G
  47.   HAL_TIM_PWM_Start(&HTIM3, TIM_CHANNEL_3);//开启TIM3通道3的PWM$ y) K/ V2 x$ {- J
  48.   1 a4 Q0 F9 l: s1 c4 `
  49.   HAL_TIM_MspPostInit(&HTIM3);
    ' G7 {8 H; s) \; Z. Z% k# }( n" h& U
  50.   
    + L4 t( U7 |, v7 h; o. v
  51.   //HAL_TIM_Base_Start_IT(&HTIM3); //使能定时器 3 和定时器 3 更新中断
    ( Y$ _: B6 _0 d
  52. }
    ! x$ C8 Q3 R" `" x8 m$ y
  53. ( w9 X- [" D& v" `) S; X9 w( m
  54. //定时器底册驱动,开启时钟,设置中断优先级( |/ x6 o% S6 k7 y; Q1 J
  55. //此函数会被 HAL_TIM_Base_Init()函数调用
    / a6 G0 e- m+ e  m+ l' Z* H
  56. void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
    ; F' a. o% v. ?
  57. {3 x  ^4 Y0 C+ q: t1 A7 K5 e: r% j

  58. & Q# |5 @; G; l8 z
  59.   if(tim_baseHandle->Instance==TIM3)( O/ b: `; t! C3 l( k
  60.   {
    ' |, \. |7 Y( Y4 O2 y8 J4 [
  61.   /* USER CODE BEGIN TIM3_MspInit 0 */
    0 M" D" {# Y2 C$ S) l; l  o! G( j: }
  62. $ y7 C8 F) ?- p! g; Q
  63.   /* USER CODE END TIM3_MspInit 0 */% o/ _0 j3 S) ]8 g
  64.     /* TIM3 clock enable */( `" W; `) X' _. Z
  65.     __HAL_RCC_TIM3_CLK_ENABLE();+ c( ^, \; w* [5 j

  66. 9 n8 ?' X8 w3 n/ N9 h
  67.     /* TIM3 interrupt Init */7 {7 U1 H) Q' R, A% l  {, `/ z! y! F
  68.     HAL_NVIC_SetPriority(TIM3_IRQn, 1, 1);4 }, F3 U7 z# V8 U* y2 `
  69.     HAL_NVIC_EnableIRQ(TIM3_IRQn);
    - F4 J: P9 g6 Q8 {6 y+ o# y! w
  70.   /* USER CODE BEGIN TIM3_MspInit 1 */1 p. x  n$ f, k! F0 Z
  71. 9 Z/ o8 A; b' G- Z6 q3 I
  72.   /* USER CODE END TIM3_MspInit 1 */- |  {5 B6 u  a* c
  73.   }  X$ r. u+ e4 I( G' U8 D
  74. }( F- F! o1 R1 g3 Q" T
  75. //此函数会被 HAL_TIM_PWM_Init()函数调用
    $ D) C/ z) B; c  A: L0 ^
  76. void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)- Y6 }9 b2 Q2 r. |7 @/ V1 f  r
  77. {8 F1 |- A5 A5 H& I; k
  78.   GPIO_InitTypeDef GPIO_InitStruct;1 M8 t6 w! m5 p. D8 }% C
  79.   if(htim->Instance==TIM3)' G& x) o4 m, [$ _+ w" ~2 v3 r
  80.   {
    # Z3 O. c# k" Y9 K6 l/ @
  81.   /* USER CODE BEGIN TIM3_MspPostInit 0 */
    , V( G- f# }, i
  82.     __HAL_RCC_TIM3_CLK_ENABLE();& [. O6 k2 N* p$ a2 h
  83.   /* USER CODE END TIM3_MspPostInit 0 */
    0 y5 _2 {1 y! S7 {& w
  84.   & V+ s% Y$ E! O. J+ H7 ^) F
  85.     /**TIM3 GPIO Configuration   
    9 ~+ l8 m6 J5 b) [# U! r5 W( k2 ^
  86.     PB0     ------> TIM3_CH3
    + l$ h- U1 F% ~
  87.     */
    , E4 ?! B; F, A5 B
  88.     GPIO_InitStruct.Pin = PWM_LD1_Pin;
    " b. G' c! R- C. \! p' M  o
  89.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;//复用推挽输出
    , f, u5 f/ u, g+ p$ o
  90.     GPIO_InitStruct.Pull = GPIO_PULLUP;    //上拉
    3 b1 X8 q7 c) ?8 S
  91.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    " ~/ \; U+ {1 d4 F: P6 W
  92.     GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
    , B: S& H/ m  W, P& i
  93.     HAL_GPIO_Init(PWM_LD1_GPIO_Port, &GPIO_InitStruct);8 O' {" g* y- @& A: e  X  K

  94. 0 j2 `" s, u1 ?) o$ `, m
  95.   /* USER CODE BEGIN TIM3_MspPostInit 1 */
    - F, p' f0 {/ H% D7 h2 Y
  96. " X% R2 Z5 I! d0 J+ I2 h' r
  97.   /* USER CODE END TIM3_MspPostInit 1 */
      ^; M2 U9 ~+ h, y6 k" _6 f) p
  98.   }
    $ G* C& _5 |( @. a8 ]$ E
  99. }
      `. \0 w; e4 u' w* z( k+ b: i& {
  100. void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
    $ d2 n5 P9 V) i/ N1 C
  101. {: E/ K+ G2 m( L
  102. ( @+ {) A6 W7 M) \' N
  103.   GPIO_InitTypeDef GPIO_InitStruct;+ i) T- l+ [. a( _; w$ M! C$ T
  104.   if(timHandle->Instance==TIM3)  @: i7 [* h- B- T1 f" U  H
  105.   {% a( }( v. O2 \/ ~
  106.   /* USER CODE BEGIN TIM3_MspPostInit 0 */
    ; H! O1 \  j, M

  107. ) M( N& T. g+ e! V; @
  108.   /* USER CODE END TIM3_MspPostInit 0 */
    ( F7 _3 L% R6 L0 ^
  109.   * I! W. h* w% \: R: q7 W
  110.     /**TIM3 GPIO Configuration   
    2 x" U5 i3 ?$ m( {# ]  ]7 ^
  111.     PB0     ------> TIM3_CH3
    + Q6 R9 q$ Z! e4 P  K& Q( K
  112.     */
    $ N2 H. h- `2 V$ I6 m" x
  113.     GPIO_InitStruct.Pin = PWM_LD1_Pin;7 ^+ V! h$ N' O6 N6 N6 W
  114.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;//复用推挽输出
    7 D1 L/ |7 r6 i# m3 O  G9 ~
  115.     GPIO_InitStruct.Pull = GPIO_PULLUP;    //上拉
    . R6 G6 V4 p, \2 \# c: k5 q
  116.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    9 [, k9 q" ]2 D8 d! e% E
  117.     GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
    : N0 D4 Z& P* a0 M
  118.     HAL_GPIO_Init(PWM_LD1_GPIO_Port, &GPIO_InitStruct);
    + A9 W2 {) ~0 `' _

  119. * {5 d! F5 Q9 w. }
  120.   /* USER CODE BEGIN TIM3_MspPostInit 1 */
    5 o  e5 A1 u0 X! D* i4 X# N
  121. 4 R& i! u2 _. p5 e( O6 b4 z; ~
  122.   /* USER CODE END TIM3_MspPostInit 1 */
    6 g" Q8 f5 {1 T" l+ g1 ^
  123.   }& M0 M2 o% T0 q$ I/ q
  124.   D3 c3 Q' x( O
  125. }% g4 y5 \( N% f) ]5 N* [" W  d

  126. 9 N; ~; I3 w7 I. {
  127. void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
    . p( f6 p, R5 R% [7 w* s9 s( u; V2 \
  128. {7 q5 ~# U( T- r! C9 O6 z2 c
  129. 7 I% Y  M0 `1 z
  130.   if(tim_baseHandle->Instance==TIM3)
    ) E" r3 C/ P$ }3 ^1 Z* K
  131.   {
    : P8 E& d5 p2 ?2 K; t7 x
  132.   /* USER CODE BEGIN TIM3_MspDeInit 0 */
    7 ?& Q1 H  r- Z$ [  X4 m: ^0 s( m
  133. * ]7 V3 v; Z, l: P2 `
  134.   /* USER CODE END TIM3_MspDeInit 0 */. b) I; X. C* O$ c" ~# J6 |
  135.     /* Peripheral clock disable */
    - ^' z4 k1 |$ S5 _
  136.     __HAL_RCC_TIM3_CLK_DISABLE();
    0 N' W! m  K' Q
  137. 2 [, W" C# I$ v
  138.     /* TIM3 interrupt Deinit */
    9 o+ u% A8 {6 t$ s4 ]+ S9 l
  139.     HAL_NVIC_DisableIRQ(TIM3_IRQn);
    & G. I) a- [) H- p7 U
  140.   /* USER CODE BEGIN TIM3_MspDeInit 1 */" Z" O8 [3 _! K3 ?7 r. `

  141. + J' P- P+ h" Q- i) W9 {
  142.   /* USER CODE END TIM3_MspDeInit 1 */
    ; W( [& B7 k, L8 p8 u1 e
  143.   }2 z' F5 ?4 I, f: K$ d
  144. } 8 |. E6 z# `6 U1 `2 p
  145. * u8 `8 D6 N5 J/ m: [
  146. /* USER CODE BEGIN 1 */: B4 B! N3 V, k3 Q4 w2 j& x

  147. + h% ]- q. M2 N; \
  148. //设置 TIM3 通道 3 的占空比   compare:比较值  //compare/100 * ARR
    8 c2 W) L) x9 ~) d% z
  149. void TIM_SetTIM3Compare(uint32_t  compare)
    ' `/ g4 U# J; ]3 P
  150. {, \2 v6 `* @/ h4 M) P8 D4 T- y2 f
  151.   TIM3->CCR3=compare;
    * N& \1 u( N" V! W8 V+ N
  152. }9 a. ~: X8 B, D3 @
  153. //TIM3,Compare2/100 * ARR0 T3 ^- V! x0 ~0 c4 w
  154. void TIM3_CH3_SetCompare(TIM_TypeDef *TIMx,uint32_t compare)
    ! r. H( Y7 N6 E, Y1 a* f
  155. {
    / `7 L* _5 a& E# X
  156.   sConfigOC.Pulse=compare;% G2 W% X! k1 G. E+ O/ [
  157.   HAL_TIM_PWM_ConfigChannel(&HTIM3,&sConfigOC,TIM_CHANNEL_3);4 N( ?5 }, Z8 d9 r6 _
  158. }
    / G6 b6 ~. p9 @* Z
  159. : P: |( c! _- W$ Z' w9 X
  160. //呼吸灯+ \8 B' \7 m# _* k" ~
  161. uint8_t  LD1_dir = 0;
    ( a7 T: S- x/ ^7 c
  162. uint16_t LD1_PWM_Value = 0;" ?# i7 W% i3 G2 S: D9 B2 u
  163. void TIM3_CH3PWM_BreatheLED(void)
    % G3 x. j+ z6 k/ u. t  r3 d3 R
  164. {
    0 t$ w' n* z8 m+ `6 r6 Y' ]
  165.   if(LD1_dir == 0)
    2 g" ^2 }, P( P$ x9 X
  166.   {
    0 ~8 O6 i' u/ s/ I" B& K
  167.     LD1_PWM_Value ++;
    * Y% K: t/ V( \
  168.     if(LD1_PWM_Value >= 300)% {) ^$ d; {3 @2 t
  169.     {
    3 o$ a4 g& T- i6 S+ P- j
  170.       LD1_dir = 1;$ q% v& B1 G6 @
  171.     }' [; ?* D# ~  V
  172.   }
    / N* O6 p: e" c8 p) }% j
  173.   else7 X+ W8 F6 b, _9 `8 D% |
  174.   {( Q9 @* t. o, J) N+ R6 T
  175.     LD1_PWM_Value --;! c' a  `- F9 p8 o- p5 `- m
  176.     if(LD1_PWM_Value <= 10)
    4 ?9 T* K( I1 [1 {1 X
  177.     {6 Z1 S9 Z5 S2 g( y
  178.       LD1_dir = 0;, R7 i% S0 Z8 U7 I/ K
  179.     }: N2 ?) {' ^! ?' y! D; I" }
  180.   }6 {0 q& \* H3 g3 u
  181.   TIM_SetTIM3Compare(LD1_PWM_Value);
    & a8 k' Q) i" c1 ]5 B6 y7 @
  182. }
复制代码
放在滴答时钟里面执行的:
! ]' k+ `% A! w, b+ d- N! ]+ @
  1. uint16_t Breathe_Count;
    ! k, K/ @6 m! D! M! T* P' N
  2. void SysTick_Handler(void)4 Q8 S9 B& s1 I. A- ^2 k
  3. {5 }# |: g5 [& J
  4.   /* USER CODE BEGIN SysTick_IRQn 0 */
    9 j; p: m: B% b" u

  5. * N8 Q. i4 O1 t4 Q/ I7 Y
  6.   /* USER CODE END SysTick_IRQn 0 */
    3 y0 W1 `  f: V, C
  7.   HAL_IncTick();
    1 _$ l$ ]4 d6 g- G& V
  8.   HAL_SYSTICK_IRQHandler();3 f" J8 n" X7 A; K
  9.   /* USER CODE BEGIN SysTick_IRQn 1 */0 ~" [" m3 J8 D4 H: Y
  10.   TempVref_count++;3 N: F, D1 z/ J2 ?5 Y, J
  11.   Breathe_Count++;
    ! L1 H  i9 j4 {: ]
  12.   if(Breathe_Count >= BREATHE_TIMER)//10ms
    7 M& Y+ o( v5 D
  13.   {
    ! V9 {1 @7 B) T6 c1 A5 O
  14.     TIM3_CH3PWM_BreatheLED();//呼吸灯
    & D# z5 t/ q( O. {  _
  15.     Breathe_Count = 0;& c- c$ W7 m0 ?! o" R
  16.   }
    * `4 p5 C7 P2 B8 v2 j3 G. M0 a6 D
  17.   /* USER CODE END SysTick_IRQn 1 */& ]0 e$ F8 V' I
  18. }
复制代码
" T7 ^8 S% o6 o+ m

% [: U# }0 F- {. ~7 Y/ l" [; d6 E; L9 f5 H, ^$ a0 ?# T3 m5 y
4 [% v$ N0 s6 u% h5 Y7 x& z
效果:
$ m/ w0 v  x4 [1 a 2017_07_27_20_50_49.gif
& y, F$ o. X5 ~, n7 i. L
! w, N) f8 M6 z$ @0 _' D& F+ p8 Z5 m5 I- W6 o' I$ i5 ~% a

; O; t( Q  U0 z3 A4 d% ~工程代码: NUCLEO-F767ZI.rar (5.49 MB, 下载次数: 79)

评分

参与人数 1 ST金币 +10 收起 理由
zero99 + 10

查看全部评分

赞 收藏 6 评论12 发布时间:2017-7-27 21:01

举报

12个回答
wolfgang 回答时间:2017-7-27 23:39:12
很好,支持~~~
五哥1 回答时间:2017-7-29 17:47:04
五哥1 回答时间:2017-7-31 15:38:49
楼主新增部分能用其他颜色标出吗,这个看了半天,
队长shiwo 回答时间:2017-7-31 17:51:10
五哥1 发表于 2017-7-31 15:38
0 T( v# r; h; i* ?3 P  s5 B6 l楼主新增部分能用其他颜色标出吗,这个看了半天,
4 c; f* M2 N- T
上传了工程文件,你可以下载来看看,用论坛的代码编辑确实有点参差不齐的
五哥1 回答时间:2017-8-2 01:41:21
谢谢楼主分享
samhong 回答时间:2017-8-2 09:00:13
早上好!谢谢楼主分享!
andey 回答时间:2017-8-2 09:12:05
提示: 作者被禁止或删除 内容自动屏蔽
合肥·宝 回答时间:2018-5-8 20:38:42
厉害了我的哥
lilyliu123 回答时间:2019-5-17 00:23:03
为什么我用keil5编译后有很多错误提示
z123963 回答时间:2019-8-2 19:13:37
很好,支持
傻猪卜爱哭啊 回答时间:2019-8-3 13:35:53
支持,谢谢分享
Ian-392967 回答时间:2020-1-5 13:11:26

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版