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

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

[复制链接]
攻城狮Melo 发布时间:2024-1-18 19:00
微信图片_20240118190031.png
$ e9 W2 a% a0 q3 n) Q% K

) A& Y" }: G8 B* ^2 b
1 V4 h- H# _( M% I
很多STM32芯片里往往内置了专用的ADC通道,比方用来测量Vrefint,VBAT的分压或温度传感器的输出电压信号。不同系列所内置的模拟信号通道可能有差异。这里以STM32G4系列为例,它内置了对应于Vrefint,VBAT的三分之一分压和温度传感器的输出电压的专用模拟通道。
& L  J; z  P' F+ }7 K3 K# V4 R+ C5 o' R9 p& n
微信图片_20240118190028.png

8 p) a1 s0 t* H7 F( S/ x8 |% M2 m) \, z* f  |9 I' \9 n
微信图片_20240118185948.png

# H  z! ]( K" R0 W! B7 }4 i

7 s$ E, J5 S) c( s下面的示例就是针对上述3个通道进行ADC,并测量相关电压和片内温度,最终得到3个结果,分别是VRefint电压,VBAT的电压,片内温度。
0 j& |2 K( B- c, p; J. Y/ ]
8 M* ]! ^" v+ }* ?4 j  y6 J4 C
微信图片_20240118190017.png

1 @4 F, B0 c% ^. k. O
' f2 N" R% ~& \3 i4 B
实现过程是这样的,大体分四步:【有点点麻雀虽小五脏俱全的味道图片】8 Z& }' M$ g0 i& L( ]- @
) [3 d' [* O# q, E" ]1 v
1、TIMER1 更新事件触发ADC的转换;1 B% m  a3 L' I0 P7 X- n3 [
% m" \4 f' G% N1 f7 M! `4 ]5 {7 V
2、CPU基于EOC中断获取ADC结果;; @- K- t6 m* \: O/ ~3 l1 V

$ A0 G2 C) e6 G* K% L3、对ADC结果进行换算,得到电压值和温度值存放在特定内存位置;4 U/ i& s+ X% z

4 _! p9 D3 J0 j0 E! L, f9 P2 x/ ~& ^4、基于DMA传输通过UART将最终结果在串口终端显示;
1 O, d5 l3 I# q; n; U( G9 Q7 z$ |  L  H/ C7 {
其中,TIMER1的CH1输出PWM波形,其更新事件做ADC的转换启动信号。每次的TIMER更新事件触发ADC,3个通道扫描方式转换。这里的UART使用片内LPUART,使用它主要是考虑它跟板载虚拟串口直接相连,没有其它特别用意。; V3 d- J; t3 z, V* n

( i6 i2 V# H% V- e9 c/ m, ]! n
微信图片_20240118190012.png

3 m7 h) b/ ~; W) Q% O- B8 ~
6 a' P) {6 {$ z. C1 ]我使用STM32G474Nucleo板来进行下面实验。其中VDD=3.3v,VBAT与VDD相连。另外,ADC模块的参考电压也是3.3v.( m* }9 G- X; k2 l. b
9 N8 T* s" v$ O9 o- {8 q/ z
使用CubeMx图形化工具进行配置,先看TIMER配置:
/ ]% s0 j' j2 w% U; x' M4 ]0 q
" z! `0 X+ a; U) R
微信图片_20240118190009.png

