请选择 进入手机版 | 继续访问电脑版

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

STM32基础设计---中断串口通信

[复制链接]
STMCU小助手 发布时间:2023-1-5 21:02
首先,总结全文,设计步骤主要如下:" r+ A# U% S4 s" b& J& v. Y
1,初始化GPIO
' S6 K0 r4 y: [3 S. O# s* n3 K2,初始化USART1
- i2 o( z, g2 b! z$ |8 x. N9 @3,初始化NVIC(嵌套向量中断控制器)
8 Q7 ^; n' D; B6 V; M4,编写中断服务函数6 g" C9 r' j6 y' ^. ?5 q2 m
5,编写主函数( h% d6 j5 f5 g% o' v
# D0 i% f+ p8 P
详细步骤如下:
% }7 r/ i7 I" Q" @& n. ?+ x

$ Z) e4 z+ V/ W/ s1,初始化GPIO3 a$ \# W7 Y. I3 E+ i% Y1 E' o  z
  1. void IO_Init(); |7 j+ X9 g% g1 E8 n$ u5 z
  2. {$ e, \! d( F! T/ ~3 u: [3 R$ r
  3.         GPIO_InitTypeDef Uart_A;, B, U0 _' t+ @  W6 u
  4.         GPIO_InitTypeDef led;
    3 ~0 F* X# Y/ N8 Z$ R' Z
  5.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);9 D# F0 M, A4 j
  6.        
    / D/ J: ~; D2 G; I8 [3 c
  7.         GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable|GPIO_Remap_SWJ_JTAGDisable,ENABLE);
    ( j  h5 g) D9 X" J
  8.        
    0 o! ~. y1 e+ M, Y' S
  9.         led.GPIO_Pin = GPIO_Pin_13;//博主开发板上的LED灯接的GPIOC的13引脚7 I) E  I& ?! y; s
  10.         led.GPIO_Mode = GPIO_Mode_Out_PP;
    8 r& i( ]* T2 B5 w9 C
  11.         led.GPIO_Speed = GPIO_Speed_50MHz;
    / h+ D9 B! P& v* n1 O
  12.         GPIO_Init(GPIOC,&led);! E, D7 M- `5 ]/ L
  13.        
    3 p6 p$ {3 r% s$ t
  14.         Uart_A.GPIO_Pin = GPIO_Pin_9;) l+ z7 [' ^/ b( M  S  }8 m3 i
  15.         Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
    ' e+ K: c; r5 e! O
  16.         Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;. p4 X9 r9 H* K6 M( x2 F4 s4 W
  17.         GPIO_Init(GPIOA,&Uart_A);$ c* ^9 O: |7 R6 D  D8 f3 x+ R, Q+ b% n
  18.        
    ! a$ H/ E- L, y1 x, @$ d% @& Y. }
  19.         Uart_A.GPIO_Pin = GPIO_Pin_10;
    9 N/ p9 _) K! a1 D; |. q8 R/ ?2 b
  20.         Uart_A.GPIO_Speed = GPIO_Speed_50MHz;3 k9 c* ^0 h5 C! P
  21.         Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; + h& S/ f& Q6 t$ Q
  22.         GPIO_Init(GPIOA,&Uart_A);: i1 v9 G+ D* Z) L7 t. E+ j
  23.        
    ) z: H9 K# ^( y5 L8 T( W1 \* d6 \# N
  24. }
复制代码
% {5 A3 a8 Q- v) q! U
以上代码不在详细介绍,前参看STM32基础设计(1)---点亮LED灯、SEM32基础设计(2)---查询串口通信
' i, Y# L9 E9 }  L+ {( \) M6 E' s: H0 ?- G7 o
7 R) t$ l+ l9 f0 u; d6 w
2,初始化USART1
# D6 a. c4 H& \( Y9 }9 [
  1. void Usart1_Init(): Y# X- [2 X6 F; O
  2. {
    " c+ c. v. u& C& T" t6 `/ P
  3.         USART_InitTypeDef Uart;
    6 @9 `- S( [  h) |9 Z+ ]+ x  L* G
  4.        
    ; o5 @+ c% l+ l3 X( d
  5.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    ( |! O* ]2 D! ^3 ~# g
  6.         Uart.USART_BaudRate = 115200;
    & O3 ]7 u& |9 r
  7.         Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    - G" N! e( [4 D# V' F
  8.         Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    ; J7 Q1 J4 i' u
  9.         Uart.USART_Parity = USART_Parity_No;( H+ R9 o0 a# h! i
  10.         Uart.USART_StopBits = USART_StopBits_1;
    8 K8 _' b' c. O8 m' ~, P
  11.         Uart.USART_WordLength = USART_WordLength_8b;
    , c7 D4 n0 g7 \$ P) p
  12.         USART_Init(USART1,&Uart);0 {! |6 W7 @. w! k
  13.        
    - X  L1 m3 @4 ]4 @8 l, y3 I
  14.         USART_Cmd(USART1,ENABLE);
    ( r9 k+ R/ s+ C+ w7 ^5 B: J5 Z
  15.         USART_ClearFlag(USART1,USART_FLAG_TC);
    2 b" x! h  T4 A- e8 x! k
  16. }
复制代码
7 _2 J" D0 Z7 `

0 l4 M* F; S9 p* p+ J$ |% F以上代码不在详细介绍,具体请参看STM32基础设计(2)---查询串口通信8 d) U) u& w# N1 Y' e& M
/ @  S0 s+ U( |
! ^5 D2 b6 Q  y1 f8 i
3,初始化NVIC
- T, S( i  ^! ?/ k6 {' M& k! @1 _首先,让我们来了解库函数中的NVIC结构体:
9 ?+ L  H: p5 T2 k7 Y& ^
  1. typedef struct
    7 e3 ?; s2 a# J- f! _6 e" d
  2. {//指明那个中断通道
      I" H; S* x& F% |8 I7 g7 e
  3.   uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.; o) ]! G% N; r
  4.                                                    This parameter can be a value of @ref IRQn_Type ( _% `6 A% }2 b  \
  5.                                                    (For the complete STM32 Devices IRQ Channels list, please
      z8 }" b7 C! i6 E' f
  6.                                                     refer to stm32f10x.h file) */
    % r; v  [. \3 ~' v6 q( K8 }% E) c) r8 R
  7. //抢占优先级9 _$ z: a, j' @, n
  8.   uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channel, i9 U# P0 l0 n8 L' v2 ], N
  9.                                                    specified in NVIC_IRQChannel. This parameter can be a value
    - _; V. J+ Z9 q$ L+ k
  10.                                                    between 0 and 15 as described in the table @ref NVIC_Priority_Table */3 @* L6 p1 W  m1 e# v( t
  11. //子优先级
    , @4 e) N$ f& Z  Z3 t! O% c
  12.   uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specified  x! y( W! D: {" ]/ w( [, K6 V
  13.                                                    in NVIC_IRQChannel. This parameter can be a value
    & n; g3 D' |6 Z9 e( d4 T2 V
  14.                                                    between 0 and 15 as described in the table @ref NVIC_Priority_Table */: _1 C' z6 t& P: M2 ^
  15. //中断通道使能
    ; _- k% M1 Q: P% n, A8 A2 X8 ?
  16.   FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel& t1 R) B" V, _. e2 L( `
  17.                                                    will be enabled or disabled. ) A- E4 C, W: E1 V  g
  18.                                                    This parameter can be set either to ENABLE or DISABLE */   
    % z9 O2 ~1 i( g1 B4 g3 B
  19. } NVIC_InitTypeDef;
复制代码
0 {) M6 Z( A0 [- n. G
了解了这个结构体后,就可以在初始化函数中定义这个变量了
+ W2 Q! t$ w% e$ }" C1 I# ]* O
) |" ~" a1 S' |7 W) k* w' @
  1. NVIC_InitTypeDef nvic;
复制代码
9 t: t( d, {( o5 Z# o
另外在NVIC初始化中还设置优先级分组(哪怕只有一个中断也要分组,这是规定)。具体使用这个库函数:
% q; V, S! s9 o& x4 K6 t# j" @  ]
* a5 _7 i' Y) Z) Z
  1. void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)) L; M, m- R& ]# s  t, |
  2. {
      U1 l3 w3 w# R0 ]; H1 e& }
  3.   /* Check the parameters */
    ( Z0 r7 B2 E8 x
  4.   assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
    % [$ d3 L: e3 {* |0 L
  5.   : Z4 w2 W  z/ f9 p8 n+ U
  6.   /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value *// q3 ?( x, _1 M/ V  h& {) Z
  7.   SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
    7 Y7 N, n3 Q4 T- g' y9 N
  8. }
复制代码

0 h/ {/ D; P/ r- k) l; l. u9 [接下来,设置结构体中变量的值:
" z% }# Q& X, ~1 L: @6 n+ s
  1. nvic.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
    9 u: K3 M& _) Z3 r5 O
  2. nvic.NVIC_IRQChannelSubPriority = 0;//子优先级
    * r3 r* l8 E0 R+ ?
  3. nvic.NVIC_IRQChannel = USART1_IRQn;//中断通道
    3 q+ c9 o% g" ^( o9 x
  4. nvic.NVIC_IRQChannelCmd = ENABLE;//通道使能1 k  Q# K& _( B0 }& P. g) F0 Q
  5. NVIC_Init(&nvic);//NVIC寄存器初始化
复制代码

$ R  Q) o  R/ g7 ]# ?4,编写中断服务函数
2 t3 |& x! N: I. C, R' `; N. S6 h先贴代码,在解释
; E2 u* Y$ Q* {0 I& A# i/ v: J
  1. void USART1_IRQHandler(void)//注意,这个函数名必须这样写,否则进不了USART1中断。详见库函数中的  IRQn_Type 结构体
    . h# x4 W$ W0 a/ G& n/ z7 K" ?
  2. {
    8 g7 F# F8 b' b' Z
  3.         char temp= '0';0 ^+ G: E6 h" Y- n3 K7 ~3 ?
  4.         if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)//判断是否接收到数据- q& r7 x# Z: o. Q
  5.         {# A0 f; v( n2 Z$ M
  6.                 temp = USART1->DR;//如果接收到数据,就将其读出,这样才可将RXNE寄存器清除" Y; ]7 _  `/ o% S8 P
  7.                 if(temp == 'G')//如果接收到G  则关灯
    9 U3 D! P( q$ E& g
  8.                 {
    - S& a+ r* N) E2 D9 j8 i6 }# d+ H; `6 j: H
  9.                         GPIOC->BRR = GPIO_Pin_13;
    4 Q6 ?# w0 `6 \- q. g
  10.                 }else if(temp == 'K')//开灯
    % c! D  }1 |1 f, w8 t1 P8 p
  11.                 {9 P: X; {/ |  o1 ]; ^/ N; n
  12.                         GPIOC->BSRR = GPIO_Pin_13;
    7 ?# Y% z" Q3 j' X4 _* r# G
  13.                 }) _( I3 H. ]6 t' C6 ~' v% J' i
  14.         }) L' e5 e$ f1 h4 n) ]
  15.                 if(USART_GetFlagStatus(USART1,USART_FLAG_TXE) && temp != '0')//如果发送寄存器为空,即可以发送数据) E' u' I9 y$ v3 t. t; ?3 e
  16.                 {0 X- E- k& G- k( a- g
  17.                         USART1->DR = temp;将接收到的数据再发送回去
    9 r' {7 O2 d3 \) C7 O$ M* ^) G
  18.                         while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));等待数据发送完毕
    # v+ w- n1 G3 k' h, h, F
  19.                 }& V9 m+ n1 ]( A4 k
  20. }
