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

基于STM32的ADC片内信号经验分享

[复制链接]
攻城狮Melo 发布时间:2024-1-18 19:00
微信图片_20240118190031.png

2 x# \5 N. h; t! o1 Q* y% a6 D
; j. Q( V- P8 x

( b% x9 U4 c/ T/ Z8 u7 B- R很多STM32芯片里往往内置了专用的ADC通道,比方用来测量Vrefint,VBAT的分压或温度传感器的输出电压信号。不同系列所内置的模拟信号通道可能有差异。这里以STM32G4系列为例,它内置了对应于Vrefint,VBAT的三分之一分压和温度传感器的输出电压的专用模拟通道。
5 r3 B/ P! z$ F' s" F% [" X  i$ d6 B( l$ o3 Q7 q, B
微信图片_20240118190028.png
. Z  b7 w9 k0 u/ n* h* G7 v  \5 U8 h

9 A& o' k9 X9 ~1 H
微信图片_20240118185948.png
5 E0 q& o6 g6 N, d4 {! f' J) r! T7 y
* y- m4 z+ {0 r) q( R4 t0 J
下面的示例就是针对上述3个通道进行ADC,并测量相关电压和片内温度,最终得到3个结果,分别是VRefint电压,VBAT的电压,片内温度。; V  @* z+ r4 q3 b$ p% M
/ J2 |$ E2 D9 g
微信图片_20240118190017.png
. v6 i7 ?. B: F) V
1 l" [0 o5 I% `
实现过程是这样的,大体分四步:【有点点麻雀虽小五脏俱全的味道图片】
9 }! d, j" s- J; [  U8 @; c, Z- ^( a3 [
; ~( T& F" o6 _) @# u7 A1、TIMER1 更新事件触发ADC的转换;
6 l) ?: ~) p+ Y
/ L2 Q( _5 V( v" X2、CPU基于EOC中断获取ADC结果;
' B8 i$ Y: h" ^
/ Q+ k0 B: G4 b. t% x! V# ^3、对ADC结果进行换算,得到电压值和温度值存放在特定内存位置;/ u; \4 W: ^7 z/ L/ ?5 q

7 ^$ \1 _) o- @/ L! |% E4、基于DMA传输通过UART将最终结果在串口终端显示;
3 \8 p9 P8 F( x( X6 W5 \4 T; H( k7 o) I2 _0 w) i5 h
其中,TIMER1的CH1输出PWM波形,其更新事件做ADC的转换启动信号。每次的TIMER更新事件触发ADC,3个通道扫描方式转换。这里的UART使用片内LPUART,使用它主要是考虑它跟板载虚拟串口直接相连,没有其它特别用意。  T- y1 l( p0 @( x& L5 T

& Z! y+ B2 ^: a7 r  S$ {. ^
微信图片_20240118190012.png

! u/ p2 u+ f" x. C: l
8 ~% b# B4 u8 o$ _6 s我使用STM32G474Nucleo板来进行下面实验。其中VDD=3.3v,VBAT与VDD相连。另外,ADC模块的参考电压也是3.3v.
; h% ^# H% {# h) y: m7 P. Y% h: g
: Z! f& Z/ q2 h4 b% Q9 Y: C/ N5 T" v使用CubeMx图形化工具进行配置,先看TIMER配置:
/ ?/ v6 Q) o. U/ s. W; _0 X5 n2 b. N- v6 {
微信图片_20240118190009.png

5 L0 M  I% X7 w' X7 z. Y5 H8 \2 p" m5 ~
再看看ADC的基本配置:
+ Y+ C( T* Q5 X% ~3 w! M  u+ G( ~3 t3 }3 f
微信图片_20240118190005.png
4 m; Q  o( C0 ]3 \& S4 q$ L' p1 o. V/ Z) c

( }& o' Z7 {5 C* D* o* hLPUART的基本配置:
1 C- s1 e1 J/ f- T# L% s
1 y% y; O! T! Z1 K% J
微信图片_20240118190002.png

) @; {& |2 d3 o& i& G& o+ i6 ~+ b( Q
因为要使用ADC中断和UART的DMA传输,记得做ADC的中断响应使能配置和LPUART的DMA配置,这里只使用UART的TX DMA功能。3 T& s# ?: x  c# {! u9 E
' e% I! I9 v* j$ `
微信图片_20240118185959.png

0 ^3 Y) _5 x$ K7 N* h+ L" t. e

! x# x5 v6 I* O" o- O+ E使用CubeMx主要配置主要是上面这些。  f  G2 i6 f5 k7 u+ N
& I( S3 d. V5 d& ^- ^
在组织用户代码前,先简单介绍下片内温度传感器的内容。该温度传感器针对不同温度有不同电压输出,其输出电压跟温度呈线性关系。ST公司针对片内温度传感器在两个特定温度【30℃和110℃或30℃和130℃】、基于特定参考电压【3v或3.3v,不同系列以数据手册为准】生成了1组校准值并存放于片内特定FLASH位置。/ u' ~3 _- J' c2 U, g4 v( K
5 w6 M2 T4 M; o0 M. O2 U9 r
STM32G4系列的校准值是在参考电压为3v,30℃和110℃条件下的两个值,在数据手册里还给出了校准值的片内存放地址。9 @* W8 o2 i/ A) L9 R
  Q" K, r' \0 F& l6 W
微信图片_20240118185956.png
" O" o. f. O) y! x, |

+ p, T/ l6 e- D6 v; G/ t- A针对这个温度传感器的使用,ST公司在参考手册里还给出了计算公式。其实,有无这个公式无所谓,我们不难自行推理出来。【TS_DATA代表某时刻测得的传感器输出电压对应的转换值,TS_CAL1/TS_CAL2分别表示在30℃和110℃条件下基于传感器输出电压的转换值。】; {0 E. ?; Q8 M  D, j, g

0 U- g( U, B. U3 I5 J% _" f
微信图片_20240118185953.png

. l5 z$ L) y' _1 B* A$ p. d
5 ]' N+ `! G/ M' h, r$ }6 [
另外,前面提过,ST公司在手册里给出了温度传感器的两个温度下的校准值,但要注意生成校准值的ADC模块所用参考电压跟我们实际应用时AD模块所用的参考基准电压可能不一致。如果不一致,就必须将ADC值换算成同一基准参考电压条件下的数据。目前在ST手册里也特别强调这点了。我把上面一副图再贴一遍于此【见黄色语句提醒】。
* T5 z$ F! s7 }5 `1 S+ T  L, N+ b: T9 Z6 w! _( z7 f

( H) s7 Z: I' Q0 I1 l8 o2 z

& P) o" x' }9 M- K2 D6 a7 p6 l; [0 i) o# {关于这点,我们也不难理解。同一待测信号、同一ADC模块在不同基准参考电压下转换值往往是不一样的。见下面示意图加以理解。2 A; l' p3 R4 R4 z

$ v. m3 T2 x: {8 e! E3 l
微信图片_20240118185944.png
0 `, ^+ L. S+ [/ Z: k3 D6 ?

# A# k4 }% h3 }1 N完成各项配置后,创建软件工程。添加必需的用户代码:  [' v! b# d+ h$ \  f! T2 y# M' w

. y( S* _2 m6 {: r
  1. #define TX_Timeout (9999)# r0 i8 ?5 P& m6 y+ h* u  I
  2. & V! B$ l! d0 |* d1 [& d- {0 U
  3. #define TS_CAL1_ADDR  (0x1FFF75A8)  //用于计算温度传感器数据
    ' M0 a6 a  d$ `3 w* Q# w" G: ?/ q
  4. #define TS_CAL2_ADDR  (0x1FFF75CA) //用于计算温度传感器数据7 G. D, C, S* F0 {+ [/ z
  5. # g0 f5 V/ z/ V' D* x' W$ _, T
  6. #define size1 (40)
    0 x0 T' |4 W4 D

  7. / x/ X9 ?! u" [% P( s$ J2 h+ ]
  8. char WDVol[size1],BatVol[size1],InVol[size1];( M! X' T+ g" Q3 E  }

  9. 0 b- Q4 p3 n* h0 A
  10. uint16_t ts_c30,ts_c110;
    ( X) u; V" b, W' b" O6 S

  11. " i" @. |7 P1 L: B+ Q7 g# q0 ?) e% k
  12. uint16_t ADCResult[3],convCNT;
    . G, Z% a* B6 ~$ h
  13. 1 I; W4 L# l3 q" E0 J% b
  14. volatile  uint32_t Completed,EndofCon_Flag;: @+ c7 r. N  i0 H; [! t5 u
  15. $ E( t5 ~( a8 r- P% S0 h
  16. float    VBATVolt;//存放BBAT电压最终结果9 d& k, k" r9 z+ }& S7 f" D
  17. float    VRefint;  //存放Vrefint电压最终结果2 }# a2 L( v: ^: V
  18. float    Temperature;//存放片内温度℃最终结果6 N( P# Q) G6 t, e) F& c

  19. 5 v  F' Z( k9 a- O: b- y
  20. int main(void)
    6 _, i. |! Z7 V( z, T. ^9 J
  21. {
    ; G0 a& ^. D  }: C* {7 z
  22. /* USER CODE BEGIN 1 */* {) x" W9 f2 p0 c0 T+ p0 J
  23. 3 V0 D0 V' V& ]1 t( d& R
  24. /* USER CODE END 1 */2 }$ t. ]' Z* W- D  C
  25. 2 P3 J' Y  K% i: B  W
  26. /* MCU Configuration--------------------------------------------------------*/
    7 k, h, N$ f" a* a' }

  27. 0 v4 D6 d% I! \/ W
  28. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */+ ~: K8 T3 c9 {6 y. [3 y( C
  29.   HAL_Init();
    9 M# c5 R7 ~! A0 b
  30. 5 H2 d6 K2 e9 l3 E! Q
  31. /* USER CODE BEGIN Init */# J2 c) {; l, D4 y( _, f4 T8 K

  32. 0 r2 }# Y! d& o* Y0 Q1 x  i' m
  33. /* USER CODE END Init */9 |# V% r3 `& n) A
  34. " r& N* {3 u) i/ Q& L
  35. /* Configure the system clock */6 a. U* ^  V* ?* @1 ^" F
  36.   SystemClock_Config();
    2 ^' Y* O  `# ?

  37. ; V# R3 x* E8 Q& W0 }) c5 l
  38. /* USER CODE BEGIN SysInit */
    5 y! O0 V; W6 Y. ~( D$ s( U

  39. 8 C$ [* P1 n; r
  40. /* USER CODE END SysInit */
    ; g/ w5 ]2 m5 D7 e" L& ~6 N4 J
  41. ) ^% J7 h- j" _+ K8 T2 c8 G6 j
  42. /* Initialize all configured peripherals */. X3 v, n) s( S0 I) ^
  43.   MX_GPIO_Init();) U1 y+ y3 ]$ K0 p! j0 Z# i
  44.   MX_DMA_Init();- ~  @  G' V& `2 I* M9 N
  45.   MX_ADC1_Init();
    1 f( r- P" y' t  Y5 e5 Y. |
  46.   MX_LPUART1_UART_Init();; B. a* }$ y% I/ n
  47.   MX_TIM1_Init();
    4 b' T* c( q0 N& w$ V
  48. /* USER CODE BEGIN 2 */1 `. [9 S& w, `. V# K) s$ d) Z
  49. . F5 l5 a: H0 Q  x* y- [. p% R0 }
  50.    ts_c30 = *(uint16_t *)(TS_CAL1_ADDR); //读取30℃时的ADC校准值
    8 H( C1 L0 e4 a. B+ o+ i

  51. ; Q: X% l2 ]- e( U
  52.    ts_c110 =  *(uint16_t *)(TS_CAL2_ADDR);//读取110℃时的ADC校准值0 y  R( x' E8 Y- P$ M7 E7 p

  53. . R& u2 \- v9 v4 \
  54.   HAL_ADCEx_Calibration_Start(&hadc1 , ADC_SINGLE_ENDED);//ADC校准7 v3 _. E* y( \# l' O
  55. 7 F  Y' o4 _! w1 I) n0 z0 B
  56.   HAL_ADC_Start_IT(&hadc1);//启动ADC并开启转换中断
    1 M9 b% Y( Q9 Q; G) P2 S
  57. * N8 ?. G- }2 T* p" W
  58.   HAL_TIM_PWM_Start(&htim1,  TIM_CHANNEL_1);8 [* P9 i) n4 {' |6 w6 o

  59.   f. B6 V( G3 s% |9 p

  60. % h8 A( k9 ]; M2 `# {* i
  61. /* USER CODE END 2 */
    , l" X2 S# I4 K- h

  62. # D8 @( Z' o. I& Y
  63. /* Infinite loop */6 j( n. |& T* G1 a; X
  64. /* USER CODE BEGIN WHILE */
    , `8 B( Q& j  g, M  k
  65. while (1)
    " B8 I6 j% |* I9 n; V& X! H0 J2 ~
  66.   {& r  {, j$ a8 ^6 ]  B7 G
  67. /* USER CODE END WHILE */
    : n& J* ^. }+ Z  a4 O" e" G
  68. - ]/ A7 k( k. Y9 H* [0 K9 Z
  69. /* USER CODE BEGIN 3 */! X; j3 W2 M4 v* C* m
  70. ) t6 ?& H" E- D4 T6 P& l
  71. if (EndofCon_Flag!=0)" N  c' U% g) H! o8 b$ v
  72.   {
    & h' |' G* ?! f1 o* R/ c
  73.     VBATVolt=(ADCResult[0]/4095.)* 3.3 * 3.;  
    9 A+ y! }* e) q8 }0 Q# `' c
  74. + N0 o9 n4 A+ Q$ [6 k4 q
  75.     VRefint=(ADCResult[1]/4095.) * 3.3;  
    1 s, d- d) \+ C
  76. 5 T  f" j1 _: f
  77.     Temperature = 30.+ (88.*(ADCResult[2]-((ts_c30/1.1))))/(ts_c110 - ts_c30);! }8 l7 O2 p0 x! v% L1 Q
  78. 9 d# C0 G8 R/ q9 h. w
  79.       EndofCon_Flag=0;
    $ ]' t9 U0 v5 g# z" {) h
  80. & _0 B) s+ C& _% {- Z! Q9 i
  81. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol), TX_Timeout);. o( _5 Z: Z! P, G: F% i
  82. # w0 ~2 i& q! ?6 r: J
  83.       HAL_GPIO_WritePin( GPIOC,GPIO_PIN_3,GPIO_PIN_RESET);  //for auxiliary test
    / X0 u& S$ e1 k/ x) a0 Y
  84. 8 w. H' o. J1 U: u" T7 q
  85.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol));
      s" n* b6 k9 d: k( R, W

  86. 7 M5 w5 w$ W2 n
  87. while(Completed==0){}
    . O: N7 U) m0 N7 |
  88.       Completed =0;
    6 W3 I) ~- E0 \9 i
  89. + y* Y8 `" {4 ?3 g

  90. . g5 h9 _/ |0 e+ T9 V8 E
  91. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol), TX_Timeout);
    9 Z2 A2 W( ]3 K6 A( b6 W) X  O
  92.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol));
    & u1 I; h* Z; j* l/ R
  93. + g* y5 I8 t) l+ e) e2 C
  94. while(Completed==0)  {}; n! P& g: p) w) w
  95.       Completed =0;8 u  o2 u" I" W3 [
  96. / O* _; Z: n5 X  E4 J

  97. 3 f. \( [# X) H! j9 D: @
  98. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol), TX_Timeout);
      Z% S% e, J$ i, I+ d% H
  99.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol));3 M* C: N- B! N" n- W4 y
  100. 2 a& i) y1 g, i* `) z
  101. while(Completed==0){}4 r. Y0 Y! O' f" K
  102.       Completed =0;
    9 O" W$ G9 R6 l  z4 c/ J5 W; j8 {1 {# w
  103. - I* q+ ?4 M/ `; E
  104.       HAL_GPIO_WritePin( GPIOC,GPIO_PIN_3,GPIO_PIN_SET);  //for auxiliary test( m9 v" @* Z5 g  h  J
  105. & }% ~( q" R; i' T3 @) S
  106.    }   5 R) {5 Q0 g$ c; f

  107. 9 n8 a& z- F* x1 {0 _, y; R9 j
  108.   }' U* ^7 n& s) N" [. i6 B, z2 Y
  109. /* USER CODE END 3 */
    3 \6 y$ y4 C8 q/ D' j1 W
  110. }8 D# M9 G5 }0 o

  111. 5 ]2 }: K/ D8 Q! T" y6 H
  112. //ADC EOC 中断回调处理函数9 [( ?/ }4 N- m+ q
  113. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)$ u3 |/ X9 g# E5 R6 C1 ?9 `
  114. {; X  Z- [+ {6 v; x7 X4 M

  115. 6 v0 n1 E* @& P* H) q
  116.   ADCResult[convCNT]=HAL_ADC_GetValue(&hadc1); //获取转换结果并存入数组
    6 ~- G& B( I4 a8 u/ y& s
  117. 2 ~, y' s0 \- i; t
  118.   convCNT++;
    8 b9 K6 s4 I- F& a3 `

  119. ! [4 j$ e. N7 h% [1 h
  120. if(convCNT==3)  
    4 D0 `! O( K4 Y+ q7 h! X5 M( R
  121. + b9 E* \4 z0 E$ U# O" z/ A: d
  122. {
    ; H* J( O0 }: c) {
  123.     convCNT=0;6 Z7 }! S5 A6 K0 M' d  l2 A: `
  124. 4 W) g/ g+ j. K' t
  125.     EndofCon_Flag=0xff;
    4 q+ @/ T  T/ d; x9 M

  126. $ U) m6 [8 U' Q$ W1 Z# `
  127. sprintf(WDVol,"Internal PN Temperature: %5.3f  \r\n",Temperature);  4 W2 \. z# C+ v2 v! C
  128. 9 x1 x' j: E! w/ ~; s3 o8 }
  129. sprintf(InVol,"Internal Reference Volt: %5.3f  \r\n",VRefint);  
    5 V- r" {! ]" w! h& W9 F

  130. % q& u$ P& Z/ l- ?" S9 S
  131. sprintf(BatVol,"Current Battery Volt:   %5.3f  \r\n\r\n",VBATVolt);% G! u* h5 B/ V" R8 t" D
  132. : N- g+ D# g- l. B- c$ ]* a5 d- o
  133. }: K) ^# o9 ?0 Q% ?9 Q, N3 v

  134. 5 E6 f" s/ D/ |8 g! |+ q9 j7 x2 W" B
  135. }. [: ^/ X+ O( A4 W7 y2 j

  136. ( e) p! g& J3 O4 v9 o
  137. //UART DMA 传输完成中断回调函数! [; O  C$ x6 U" z* ~
  138. 2 ?! {' P- O# v3 N% U
  139. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)3 }* W4 j+ {3 X
  140. {
    0 l2 q# `* Q; T/ G, D' M

  141. / q/ A9 D1 k; K/ p" ^
  142.   Completed=0xff;; y# q7 u. `0 s) S. Y
  143. }
复制代码
5 f, ?; L+ N( }! E( s( R
基于上面的配置和测试代码,我们就可以看到最终的结果了。定时器周期性地触发ADC,每得到3个ADC结果就进行数据处理,然后通过UART以DMA方式传输到串口终端。注意VBat电压是测量结果再乘以3得到的。( ]6 L2 D5 \9 ]7 u
1 d/ J( Z. t3 q+ j, g# ?( J/ Q
微信图片_20240118185941.png
9 c9 t/ i: w) z5 Z; G: t8 u

( w* I  C3 ^( ~2 |. `
微信图片_20240118185938.png
& X- P, o0 P- K! E* t3 h

3 j0 t3 c2 D) r; T  u% t1 d: J针对上面的应用演示,最后给几点相关应用提醒:& _8 n1 Y! x; u. |
7 {# {2 ?& a& G7 o! ]5 A
1、针对温度传感器做测量时,校准时使用的参考电压与实际应用不一致时要做换算,换算成相同参考电压的数据后再做计算。这点前面也提过了。  D5 w" w) M, F% O

3 i; _; D9 a: P+ \: W* P% V2、使用TIMER的TRGO触发ADC,如果选择类似比较事件、更新事件来触发ADC时,此时ADC对触发极性的选择是无效的,或者说ADC的转换仅依赖于触发事件时间点。如果是选择TIMER的Ocref信号作为触发源,此时ADC的硬件触发的极性选择是有效的,可以是上沿或下沿触发,甚至是双沿触发。这时就得根据需要选择合适的触发沿。【可以进一步阅读本公众号文章《STM32定时器触发ADC的时序话题》】& e$ [  k! t1 g2 V7 b2 m8 X

( e9 P7 Z  n8 w; Z4 C* V/ U* M3、这里使用UART的DMA传输依次显示三个结果于串口终端,三个启动UART DMA传输的函数须保留适当时间间隔,即等上次传输完成后再启动下一次传输,因为这里每次传输使用的是同一DMA通道。否则没法全部正常输出。比如若把上面3次UART DMA传输的代码改成下面这样子:
' H& a$ e1 x) G9 R
8 D6 N7 m  l# r2 u
  1. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol));% M' o2 [9 F$ u2 g1 s5 O
  2. 1 [( W4 _) s9 L$ c+ J( ?
  3. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol));: f0 v3 u: \. g# O

  4. 3 ]7 z% j& q; W* P  e4 b
  5.   HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol))
复制代码
; b* F, Z% O: a; z  B  \1 }
这时输出结果会变成下面的情形,总是只能看到一个结果的输出,即第一次启动的DMA传输结果。/ q) B+ `! F! l0 g% i3 _% M

( v, L, g* m4 C
* M2 i2 K6 u2 X. @+ F
9 {# E8 q8 C7 s- h
如果想省事点,直接在相邻2次DMA传输间加上合适延时也行。我这里根据DMA传输完成事件来决定执行下一次发送。在DMA传输完成中断里设置Completed变量为非0值表示当前一轮DMA传输完成。  k& X$ N8 Z) I; I. }

8 b6 `/ E# ^8 W: Q; b6 ]- L4、对于那些在中断和主程序里都会被访问的变量,记得将它们冠以volatile。
) \( W" o' a- r- k. n& Q, Q% E% U- N" E2 J- w' u! ?3 ]& _
下图的三路波形是我调试时辅助使用的。0 L6 j5 x* d" H: a
5 C( K. M5 Q' W6 n5 ^$ N
第一路表示计数器的计数变化,显然是单向向上计数模式。  d: `: \% z/ e) w6 p+ t/ |

" |. p6 L* h* w* s第二路是TIMER1通道1的PWM输出波形。* r/ _5 Y. w0 {. Y

2 Z- q+ _3 P4 v+ l第三路是我每次基于DMA实现UART发送时拉高拉低的波形。平常管脚电平为高,在实现DMA传输过程中拉低。9 ?! }: c, q! m6 r. u
3 `% n- i+ b5 e4 w5 D
微信图片_20240118185918.png
2 j$ ]! O/ m/ z' V9 s$ d, J
4 E* [" x# u  C% `8 i& Z
如有侵权请联系删除
2 h2 Q' ~% U0 Z8 x9 C# \转载自: 茶话MCU' l$ j* b- \' _1 X. X2 m

* x/ M, Z, L+ q1 S
) @" i0 l/ \$ N6 x. i* Y! [
- s% ?5 \% P6 ?* N- R4 Y3 l9 ~
微信图片_20240118185921.png
收藏 评论0 发布时间:2024-1-18 19:00

举报

0个回答

所属标签

相似分享

官网相关资源

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