8 f' }0 f8 @9 e! ]! z% `& ?; o% O- ?
再看看ADC的基本配置:0 B2 g% X# w& p. }% }! h1 J) F+ }7 X
4 V2 f+ ]. b2 W& y1 W& Q+ i; s
微信图片_20240118190005.png
: }6 y: w2 I& r/ J, `3 y$ ^9 N
8 @& @' w; N! K
LPUART的基本配置:
8 F5 O" O4 z# C& x6 Q7 x, ^+ S: [4 i  b
微信图片_20240118190002.png
0 C6 S6 i6 n' U, W6 p9 U
* c6 ~3 e- h% I# o
因为要使用ADC中断和UART的DMA传输,记得做ADC的中断响应使能配置和LPUART的DMA配置,这里只使用UART的TX DMA功能。
6 A' y8 r1 z9 G. J7 |+ \# `; {# W: Y& q9 `5 {6 `0 }
微信图片_20240118185959.png
$ ~1 V. |# A1 O- Z" g: q$ X2 l8 T

! _9 X% w/ o9 ^; x使用CubeMx主要配置主要是上面这些。+ E: Q2 j6 q1 E4 l: ?

; i: K0 {8 l7 g" S$ d5 O在组织用户代码前,先简单介绍下片内温度传感器的内容。该温度传感器针对不同温度有不同电压输出,其输出电压跟温度呈线性关系。ST公司针对片内温度传感器在两个特定温度【30℃和110℃或30℃和130℃】、基于特定参考电压【3v或3.3v,不同系列以数据手册为准】生成了1组校准值并存放于片内特定FLASH位置。0 w7 n( u. d+ H1 \. Y: ~$ [

) s& d! F6 y! z, a2 e8 tSTM32G4系列的校准值是在参考电压为3v,30℃和110℃条件下的两个值,在数据手册里还给出了校准值的片内存放地址。) Y, o" J1 H) \  x' d- m; i

5 c0 T9 E( k* H/ v$ c
微信图片_20240118185956.png

5 X  @! D. Z+ y& B

- L8 j; l% ~- ~; k0 H- X6 t$ u针对这个温度传感器的使用,ST公司在参考手册里还给出了计算公式。其实,有无这个公式无所谓,我们不难自行推理出来。【TS_DATA代表某时刻测得的传感器输出电压对应的转换值,TS_CAL1/TS_CAL2分别表示在30℃和110℃条件下基于传感器输出电压的转换值。】, b* z# d8 o" o6 B* P7 X
* `" I1 ]4 M* ^- y" P
微信图片_20240118185953.png
: U* y: u) f5 Z: h; |# v
- d+ q# s2 q+ h8 C0 R+ n' `
另外,前面提过,ST公司在手册里给出了温度传感器的两个温度下的校准值,但要注意生成校准值的ADC模块所用参考电压跟我们实际应用时AD模块所用的参考基准电压可能不一致。如果不一致,就必须将ADC值换算成同一基准参考电压条件下的数据。目前在ST手册里也特别强调这点了。我把上面一副图再贴一遍于此【见黄色语句提醒】。
4 H9 W7 ]8 h" i0 Q# |$ V6 g  J
! D- m" O3 z8 I8 }- e( I& Y

' \+ |: e0 j( m- [9 y. C4 e' ~) P