复制代码

1 B  k2 ?; N7 n% ~5,编写主函数
. \% j0 W. Z0 n( S- L/ N
老规矩,先贴代码再解释:% @$ Z  J0 c! V$ P- C2 o* s
  1. int main()- T0 A3 d6 g: [+ ]4 }
  2. {
    2 W( k8 c2 j. ]
  3.         IO_Init();: c' t  x7 b8 s  R6 @4 _
  4.         Usart1_Init();8 G' h" p/ S' Z& |" v
  5.         Nvic_Init();
      j8 G) R8 D0 I
  6.         USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//这里是打开串口的接收中断,以便在USART1收到数据时,进入中断函数。这里特别提一下,现在不用打开发送中断,只有在准备发送数据时才应打开,否则会直接进入中断函数。
    - p; M, j' ^9 e2 q- `3 V- ]
  7.         GPIOC->BSRR = GPIO_Pin_13;
    1 x- E) S' z! w, r8 }  K2 m6 N+ i
  8.         while(1){}( E" p9 N: n. [- f5 z3 |4 u
  9. }
复制代码

3 A; _9 N7 @, Y& e6 K( K额。。。突然发现没什么好解释的。' p( ^: o( p5 s/ \3 c. e+ Q$ N3 n3 N

$ g. q. {4 [: h' ^, K! r% f( r" T中断串口通信介绍到此完毕。
4 d5 E6 L" k5 b4 b- u, u# _+ c; Z( C
, c' D) [: Q/ d' K本文完整代码如下:0 P1 V4 r- @0 z" v3 B
  1. #include<stm32f10x.h>
    , T) F0 @, r) d8 w
  2. #define uint unsigned int
    ; V+ t$ m/ Z& n* b0 M* |, \
  3. #define uchar unsigned char
    9 g# s- m+ u8 x4 U
  4. void delay(uint n)' K3 `% x8 m5 A/ [1 [5 w0 d
  5. {% |/ e7 q1 H: G% t2 g9 E8 S) ~
  6.         int i,j;
    ! i) g' |. k' r& [4 L2 W& E. R
  7.         for(i=0;i<n;i++)
    4 I  R7 F/ a2 F5 m0 f  o* i8 n
  8.         for(j=0;j<8500;j++);
    8 }9 `, d. I- x1 u$ W2 d
  9. }" O" g/ u3 n: b8 {) @$ E' X2 l
  10. ; n) m' C9 _& t
  11. void IO_Init()
    ) S& `% ]% i9 a1 V  [4 G
  12. {; u: D) H$ N3 _7 d% [8 P
  13.         GPIO_InitTypeDef Uart_A;% [% v! v+ T$ X8 ^% U5 i. |2 k3 n
  14.         GPIO_InitTypeDef led;/ M; c1 `8 V& c+ D% L. `0 M$ M
  15.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);
    8 h  g2 p/ x4 {) r0 V( w) D
  16.        
    % B& D7 t8 V& R/ ?; k6 T" ?
  17.         GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable|GPIO_Remap_SWJ_JTAGDisable,ENABLE);% Z: n% Z7 R0 F* {# {* n. A7 Y: U
  18.         . U* M% w& l3 w( l- y+ g/ c, o0 R! P' u
  19.         led.GPIO_Pin = GPIO_Pin_13;: F7 ^0 u0 ]+ l3 X$ a5 G
  20.         led.GPIO_Mode = GPIO_Mode_Out_PP;
    " e! [8 g' P" Q1 q5 @
  21.         led.GPIO_Speed = GPIO_Speed_50MHz;
    7 s" V& W- J- m1 g5 Y8 K
  22.         GPIO_Init(GPIOC,&led);
    : _/ m  C" e) |
  23.         - q; j/ x/ z6 `5 k
  24.         Uart_A.GPIO_Pin = GPIO_Pin_9;
      b' X0 n5 \: ^" K' @" t
  25.         Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
    7 ]0 I% C# G" Y- C5 |
  26.         Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;
    & Q( P! B8 p( v' g' v
  27.         GPIO_Init(GPIOA,&Uart_A);
    + i7 P6 G& }: C1 t7 V
  28.           k6 e  `" U6 h- X
  29.         Uart_A.GPIO_Pin = GPIO_Pin_10;
    8 u  ]0 c7 o9 z: i( _4 ^0 r5 a
  30.         Uart_A.GPIO_Speed = GPIO_Speed_50MHz;
    3 q* ?- ]4 Q% x# S, Y
  31.         Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; //page 1107 j/ f& s& A) r# ?# N
  32.         GPIO_Init(GPIOA,&Uart_A);+ j2 p9 G& }2 b- s& D4 @
  33.         7 c' k8 j! L4 Q* Q2 I+ f& o# w5 W
  34. }
    9 S  g( t# V! T0 ^8 G1 W
  35. void Usart1_Init()  w% V$ e; m& L! \- j' \4 r/ S; j
  36. {
    " ]! u* E4 C) n  T4 P4 x
  37.         USART_InitTypeDef Uart;6 G0 e4 e* \* ~: v9 K7 z
  38.         ! O8 a7 p9 M8 t0 ^, t
  39.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);& `. Y1 {1 G( `1 v0 y' a, A" L
  40.         Uart.USART_BaudRate = 115200;
    8 _- V. c& T4 g+ E9 j
  41.         Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;$ P" h( T6 Q) r* H
  42.         Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    6 q! J1 E- A3 {- ~
  43.         Uart.USART_Parity = USART_Parity_No;+ ]3 o; q* ?' a9 w% ?
  44.         Uart.USART_StopBits = USART_StopBits_1;
    ) R0 |4 d* f. L" J$ T
  45.         Uart.USART_WordLength = USART_WordLength_8b;
    0 n. T! f* ^) ~: K$ e* Z( l8 u/ U
  46.         USART_Init(USART1,&Uart);( h2 C' \8 j5 S; a
  47.         * d1 L! P' H: G  E. A4 T, b
  48.         USART_Cmd(USART1,ENABLE);# G* ^$ F8 O# Y+ S. Y: C9 k- s
  49.         USART_ClearFlag(USART1,USART_FLAG_TC); //page 540
    . F9 t! }2 o6 |. }! v$ _
  50. }/ R9 y# f( w% h, S9 N: N- N* P; ~
  51. void Nvic_Init()( f# A7 N2 Z' e5 c( o. d
  52. {$ i6 L' g. ^) A4 l& H& ]: w8 A1 l* Q
  53.         NVIC_InitTypeDef nvic;
    3 s) j5 A0 P( B
  54.        
    - i- S% b/ K2 F+ o6 l
  55.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    6 Z* `' f# ]; z3 J
  56.        
    # _4 E: R; M  [. J. p1 ^% x
  57.         nvic.NVIC_IRQChannelPreemptionPriority = 1;, C* e* V2 K  |$ q" ^
  58.         nvic.NVIC_IRQChannelSubPriority = 0;5 {7 J  Y) u+ l# x" B- `& U9 U
  59.         nvic.NVIC_IRQChannel = USART1_IRQn;
    , l/ M( C/ ~3 _. J4 h% T
  60.         nvic.NVIC_IRQChannelCmd = ENABLE;, h  O3 w8 J: S) m0 ]0 w' t0 z; K
  61.         NVIC_Init(&nvic);
    : v' l" ]9 B+ G; R1 A) S- r
  62. }
    9 M5 s5 I9 ^* I4 W* N$ u

  63. 1 z6 r0 Q" C4 b! `
  64. int main()7 h, {4 g' A) ?
  65. {' n% y; g% V6 h6 @( `/ `
  66.         IO_Init();9 n8 j5 Q' E5 s6 {
  67.         Usart1_Init();
    ( t" i3 x% Q& [" r9 ~/ [5 t" P
  68.         Nvic_Init();
    / j1 {% D+ E3 l$ M4 U% E5 _# ]
  69.         USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);1 s+ z8 t" _2 ]- C
  70.         GPIOC->BSRR = GPIO_Pin_13;
    / ^5 o/ ], w! ^4 ~% M
  71.         while(1){}
    / \7 a5 [4 f/ }6 N  J6 u
  72. }# P% m5 A* h( s' W" ]7 S8 G7 @
  73. 6 \; J: n2 c2 P+ }! D
  74. void USART1_IRQHandler(void)
    # v  J7 O: I  ^$ E
  75. {2 s# a7 M( y* ~' X
  76.         char temp= '0';
    1 |% S' a2 {' ]% {9 `' Q4 o# t
  77.         if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)
      s% m0 Q) U2 G, W* e. m
  78.         {
    3 T/ Z! @$ x. Z0 n0 K' v$ `: l
  79.                 temp = USART1->DR;3 r' t: Q& f& j! Y
  80.                 if(temp == 'G')
    ' z5 q! \  H* O5 h& s
  81.                 {
    . T9 s7 O9 h! J
  82.                         GPIOC->BRR = GPIO_Pin_13;
    / L1 P% T8 v$ X* x' q
  83.                 }else if(temp == 'K')2 i$ p8 F) j6 |- F
  84.                 {' S( `9 f/ X! k9 q+ M
  85.                         GPIOC->BSRR = GPIO_Pin_13;
    6 X: M- ?& s, j6 ~6 W7 @3 O
  86.                 }; U' T, X5 ^  J7 r- y, O
  87.         }) l+ b- U, z1 V" C# V# U' \
  88.                 if(USART_GetFlagStatus(USART1,USART_FLAG_TXE) && temp != '0')
      y( o  Z2 u  L) n( w
  89.                 {
    * t1 }1 q6 k5 c5 e" G" c$ ~
  90.                         USART1->DR = temp;0 ]$ P( }9 y% ?/ E# L) X
  91.                         while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));
    $ ]' t* o7 @& b8 S% ?3 j9 w% k2 u
  92.                 }
    2 k( Y7 e4 G$ W& n. W! l- n
  93. }
复制代码

9 v  |" ^' S# V4 S3 m5 T- q3 q8 V* D4 w2 M
————————————————
. E+ H3 u$ G  s9 a! j版权声明:家安( Y8 W5 Z* O. g- l# I0 W* M3 P
1 m( i( W9 k: z# @
3 n& ], k" c- V5 Q7 [$ I8 @! x
收藏 评论0 发布时间:2023-1-5 21:02

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版