找回密码
 注册
关于网站域名变更的通知
查看: 576|回复: 2
打印 上一主题 下一主题

STM32之学习笔记--串口通信

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-9-9 15:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
  在基础实验成功的基础上,对串口的调试方法进行实践。硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中。
3 q5 E+ }5 f# `; [  b) 初始化函数定义:
' i% {& f4 W6 J4 W  void USART_Configuration(void); //定义串口初始化函数% X* C( b, N+ v/ w
  c) 初始化函数调用:
4 Q2 r7 V8 N2 _! n- r; e  void UART_Configuration(void); //串口初始化函数调用/ {) V$ L- Z0 E9 |) P2 y; W
  初始化代码:
2 _' y4 l6 }+ a8 l8 I
$ t3 Y  T* Q9 f- q; i; I
  1. void USART_Configuration(void) //串口初始化函数
    ' ^/ K8 I  A, \4 x! a3 P

  2. 8 o; v9 j( [' X/ Z* E9 a% D. ~5 h
  3.   {
    * i8 Q, ^3 W9 F$ s9 u
  4. * n0 j5 ^/ ]+ h( K& @1 b& r
  5.   //串口参数初始化' e( ]; q2 P$ }  H+ t

  6. " q6 S8 k) y  e
  7.   USART_InitTypeDef USART_InitStructure; //串口设置恢复默认参数3 i% v6 s) ], Y) j) ?+ e

  8. ( i  p8 O8 `# O. j4 t
  9.   //初始化参数设置
    6 b- J- W, n3 m) i! J

  10. 2 q% Q; D& q) e  B3 h& @" H
  11.   USART_InitStructure.USART_BaudRate = 9600; //波特率9600
    0 W* r( c! v8 M% I
  12. 5 m7 p4 F! B( n8 \3 \8 M
  13.   USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长8位  ~9 b% z8 F' k# x$ i) u
  14. . A' |, g; j5 X- J6 m6 `
  15.   USART_InitStructure.USART_StopBits = USART_StopBits_1; //1位停止字节# Q% V; b2 N& @* T6 ^
  16. ; S" P- w: S. N/ h# v! A
  17.   USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验
    3 w% A. H: l* f: i# r9 O1 o

  18. 9 d& H  j. C. ?  Y" `/ r5 X+ W
  19.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无流控制0 o% x' @+ N% [- K

  20.   n0 M; w/ V. r- o& d1 I* Q9 E9 w3 ^
  21.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//打开Rx接收和Tx发送功能/ x5 ^0 m9 u$ M2 o' b4 T" I0 w# b  q
  22. : `' S0 Q- Z, ~2 X9 Z: U& k
  23.   USART_Init(USART1, &USART_InitStructure); //初始化8 [( S7 s! n# A: T/ D- M7 G

  24. ' \4 [7 p  e! k$ _  m( E
  25.   USART_Cmd(USART1, ENABLE); //启动串口
      x+ m4 b  t7 x" Q

  26. * h9 p/ u  k+ N
  27.   }
复制代码

1 r) N! [7 \$ O/ A+ [  RCC中打开相应串口4 H1 s% v( U) z+ ]9 F% V
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);& O9 D+ w: m! Y: m* B& t6 y/ O1 V. B1 B
  GPIO里面设定相应串口管脚模式) d$ c( b6 ~+ L0 y. o# P6 H) p2 R

/ k/ {- z+ U  h6 A% {/ [  H
  1.  //串口1的管脚初始化0 D+ B! J& r# z9 _9 |8 E, L

  2. " G" }7 Z0 l5 o
  3.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //管脚9
    4 N$ Q: T+ ]3 V% z6 G
  4. 1 E, n6 V; \7 P/ [3 p+ H) Q
  5.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出; R" j  r0 j; c, j; P
  6. 9 V4 r" F0 q+ W# }8 X
  7.   GPIO_Init(GPIOA, &GPIO_InitStructure); //TX初始化
    ) W( ]9 C- A* l

  8. : `+ d- @! K$ ~; Q
  9.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //管脚10% x, I1 j' ?% `) k( k1 _& M
  10. 6 {; G9 G" g, C, r
  11.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入. G! M7 e. l! }% o
  12. . W( k! a$ w" ?7 J1 h* {
  13.   GPIO_Init(GPIOA, &GPIO_InitStructure); //RX初始化
复制代码
9 r- ~; t( d9 U& n  g( P
  d) 简单应用:
8 t  v6 a& t0 P2 A; E& D& [: M2 ]  发送一位字符" t( W1 a+ S! V; t. a
  USART_SendData(USART1, 数据); //发送一位数据
3 r+ O1 ]! k' m, t! f/ F9 F6 d6 U2 z+ o
  1.  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //等待发送完毕
复制代码

# v9 x# t% Z; ?  接收一位字符
/ g0 x8 u# u* J/ E. J2 H& R& h9 T. ^6 \& L, v4 F- v
  1.  while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){} //等待接收完毕
复制代码
5 G& [; O) w+ a5 w
  变量= (USART_ReceiveData(USART1)); //接受一个字节' q$ i# E6 u% y9 Z" c4 m, ~
  发送一个字符串. [$ Q  t. Q" m& R0 ]0 J
  先定义字符串:char rx_data[250];
: U7 b7 m! a" ]3 @  然后在需要发送的地方添加如下代码! Q8 t' K9 C2 T6 B/ i

* I3 m% j8 F7 N$ R
  1.  int i; //定义循环变量* T5 ^" @; w! k- m7 j% C
  2. ) N3 e* g1 N( x6 i5 u
  3.   while(rx_data!='\0') //循环逐字输出,到结束字'\0'
    3 r, [: r# ], e4 D! \

  4. - D" h* S& U; v5 @, J7 u. R
  5.   {USART_SendData(USART1, rx_data); //发送字符
    7 j, J/ d$ U9 c$ J. Z
  6. % s$ R8 r9 t3 W9 y, q
  7.   while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //等待字符发送完毕
    9 k- l; h- h/ p" L! m3 W8 P# z

  8. 8 F0 A2 J# S% _' n
  9.   i++;}
复制代码
. o; u# Q7 T) Y. U" n! T
  e) USART注意事项:
0 u0 i$ C/ q3 ?0 J! H9 Y, h- E, ]  发动和接受都需要配合标志等待。
& f/ Y) G8 ^% l  只能对一个字节操作,对字符串等大量数据操作需要写函数
( W7 d0 y" N) J" {  使用串口所需设置:RCC初始化里面打开RCC_APB2PeriphClockCmd
) u$ |! d7 [/ Q2 e  (RCC_APB2Periph_USARTx);GPIO里面管脚设定:串口RX(50Hz,IN_FLOATING);串口TX(50Hz,AF_PP);
  z8 ^# Y3 E8 z  f) printf函数重定义(不必理解,调试通过以备后用)
1 {% L6 w1 x4 J  w  (1) 需要c标准函数:) |/ Y4 g, m9 Z$ `* i
- q* ?/ g$ T5 O
  1.  #include "stdio.h"
复制代码
: l% A/ v5 ^4 c" c# v9 S# ^# g
  (2) 粘贴函数定义代码! O  ]0 }, i& F$ o7 ~8 p
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) //定义为putchar应用. R. t6 I- _- P: I$ D
  (3) RCC中打开相应串口
8 n- ^9 T) K. Z) n  T  (4) GPIO里面设定相应串口管脚模式
  X+ O: z" e6 U3 E6 \/ w  (6) 增加为putchar函数。
% ^0 S9 t  h, z  int putchar(int c) //putchar函数
1 d) b- B1 l9 e+ j9 F

  1. $ ^) l4 y# l6 s
  2. <p>  {</p>
    ' h/ p2 \" g) V+ q: _5 ?! E) y
  3. <p>  if (c == '\n'){putchar('\r');} //将printf的\n变成\r</p>' U8 ?) l  X( N6 Z: I. G
  4. <p>  USART_SendData(USART1, c); //发送字符</p># z8 @9 w: t) G! a# \0 X
  5. <p>  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //等待发送结束</p>! x& U/ @% i/ K- s3 L. j
  6. <p>  return c; //返回值</p>
    8 T$ M: B! j' U& a2 W
  7. <p>  }</p>
复制代码
( P' a0 X* ~, W3 z6 D/ y
  (8) 通过,试验成功。printf使用变量输出:%c字符,%d整数,%f浮点数,%s字符串,/n或/r为换行。注意:只能用于main.c中。
, e  L2 f6 ?5 U5 O. e  3、 NVIC串口中断的应用' W* J+ o3 ?: j' T5 a
  a) 目的:利用前面调通的硬件基础,和几个函数的代码,进行串口的中断输入练习。因为在实际应用中,不使用中断进行的输入是效率非常低的,这种用法很少见,大部分串口的输入都离不开中断。
8 h( _& x& G! o  b) 初始化函数定义及函数调用:不用添加和调用初始化函数,在指定调试地址的时候已经调用过,在那个NVIC_Configuration里面添加相应开中断代码就行了。8 y6 ?8 l% d* P$ M. `
  c) 过程:
# r9 \0 k# s, g  i. 在串口初始化中USART_Cmd之前加入中断设置:
$ i+ f: D2 B% @* q& q1 U( W  O
  1.  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//TXE发送中断,TC传输完成中断,RXNE接收中断,PE奇偶错误中断,可以是多个。2 R) S: E4 n1 L/ j+ @" l

  2. , C& w& _+ k  B" M
  3.   ii. RCC、GPIO里面打开串口相应的基本时钟、管脚设置3 X& a4 y* L; B( o1 f& L8 Q4 g

  4. + H8 z7 a  g4 C" I5 I
  5.   iii. NVIC里面加入串口中断打开代码:
    5 s' d$ l( n' V' z) B2 e2 Q

  6. : \8 ~% M; {! r0 F# ]( X# p
  7.   NVIC_InitTypeDef NVIC_InitStructure;//中断默认参数1 S2 k& x+ E% X" N' j
  8. ) ?) X0 s" R& k8 |  p8 L
  9.   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;//通道设置为串口1中断$ m5 }9 e% n) P

  10. & @3 `( z9 X8 L/ x
  11.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //中断占先等级0, Z/ X- h- a& f8 K) k5 x4 ^6 V

  12. % g% ]% {$ u1 I; O/ b
  13.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断响应优先级08 o7 U4 v- B: y. ^% z

  14. / v) Z- [' ~; p# @4 r9 w
  15.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
    / j4 ^$ @; M7 p" }9 g3 d" T8 J4 p

  16. , ^2 `* b4 p% R/ {- |& D8 R" j
  17.   NVIC_Init(&NVIC_InitStructure); //初始化
复制代码
/ N# z, M" z; I) b8 l
  iv. 在stm32f10x_it.c文件中找到void USART1_IRQHandler函数,在其中添入执行代码。一般最少三个步骤:先使用if语句判断是发生那个中断,然后清除中断标志位,最后给字符串赋值,或做其他事情。& t5 h& r3 o, h3 B
# k; b$ M1 w1 J/ d# ^$ l
  1.  void USART1_IRQHandler(void) //串口1中断
    7 t+ a2 r0 D/ X8 i' x; i/ u4 Z& V
  2. ! e% q& P0 I6 q9 k& _
  3.   {
    4 p  m; o' A( D  p

  4. $ Q* O" K9 M# c2 p) T- ?
  5.   char RX_dat; //定义字符变量$ n3 h0 I4 M7 k1 U

  6. 0 b0 m0 D1 ?  c: f8 Q% T/ K1 {; E
  7.   if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断发生接收中断& h% w: s& i) Q7 q6 U
  8. ) d" I$ A# g: h, R. m- Z( ^
  9.   {USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除中断标志0 {. d* A5 g  y+ p( ]

  10. 6 S( I" i* o! y; n- W. L
  11.   GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)0x01); //开始传输6 F. e) [* W0 R: F( ]- x
  12. ) R4 n/ `5 V9 Q! Z' \% G
  13.   RX_dat=USART_ReceiveData(USART1) & 0x7F; //接收数据,整理除去前两位
    . J8 Q6 w$ f/ Q* ?7 v5 C7 g

  14. . ^& F" p5 u, F8 J' I, m: {
  15.   USART_SendData(USART1, RX_dat); //发送数据: y5 S7 P1 n% k! R, m% k+ |

  16. + y  q/ C4 C4 t% H
  17.   while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}//等待发送结束9 }& J' R8 n0 c8 Q  D$ C: Z

  18. & F- t  O- ], b0 Z# I
  19.   }4 _7 \6 L) Z  m' i9 U9 m! w7 w: n
  20. 5 s$ V8 _! o$ R% n7 s- I: l
  21.   }
复制代码
; G) o' S) h) d0 c0 j
  d) 中断注意事项:4 a5 ]: M8 h7 F) \9 j, N8 W
  可以随时在程序中使用USART_ITConfig(USART1, USART_IT_TXE, DISABLE);来关闭中断响应。! a, G/ R4 U  F' t1 A5 z
  NVIC_InitTypeDef NVIC_InitStructure定义一定要加在NVIC初始化模块的第一句。
6 i$ x0 X: v+ g  全局变量与函数的定义:在任意.c文件中定义的变量或函数,在其它.c文件中使用extern+定义代码再次定义就可以直接调用了。
% y0 g: R% ]5 X/ a( J0 R0 g% x  STM32笔记之九:打断它来为我办事,EXIT (外部I/O中断)应用
  _% J" h) }/ c3 U; H6 b( p  G( k  a) 目的:跟串口输入类似,不使用中断进行的IO输入效率也很低,而且可以通过EXTI插入按钮事件,本节联系EXTI中断。
+ m- {+ F1 o3 l" A2 Q  ~8 c  b) 初始化函数定义:- g& W: }5 }4 V% i6 N3 `' K
/ }: R; \2 S! Q
  1.  void EXTI_Configuration(void); //定义IO中断初始化函数
复制代码
/ U4 j3 \' A9 F
  c) 初始化函数调用:& q# i0 K3 `+ K- e/ Y6 s
' V2 [2 S' U% i9 J# r$ [, h
  1.  EXTI_Configuration();//IO中断初始化函数调用简单应用:
复制代码
' |2 v. ^! {; |
  d) 初始化函数:
  M  e6 X! B" X2 z$ m! o+ n. R) q3 N! }0 c5 Q/ K
  1.  void EXTI_Configuration(void)
    0 V0 S6 w1 J( Z% L: ?
  2. 9 x: d0 u+ ?7 `  R! D. c3 j+ I
  3.   { EXTI_InitTypeDef EXTI_InitStructure; //EXTI初始化结构定义+ w7 D7 J7 A+ t( \. @4 H8 `
  4. ( M, T& q' u3 _2 T( y
  5.   EXTI_ClearITPendingBit(EXTI_LINE_KEY_BUTTON);//清除中断标志
    4 h& s. Y9 q5 t6 ]# g1 l1 i
  6. - C( W0 K( L* {" y8 u
  7.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);//管脚选择
    ( k. o. n1 K% U$ q2 ~

  8. $ H7 G7 k* `* X: l  ~  L
  9.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);
    : R1 g  q' \9 `+ Q5 C3 H

  10. 2 x9 S) _  \! @  i
  11.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);) w- m; j3 C4 G

  12. 5 }0 O  }- j0 @, O7 j
  13.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);
    2 S% H% G+ g# A6 v! {0 t
  14.   f" M) |9 Y/ X
  15.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//事件选择  D# V3 f5 E/ @- [

  16. ) E: n" V( ^& P: ?; v5 m6 i& ^9 t
  17.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发模式* Y, [3 S- n+ g: d9 Z0 `
  18. % X$ N. \) |3 ?+ R# J% f
  19.   EXTI_InitStructure.EXTI_Line = EXTI_Line3 | EXTI_Line4; //线路选择
    0 E) i9 C. z4 e2 B& `" F* I
  20. ) b: c6 d" N* U( |/ {7 @3 _2 r0 q4 d
  21.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;//启动中断
    + b  _. J, z$ Q6 A1 e8 `; ]2 E, \
  22. / r5 O) o* w! o; c
  23.   EXTI_Init(&EXTI_InitStructure);//初始化
    ' m! l4 C: O# j; i/ P- P; g

  24. 8 L. T1 V5 q2 {
  25.   }
复制代码

; H. T1 d8 l3 d  e) RCC初始化函数中开启I/O时钟1 n' N# f/ O1 h2 J7 l4 l3 l
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);* N) _$ C0 \" o" w5 Q2 D
  GPIO初始化函数中定义输入I/O管脚。9 T2 g; @9 Z" X# o

$ s& ~) ?; r( h) m6 Q1 [% M5 t% _- {
  1. //IO输入,GPIOA的4脚输入5 o. M9 G( V2 v: Z, R9 a& r

  2. 4 R" Y0 i: v" Z' Y
  3.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    : h' L. g( [6 g6 Q0 E" U

  4.   N7 e3 Y  s* g6 r: W3 c$ x
  5.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
    ( s$ t+ b8 a0 ^- }" q. K# y

  6. ' q; `- [8 C. n& ]' o) l
  7.   GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化
    - j0 w0 q! T5 ?+ u7 ?+ p/ x" Z3 [

  8. ) }( U1 X* r; P" c% _  m
  9.   f) 在NVIC的初始化函数里面增加以下代码打开相关中断:
    " H7 ]7 X* i* m2 ?) f% p7 t

  10. 8 c: I( v/ j& I- j) g0 S* P9 U! L
  11.   NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; //通道# i; N  ^, r0 f

  12. " d, e4 r$ T  n# x8 D
  13.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//占先级* x( \. g# N4 ~
  14. + k2 ]) B" g5 ^
  15.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应级! p0 }5 [- x' w% c7 g
  16. * k0 m4 Q- h; D5 f0 C5 m
  17.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //启动
    " D! Y+ T/ \  ^+ ^) T; F4 W% m

  18. 4 N" m+ I6 d4 y! D3 T7 U; C( j( A
  19.   NVIC_Init(&NVIC_InitStructure); //初始化
复制代码
, W) E7 ]/ ?4 n. o" v: s
  g) 在stm32f10x_it.c文件中找到void USART1_IRQHandler函数,在其中添入执行代码。一般最少三个步骤:先使用if语句判断是发生那个中断,然后清除中断标志位,最后给字符串赋值,或做其他事情。+ u8 e8 s( ~  r
9 E; j) I/ u6 o9 Q1 @3 k2 m! i$ `
  1.  if(EXTI_GetITStatus(EXTI_Line3) != RESET) //判断中断发生来源
    ! F& ?7 V; _( v

  2. : n$ U: Z2 Z' ?0 F% E1 r
  3.   { EXTI_ClearITPendingBit(EXTI_Line3); //清除中断标志
    " Y! m) P3 X9 q% ~- ?% Y
  4. / K# w$ \9 E3 G6 O  w0 l
  5.   USART_SendData(USART1, 0x41); //发送字符“a”2 R8 k. x1 S/ r# e- J
  6. ! G! [4 m: e$ ~4 S! r# Q
  7.   GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_2)));//LED发生明暗交替0 `/ a  E2 h* W1 ]9 B
  8. ! u/ t! Q% r$ M* [: A4 j
  9.   }