% z9 \: j+ A6 e2 u) r% L0 i关于这点,我们也不难理解。同一待测信号、同一ADC模块在不同基准参考电压下转换值往往是不一样的。见下面示意图加以理解。
  \* w" x9 p+ g9 N" `
0 h" f0 u6 r+ {% D$ j) e/ Z
微信图片_20240118185944.png

; u- ]0 A! C  ?7 B

7 i3 A) I: L& G; [7 v' B, S" @完成各项配置后,创建软件工程。添加必需的用户代码:5 Y) F# c8 f$ H; C2 l1 a

/ ~9 G6 b! k. C
  1. #define TX_Timeout (9999)
    9 n1 h% h7 \5 R; E  c' i

  2. 3 ~/ j; s5 K) {% \
  3. #define TS_CAL1_ADDR  (0x1FFF75A8)  //用于计算温度传感器数据# S4 {& `4 N/ o& u; M1 @
  4. #define TS_CAL2_ADDR  (0x1FFF75CA) //用于计算温度传感器数据3 h9 C& f7 X; I, O& m6 ]

  5. ( `1 a7 I4 `+ G0 l8 S
  6. #define size1 (40)
    9 k( H) `+ t$ a' x) V
  7. ' y  x$ P2 r" U' u9 a
  8. char WDVol[size1],BatVol[size1],InVol[size1];; C" ~& t( Q) O6 y. L" H1 t
  9. 1 _8 r# X6 `( B5 N2 |
  10. uint16_t ts_c30,ts_c110;' |0 q7 }8 Q' p2 r$ S

  11. $ r5 L4 z. Y2 c* M! h, B
  12. uint16_t ADCResult[3],convCNT;& Y& D! l( m' W! b( \
  13. . w4 y* m* f& u& Z
  14. volatile  uint32_t Completed,EndofCon_Flag;
    $ r' k+ j6 a7 g, Z+ E

  15. 8 e2 A% F8 }% |
  16. float    VBATVolt;//存放BBAT电压最终结果3 X0 z, v* u' U, J2 o& a4 E
  17. float    VRefint;  //存放Vrefint电压最终结果4 v6 P( f% R1 _; e
  18. float    Temperature;//存放片内温度℃最终结果0 E. e. a9 w8 h
  19.   d' e9 ~' l; ~, O
  20. int main(void)- A! K2 p& Z  d$ J
  21. {$ B8 d. Z' e2 h2 i' U7 X
  22. /* USER CODE BEGIN 1 */& D* P. Z3 {% z# L, C
  23.   t* ^" q, n* ^
  24. /* USER CODE END 1 */
    6 x! P  j, \8 G$ c7 t' w4 T5 ?

  25. ; i2 i/ C! \3 @( u/ W2 o
  26. /* MCU Configuration--------------------------------------------------------*/
    $ a( a5 t; f2 [* }/ d
  27. 0 j7 l  X# \/ `4 L8 \+ z# Y3 h$ O. t
  28. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    + b( I9 i3 ^3 b
  29.   HAL_Init();
    / ^) j' Z) V$ P: F: ^9 m

  30. 8 ~4 M: [5 H# ~/ j6 U
  31. /* USER CODE BEGIN Init */
    $ o5 [5 j, I, F# f

  32. 8 ^0 h  H, d! _4 C3 m
  33. /* USER CODE END Init */
      l6 d4 T+ [" B& U# P9 F0 {. e
  34. 1 f: d. }* D- J2 _7 I7 S
  35. /* Configure the system clock */( I5 L$ q. z! s
  36.   SystemClock_Config();
    . X+ n4 f' _2 A) o4 c
  37. 3 `5 W4 a4 p# ]4 I
  38. /* USER CODE BEGIN SysInit */% W& r: @6 g( ?: Y: S
  39. * h6 c0 o7 g% E, I: U
  40. /* USER CODE END SysInit */
    ; i8 a. C/ p9 _( h+ B
  41. , V8 F3 G8 {5 p1 {$ F
  42. /* Initialize all configured peripherals */
    : N8 h# a  y* e5 D" K; K7 {1 B
  43.   MX_GPIO_Init();
    / x' N. D1 s0 C
  44.   MX_DMA_Init();0 |* X3 i2 ]+ q, h% b: S% R& F& W( @7 _
  45.   MX_ADC1_Init();3 Y1 c2 h! J+ a* ]% S5 K2 Q
  46.   MX_LPUART1_UART_Init();- S( P7 \; X7 m$ h- s
  47.   MX_TIM1_Init();
    3 j# K6 F, g# r0 t6 _% K" x
  48. /* USER CODE BEGIN 2 */7 ?4 z5 @' v) I

  49. 2 {3 w; q, D; Y# s& O' H3 }
  50.    ts_c30 = *(uint16_t *)(TS_CAL1_ADDR); //读取30℃时的ADC校准值- R& J  G3 p' M; U6 W8 Y

  51. # M' ?( x' d' [7 J; L
  52.    ts_c110 =  *(uint16_t *)(TS_CAL2_ADDR);//读取110℃时的ADC校准值+ ~! h8 O# P1 L( l$ [9 X* j" D

  53. . L! E9 B' }) R
  54.   HAL_ADCEx_Calibration_Start(&hadc1 , ADC_SINGLE_ENDED);//ADC校准0 j! D) M2 m- n3 b8 J4 L
  55. / M0 n4 ^! w* C) Q2 u: |3 M7 a/ |; t
  56.   HAL_ADC_Start_IT(&hadc1);//启动ADC并开启转换中断# T# B/ p: a# n( m
  57. 8 z3 T+ n  M3 D! B% r
  58.   HAL_TIM_PWM_Start(&htim1,  TIM_CHANNEL_1);
    7 W$ g  P6 w7 F" I1 o3 k

  59. + L4 y8 z. V* W$ u1 J: u9 \( s
  60. 8 x- p4 d4 w; [) y) I# P# y1 c
  61. /* USER CODE END 2 */- _# u  e# f* }2 Z3 A* Y$ j
  62. , q# U7 ]$ `( z" j' y2 v
  63. /* Infinite loop */; {, c6 Z1 T/ I0 s/ t" S, v
  64. /* USER CODE BEGIN WHILE */
    . H; u9 I$ s8 i7 P" m' e& t
  65. while (1)
    ' O( ?1 i  _$ {
  66.   {# G  L/ y  V; I" ^% u
  67. /* USER CODE END WHILE */
    ' q# ^* k. z: e
  68. ! ?0 G) t; h8 I2 b% h& J' {. }% T
  69. /* USER CODE BEGIN 3 */. N6 ?  Z* O8 n/ N

  70. . g, ~9 p# C3 U$ `5 e' i
  71. if (EndofCon_Flag!=0)1 P/ a% ?6 I9 |) G3 N4 b" p
  72.   {3 C4 D2 x' Q8 E
  73.     VBATVolt=(ADCResult[0]/4095.)* 3.3 * 3.;  
    5 f8 M: S( x# Q8 \

  74. ) z& n# f8 g% V9 B$ Q- \
  75.     VRefint=(ADCResult[1]/4095.) * 3.3;  
    8 D$ k  L( a% \: F0 }
  76. ) w2 M) s% T* z; X0 N' T
  77.     Temperature = 30.+ (88.*(ADCResult[2]-((ts_c30/1.1))))/(ts_c110 - ts_c30);+ {5 ^7 k* i5 i" K: t

  78. 5 T8 t1 r& k. Y" V4 [% C5 S6 a
  79.       EndofCon_Flag=0;
    : Z7 h$ ]. q* J

  80. 4 u7 W9 G" [2 R2 d6 l
  81. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol), TX_Timeout);
    2 S, r) o* ?. W
  82. # J+ B0 R: M0 H  b& k1 m( |1 _, d
  83.       HAL_GPIO_WritePin( GPIOC,GPIO_PIN_3,GPIO_PIN_RESET);  //for auxiliary test+ E, X$ [* G' x6 ^/ ?

  84. * d( n9 B" ^% B  S4 q. K
  85.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol));3 V2 a7 ?- x- U1 q. q$ ?

  86. 3 m  ^, R0 ]+ j0 |4 s5 M) B  d( L
  87. while(Completed==0){}
    + P, A6 Y1 ~- v: D
  88.       Completed =0;
    % x* x5 I1 Y7 P; L5 S  q+ e

  89. ) l: N9 x: f5 G- g7 s2 x, u

  90. # R* f, ]; a1 {( Z: y
  91. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol), TX_Timeout);& H' `+ H7 ^/ ?  h7 g
  92.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol));
    ( r7 L; ]0 D! m) w2 G
  93. " j) d* I9 z1 I7 E
  94. while(Completed==0)  {}. ~0 A2 J$ }4 \" O0 {# A$ @
  95.       Completed =0;8 H6 X5 s3 z" f- b6 f- J2 `/ C8 ]

  96. 9 _3 w5 L/ A# z& @3 x

  97. 4 X$ s5 s; {* y3 M  X4 U, ^
  98. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol), TX_Timeout);
    9 O  G6 Q# K( `
  99.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol));
    8 k  B& W2 P# f2 ^

  100. 4 k+ e# L: m7 P
  101. while(Completed==0){}( d5 f  y! `: j. C& F
  102.       Completed =0;7 z6 u, K$ W1 R2 I2 K* x! r
  103. , K+ t- T) u4 H4 O  d/ l
  104.       HAL_GPIO_WritePin( GPIOC,GPIO_PIN_3,GPIO_PIN_SET);  //for auxiliary test8 Z" v( X2 H% v* ]) v' ?/ \

  105. 2 @) }0 W! Z$ l7 |, m
  106.    }   
    3 t. M- _5 M9 W3 I% {& F; g6 d
  107. - \9 k' F6 \+ O% ^# L) i
  108.   }
    / K1 S( E& ?5 n+ {9 Y1 ]
  109. /* USER CODE END 3 */
    ' @* Y; p/ }! H) N
  110. }% V/ f! F! n& C. n( G( t( S

  111. ) ~7 o+ A( V) ?* o1 X9 P
  112. //ADC EOC 中断回调处理函数
    ; n7 X+ [) }  u
  113. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
    2 g+ Y( q% Z$ b* B5 \1 t% Z! A# B( x/ G
  114. {% E8 ]- Z* Y7 }' a
  115. ! Q9 Q% Z! ]: G2 `0 C! @* S
  116.   ADCResult[convCNT]=HAL_ADC_GetValue(&hadc1); //获取转换结果并存入数组. A7 C. i7 u7 P; s5 u" }4 n" I
  117. 1 ~: v7 G% e4 l' P$ o; c
  118.   convCNT++;: p! h& n, q7 d; V( S

  119. 1 J1 V0 p0 b) F5 s# w" V" j1 z
  120. if(convCNT==3)  $ z8 r; `; I( p8 V$ U
  121. 2 T  Y  B% D1 |! b$ U
  122. {
    " z# I1 N: `' l6 {2 K, \* ^
  123.     convCNT=0;7 h8 ^+ W3 F! T$ Y: i4 S

  124. " @- Z' T& v! s, F* F  W% o& b
  125.     EndofCon_Flag=0xff;
    ' c- Z" [" h6 ?* d

  126. ) Y0 [' k# |& w2 G, j
  127. sprintf(WDVol,"Internal PN Temperature: %5.3f  \r\n",Temperature);  / r+ [5 p. ?3 _; s2 {

  128. 9 B& t; T  I4 t+ {4 q9 u
  129. sprintf(InVol,"Internal Reference Volt: %5.3f  \r\n",VRefint);  
    8 w# R/ ~% W. t8 h/ a
  130. * F# d* D( m- L# [2 {; G. \
  131. sprintf(BatVol,"Current Battery Volt:   %5.3f  \r\n\r\n",VBATVolt);3 [4 ], S2 n& X4 z) p! n5 L4 H
  132. / `4 ]7 U3 i) M0 H" k
  133. }: \( r6 Z  z0 ?- i+ V; w$ |

  134. 8 K, e4 Q7 M7 x$ b* {- k$ M, G4 l
  135. }
    $ s$ x( E0 ~2 E$ X

  136. ) O+ `- ]1 B' P( B" |  U
  137. //UART DMA 传输完成中断回调函数9 @1 I5 F- D* \( K

  138. % P- r) F* j! E9 h$ Q
  139. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
    % f5 Z9 Z8 `. `
  140. {3 f/ d( a& Z( L/ E# E' m

  141. # o! v" ~* a0 U1 H6 A( T
  142.   Completed=0xff;9 Q# ]5 ]" ~5 S( P' s8 e% j. C
  143. }
复制代码

; G$ K9 j  [7 y1 }基于上面的配置和测试代码,我们就可以看到最终的结果了。定时器周期性地触发ADC,每得到3个ADC结果就进行数据处理,然后通过UART以DMA方式传输到串口终端。注意VBat电压是测量结果再乘以3得到的。. l, I  v& Q7 k( ^
8 M* U. c+ x6 N5 h
微信图片_20240118185941.png
4 q( H2 _8 l' Y! g7 \0 ]
; G8 Y6 H) w$ a" m& g% G% A7 S
微信图片_20240118185938.png

# n* s( V% R1 r  p0 b# a# m$ f" N, l( d
针对上面的应用演示,最后给几点相关应用提醒:
8 C$ U8 c: |6 R; c$ f) P( f, V) e
, S. F) ?- a. f1、针对温度传感器做测量时,校准时使用的参考电压与实际应用不一致时要做换算,换算成相同参考电压的数据后再做计算。这点前面也提过了。
) A% a  q/ a& q5 v6 k! l+ b) I# x* z1 w" l7 M7 K+ F$ v. S7 c
2、使用TIMER的TRGO触发ADC,如果选择类似比较事件、更新事件来触发ADC时,此时ADC对触发极性的选择是无效的,或者说ADC的转换仅依赖于触发事件时间点。如果是选择TIMER的Ocref信号作为触发源,此时ADC的硬件触发的极性选择是有效的,可以是上沿或下沿触发,甚至是双沿触发。这时就得根据需要选择合适的触发沿。【可以进一步阅读本公众号文章《STM32定时器触发ADC的时序话题》】
# V2 k! m& @1 e% w5 B: k: I: H* W8 Y, o0 o
3、这里使用UART的DMA传输依次显示三个结果于串口终端,三个启动UART DMA传输的函数须保留适当时间间隔,即等上次传输完成后再启动下一次传输,因为这里每次传输使用的是同一DMA通道。否则没法全部正常输出。比如若把上面3次UART DMA传输的代码改成下面这样子:) s1 G" \% E! H. x: m; x
& O# x  v; P3 P: l  H/ ~  @8 o9 s
  1. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol));
    1 n, C1 B0 I5 }8 @% a* k
  2. ! \1 Y, H' A/ j5 h
  3. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol));
      g7 w3 L4 `# G+ x$ k

  4. ' K- k1 X  H& F/ K- G3 k- ~, }1 a: P& z
  5.   HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol))
复制代码

  E7 I# ^" ]* s7 h5 Q这时输出结果会变成下面的情形,总是只能看到一个结果的输出,即第一次启动的DMA传输结果。
( X9 Z% \( p& M( A8 p, z5 G, ]6 R) O6 {$ l

9 o: X0 A2 Z7 Y3 X# W* h# i: U( i1 {4 m- x# E9 v, Z$ r+ y
如果想省事点,直接在相邻2次DMA传输间加上合适延时也行。我这里根据DMA传输完成事件来决定执行下一次发送。在DMA传输完成中断里设置Completed变量为非0值表示当前一轮DMA传输完成。$ V) m- f6 {/ o. A+ `

& z4 w( R( O7 ^! [: W* V4、对于那些在中断和主程序里都会被访问的变量,记得将它们冠以volatile。
) |) W. w& T5 d$ j! b  t9 b  U: a6 x( [) E+ I) g9 [
下图的三路波形是我调试时辅助使用的。4 F$ Z/ u5 ~  {' Z, Q3 Q/ c2 r

5 D6 o0 k2 o+ u6 E0 d, k- z第一路表示计数器的计数变化,显然是单向向上计数模式。) y- }. @6 m! A3 z( t0 i

4 K3 g" \: X% ?, S+ Y, a% f第二路是TIMER1通道1的PWM输出波形。  r, g3 I4 _3 a4 Y
. b, ]* T+ Q0 v' r) b
第三路是我每次基于DMA实现UART发送时拉高拉低的波形。平常管脚电平为高,在实现DMA传输过程中拉低。. T+ C, C+ j5 f4 c$ k
! Y+ w: |, T- P/ T6 E8 J; g
微信图片_20240118185918.png
0 P' A: P4 i8 B& a* e2 r7 f
; s' J( E% ?3 n- [
如有侵权请联系删除
9 V3 }9 O& F- Z/ B8 q1 E转载自: 茶话MCU
( [  H( S  p- C0 o) |5 ~- c
" a; h" V  a1 g# F1 U2 ?
& j( x8 j7 ^& L9 ~5 I
& u3 Q; O) j6 M) m7 P$ k3 @/ l
微信图片_20240118185921.png
收藏 评论0 发布时间:2024-1-18 19:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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