复制代码
2 O9 d5 O  u; W9 m
  h) 中断注意事项:+ n6 F& o8 l1 X
  中断发生后必须清除中断位,否则会出现死循环不断发生这个中断。然后需要对中断类型进行判断再执行代码。
: J3 Q. r/ {- X/ B$ Y, @  使用EXTI的I/O中断,在完成RCC与GPIO硬件设置之后需要做三件事:初始化EXTI、NVIC开中断、编写中断执行代码。
- p! w+ }3 W. S, O6 q0 m6 ^3 x' b6 U2 S  -----------------------------------------------------------------------------------) a& w: i0 Q. k" z. \
  补充! E' Y$ j. _4 p6 T6 a1 b: u
  上边的不足之处就是无法发送char类型数据,是u16类型的,会报错0 j) X$ G9 x- u5 K) L
  后续可以更换为3.5的固件库,' Z" E6 ?5 e1 o% D# }( {0 m4 \
  d) 简单应用中
* y2 P8 s! u# m8 u- W0 i  超级简单应用只可以发送u16类型数据
& B. B. q' |, u! d# r, o  下面发送char数组时,& G) p+ n3 K$ M; i- _
  “{USART_SendData(USART1, rx_data);、、” 中rx_data需要改为4 P+ t3 c, R: g1 M% e
  rx_data才可以,不然就会报错数据类型不匹配,& X0 y) d- `; D5 p
5 \9 _% V# S" c0 `9 ]4 s) @
/ y; E; _( j9 Y# E, ~6 K

' v" ~' F# O3 a# D5 [
- v: R4 g9 L4 u5 l* o* `' P) T5 |% x6 k) P- T, k
  • TA的每日心情
    开心
    2023-5-15 15:25
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2020-4-20 10:31 | 只看该作者
    谢谢楼主,很详细

    该用户从未签到

    3#
    发表于 2020-11-4 11:03 | 只看该作者
    谢谢楼主分享
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-10-6 11:15 , Processed in 0.125000 second(s), 23 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表