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

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

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

4 a3 U- T; ]: u$ y
7 e" o8 \" Z7 a2 X) i/ x

9 f9 n& x3 a6 Z1 B2 K很多STM32芯片里往往内置了专用的ADC通道,比方用来测量Vrefint,VBAT的分压或温度传感器的输出电压信号。不同系列所内置的模拟信号通道可能有差异。这里以STM32G4系列为例,它内置了对应于Vrefint,VBAT的三分之一分压和温度传感器的输出电压的专用模拟通道。
: X- f5 l& b2 G, u  }# u
  p/ o* M4 A; i! n
微信图片_20240118190028.png
- z7 H. V. @7 N2 s# a1 @

& c7 ~) _1 a9 R# O3 Z4 M
微信图片_20240118185948.png

- G4 `9 _' b( `2 t9 }2 z
* d! _* Y5 |, G4 \& Z2 N6 C) A! ?$ v1 X
下面的示例就是针对上述3个通道进行ADC,并测量相关电压和片内温度,最终得到3个结果,分别是VRefint电压,VBAT的电压,片内温度。
9 X5 T  Z( U+ n  ]
3 U% ~" Y7 j# a7 U. R8 s* x4 t
微信图片_20240118190017.png
& \- g: k3 j# ?3 Y: U" V
: X. `: u) P2 u7 L; j5 c
实现过程是这样的,大体分四步:【有点点麻雀虽小五脏俱全的味道图片】5 ?0 m+ P- W) b

. ]; z; v- s& W' I0 e1、TIMER1 更新事件触发ADC的转换;
: r7 K8 E& m2 y" q3 n
) j9 m2 ~, G& D6 E! k7 D2、CPU基于EOC中断获取ADC结果;
1 W  z* a, Y; D3 k  v
& g- M) Z' E9 }* ]3、对ADC结果进行换算,得到电压值和温度值存放在特定内存位置;( X. |" X/ J8 V. S. q2 P
" `' _9 r8 v# y' X
4、基于DMA传输通过UART将最终结果在串口终端显示;
4 W* U. b% S  U8 q4 p: A
/ w+ @% o3 A9 ^& V其中,TIMER1的CH1输出PWM波形,其更新事件做ADC的转换启动信号。每次的TIMER更新事件触发ADC,3个通道扫描方式转换。这里的UART使用片内LPUART,使用它主要是考虑它跟板载虚拟串口直接相连,没有其它特别用意。
  L" Q* A: a& g5 k
9 _3 k' B* d' @/ r
微信图片_20240118190012.png
: s, V- L/ V% l, C' U1 Y
6 L" m& i7 c3 q
我使用STM32G474Nucleo板来进行下面实验。其中VDD=3.3v,VBAT与VDD相连。另外,ADC模块的参考电压也是3.3v.' h) w5 d. z8 {2 O1 _$ ?

$ l+ t3 {' b; @! f- ^* D) ~/ N使用CubeMx图形化工具进行配置,先看TIMER配置:+ a0 t7 ~3 u, Y* `4 I
' D) D$ p+ y% Q2 Q# V& |
微信图片_20240118190009.png
& \! w: ]( S) d6 @  f) ?+ I* ]

  D  [# N, ^) E5 s( Y再看看ADC的基本配置:
8 h+ ^- j; |. N' `, W& f" X4 [* B
, g3 n3 l& E  `! X- N8 \
微信图片_20240118190005.png

( h0 n' j# ^* }1 g8 R% a* q* l6 `' `5 x! B
LPUART的基本配置:
$ ]6 E( z3 B, W; k2 Q
; V- ]% t% q. R$ C& O. o
微信图片_20240118190002.png

' ], l- N1 N% Q7 }6 C7 F, e5 P+ v6 A8 b0 `! F
因为要使用ADC中断和UART的DMA传输,记得做ADC的中断响应使能配置和LPUART的DMA配置,这里只使用UART的TX DMA功能。
" v. m( x5 G' a' {0 c5 d, @- u  f$ ~. ~) w& ?! |' z
微信图片_20240118185959.png

9 @* m; ~$ c  [) r8 L3 H

1 l; U: w' T' @! @使用CubeMx主要配置主要是上面这些。
0 d( e8 I3 q1 S. K0 N. z! ^5 p& ]* @$ D- `
在组织用户代码前,先简单介绍下片内温度传感器的内容。该温度传感器针对不同温度有不同电压输出,其输出电压跟温度呈线性关系。ST公司针对片内温度传感器在两个特定温度【30℃和110℃或30℃和130℃】、基于特定参考电压【3v或3.3v,不同系列以数据手册为准】生成了1组校准值并存放于片内特定FLASH位置。# v7 c; ^8 }& [5 m
/ R9 ^$ A8 z+ m; B3 r6 B& m* z
STM32G4系列的校准值是在参考电压为3v,30℃和110℃条件下的两个值,在数据手册里还给出了校准值的片内存放地址。
% ~% f  U- J" u2 f$ f  {+ g; P
1 r1 G+ Q, }: x
微信图片_20240118185956.png
( q  H' E* u3 F1 w2 v0 B; c

. f* J" ~- L* ?7 B2 {9 Y针对这个温度传感器的使用,ST公司在参考手册里还给出了计算公式。其实,有无这个公式无所谓,我们不难自行推理出来。【TS_DATA代表某时刻测得的传感器输出电压对应的转换值,TS_CAL1/TS_CAL2分别表示在30℃和110℃条件下基于传感器输出电压的转换值。】
) `( Q0 f- Y  K3 M* ?1 ]- U1 c& Z+ ?: }. ]' a% c7 t  D6 M1 }7 i
微信图片_20240118185953.png
0 r5 P- d( w& Z8 c6 p5 i& j" j

- r: |* ]1 B9 I, {0 v另外,前面提过,ST公司在手册里给出了温度传感器的两个温度下的校准值,但要注意生成校准值的ADC模块所用参考电压跟我们实际应用时AD模块所用的参考基准电压可能不一致。如果不一致,就必须将ADC值换算成同一基准参考电压条件下的数据。目前在ST手册里也特别强调这点了。我把上面一副图再贴一遍于此【见黄色语句提醒】。. h' w# U6 M5 A5 g) ^6 P7 _  B
  [# I! Q- C7 K0 `; x8 O( U
+ V" I7 B8 t( q( C+ W6 k
1 B6 T: ^5 N) {# S+ w
关于这点,我们也不难理解。同一待测信号、同一ADC模块在不同基准参考电压下转换值往往是不一样的。见下面示意图加以理解。
- p& n4 m4 n$ B- m# ]/ C4 c& ?6 D8 {( b5 V) {4 W
微信图片_20240118185944.png
5 b9 X5 |. p. z. V6 {
  |3 {+ s- v: y& E
完成各项配置后,创建软件工程。添加必需的用户代码:
1 I1 K( ~; N4 h
' P/ \* `9 J! h0 p/ k) C
  1. #define TX_Timeout (9999)  ^0 x' k2 e, O* s- w! r& o3 p
  2. ' h9 h4 d: s) @  l2 t% R
  3. #define TS_CAL1_ADDR  (0x1FFF75A8)  //用于计算温度传感器数据8 E" g! V: i9 S5 a* k
  4. #define TS_CAL2_ADDR  (0x1FFF75CA) //用于计算温度传感器数据; h+ q0 b- c1 [7 `* [

  5. 0 l+ s- M  t, b6 o" g; k& I8 H/ n
  6. #define size1 (40)6 h( k  H6 y" \4 ~

  7. 5 X$ O6 N  m3 }( o' M
  8. char WDVol[size1],BatVol[size1],InVol[size1];+ _8 O4 D0 W3 T$ K) e3 T( E

  9. ; P, J( c$ u! D4 b0 L2 P
  10. uint16_t ts_c30,ts_c110;* k$ h1 t; ^9 W6 O7 f1 G

  11. ) z6 A: `$ h. Q: T* x
  12. uint16_t ADCResult[3],convCNT;% D9 M! ?  L! i- s" O

  13. 8 E+ G0 g4 d* B5 n6 E# p: {; R
  14. volatile  uint32_t Completed,EndofCon_Flag;
    - g$ s! N4 l+ R  k

  15. ' s) T9 ~6 r) G0 ?* o' z. r) t9 d2 j
  16. float    VBATVolt;//存放BBAT电压最终结果
    1 d  P0 m' E4 \, n3 K
  17. float    VRefint;  //存放Vrefint电压最终结果. [; m& w( M0 V! g9 t" N
  18. float    Temperature;//存放片内温度℃最终结果) u7 G1 b6 ^) y6 l2 X# s  h

  19. 8 e; W5 O- B8 r* F4 S; `7 \$ f
  20. int main(void)2 A" E4 q3 f/ Q7 C5 m
  21. {
    ' w& \& u( @4 Z" k& ?( ]) o
  22. /* USER CODE BEGIN 1 */+ q% [  [& D' n  W1 j
  23. $ V) Z: l& O2 x" ~: Q: f3 b
  24. /* USER CODE END 1 */
    6 s2 Y. J1 r; V  Z" m3 ]! Y4 j

  25. % {* b5 a; C$ W& m
  26. /* MCU Configuration--------------------------------------------------------*/2 W, V, ?2 N1 c. t

  27. $ Q2 ^. T$ S, W- l  k
  28. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    0 o4 _: r" ~7 _- L" Y  {6 s
  29.   HAL_Init();: P. A. f2 W4 d9 ]" E5 T
  30. . A/ x! I) K/ }" k" K
  31. /* USER CODE BEGIN Init */) ^' n% E' I! y: k  i! p2 O

  32. 8 I+ Z4 k, W) k  F& D; g
  33. /* USER CODE END Init */
    6 Z; H+ I( |9 z% F1 o+ s' x& d# |( \
  34. * [! @% P# F4 h( x0 I
  35. /* Configure the system clock */; G% P/ z- {: V! j7 v
  36.   SystemClock_Config();8 W6 @1 V, ^- L, q! p6 J$ ~
  37. $ e. a% \2 P: G! c' m8 l
  38. /* USER CODE BEGIN SysInit */
    , P9 x( R- y: s0 Q- }) E" y

  39. 2 s1 U& m6 O0 T4 R4 Z$ G) u8 ]
  40. /* USER CODE END SysInit */4 O- J0 R6 U% g6 ]5 u( O" v# g
  41.   S" H/ y! `; G2 g: N7 v/ o1 s
  42. /* Initialize all configured peripherals */
    ) }5 x7 m* S$ _% e. y
  43.   MX_GPIO_Init();6 o) ~4 n, P+ n: |) y) F
  44.   MX_DMA_Init();
    9 g' K" v2 O+ M6 H! ]
  45.   MX_ADC1_Init();
    / \/ k/ ^# i* R9 M
  46.   MX_LPUART1_UART_Init();3 g8 r* H  R+ q; `
  47.   MX_TIM1_Init();5 Z+ W5 G6 ]2 c$ {
  48. /* USER CODE BEGIN 2 */
      W, o. E" w8 F! P! D
  49. / w) X+ |4 j* `% R( K  A6 ]" B/ k9 x
  50.    ts_c30 = *(uint16_t *)(TS_CAL1_ADDR); //读取30℃时的ADC校准值- {2 C# C+ s" i; @0 A& d6 v

  51. 4 J) G- X# n# X& R8 k
  52.    ts_c110 =  *(uint16_t *)(TS_CAL2_ADDR);//读取110℃时的ADC校准值
    6 Q, d5 e& \3 c4 d( K# S8 b0 z" Z

  53. 9 k8 k+ G2 g4 x- V& X! R
  54.   HAL_ADCEx_Calibration_Start(&hadc1 , ADC_SINGLE_ENDED);//ADC校准2 p: k6 O$ U5 J' A

  55. 4 Z3 S4 v, ?6 {9 S
  56.   HAL_ADC_Start_IT(&hadc1);//启动ADC并开启转换中断5 @4 J" @7 j, n6 K

  57. " V' T# n2 i6 P( f
  58.   HAL_TIM_PWM_Start(&htim1,  TIM_CHANNEL_1);, Y7 W6 H& b9 c5 ?2 O
  59. * m& F& B* B$ _, f9 V2 m- Y

  60. % D, f  E$ R) D- ]$ N; x: m9 [
  61. /* USER CODE END 2 */- Q& S3 }8 K) I8 x
  62. 4 h$ o7 J+ T7 w0 U& J
  63. /* Infinite loop */
    % |) n  s7 Z/ E. L6 W. H3 ?
  64. /* USER CODE BEGIN WHILE */! r) B/ J0 I4 H3 g3 K
  65. while (1)$ ~3 l( ^- d# k# Z$ D2 S0 `7 p
  66.   {
    2 x& s( o5 s: \' Q& ~+ I
  67. /* USER CODE END WHILE */
    % X8 i+ @) i9 U$ }+ I5 G- a
  68. . I, {4 J% h( t( v' X* ~, L
  69. /* USER CODE BEGIN 3 */" B: H+ a( h( _8 H

  70. * b9 {0 [0 n# \3 f5 e8 M' G0 L2 d
  71. if (EndofCon_Flag!=0)  w, F, F% b3 A; p5 B8 Z
  72.   {
    ( Z$ y2 ^9 J' x% v  Y9 A
  73.     VBATVolt=(ADCResult[0]/4095.)* 3.3 * 3.;  
    ) v. h7 ^1 h) j4 Z

  74. , K+ v/ ^! F, {
  75.     VRefint=(ADCResult[1]/4095.) * 3.3;  ; ~7 ~/ ~! }) p) {9 W
  76. 3 C5 F; f( c) f0 D
  77.     Temperature = 30.+ (88.*(ADCResult[2]-((ts_c30/1.1))))/(ts_c110 - ts_c30);9 c* N& }' K# U4 ?3 C
  78. ( t& `) P# c; Z# E! w" L
  79.       EndofCon_Flag=0;
    ! D& ^/ l  [5 D' @% t( c( |

  80. 7 a, _/ W! m0 H$ J' n' ^
  81. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol), TX_Timeout);
    5 n( L& h8 d" X9 m: w7 N" y
  82. - T0 i' y9 y9 h
  83.       HAL_GPIO_WritePin( GPIOC,GPIO_PIN_3,GPIO_PIN_RESET);  //for auxiliary test( Z% z9 J" ^1 ^* {

  84. , O  P0 Y, p; ~- ]( g6 V0 }
  85.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol));
    % K% r" [9 R  A# d+ X+ j' f
  86. 5 G8 B0 k; J3 o+ ~7 ~( q
  87. while(Completed==0){}. J4 H" k7 X7 Y; |* i+ Y1 h
  88.       Completed =0;
      X/ j/ h0 l) e/ F$ u1 C- ^

  89. 7 C* G" Q8 C7 w* @

  90. 3 V0 n* b% j& A3 W1 C' z( c- X5 t
  91. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol), TX_Timeout);& C0 z  k6 L8 `( u
  92.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol));
    9 ~* g0 ~6 t" y

  93. ! ^  j3 S/ O% _
  94. while(Completed==0)  {}- U8 c( r3 W/ s/ e' {
  95.       Completed =0;
    3 I9 i/ n9 V* Z, y7 k& a

  96. 7 i. s+ I, F* r4 c+ l

  97. 5 G  E: {' d' |( e
  98. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol), TX_Timeout);
    5 Y! l* S% [$ V) @& g" v, \  o( W
  99.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol));
    3 R! R+ N  V% p1 [6 B+ ~4 Y$ t
  100. $ l2 j9 E9 _+ g+ t" T3 R" R
  101. while(Completed==0){}0 J  G! h8 O+ @! F4 X9 |5 m
  102.       Completed =0;
    ! Q/ ~" \6 G: T4 P

  103. 6 e( y5 W* ^, L, c
  104.       HAL_GPIO_WritePin( GPIOC,GPIO_PIN_3,GPIO_PIN_SET);  //for auxiliary test
    ; b4 P$ Q( U" B/ U3 f
  105. ; ?8 F- |% N2 e" C) T/ S! `
  106.    }   
    4 ]2 d! h: z$ U) F/ y

  107. # @4 k& N2 u& B1 S9 E7 @0 X! c
  108.   }" `3 ]+ e/ b2 T  `% q, }
  109. /* USER CODE END 3 */8 h' S3 ^: X3 G6 w0 Y5 l7 F8 |
  110. }
    8 e/ Y) ^- b  s2 `  z5 w6 P8 y. \
  111. * y" H! v1 Y: d. ^6 v
  112. //ADC EOC 中断回调处理函数; A! P( r4 E) R9 W
  113. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
    ) v+ ?+ q% M8 H! T# _5 u% w+ `
  114. {) |+ n/ l( v/ }7 t! D
  115. ( A- B3 f: b/ n; s6 B
  116.   ADCResult[convCNT]=HAL_ADC_GetValue(&hadc1); //获取转换结果并存入数组; p, C5 z" b# |; Z5 J  e+ g
  117. , s7 h: @3 \2 [; i, r& e' D
  118.   convCNT++;4 K, f9 u# l$ B$ Y1 |  h0 _" Q4 Z

  119. ) ?. y" l8 z" V: J3 I; e3 [
  120. if(convCNT==3)  9 F3 u( N* j% I: d

  121. $ f$ l( q# J" j6 {0 r
  122. {
    . J8 g( V9 j; r* {' a
  123.     convCNT=0;
    0 U& J5 c  B6 z6 \) g$ T5 `$ n2 ^

  124. , r" ^7 C5 F. |# O
  125.     EndofCon_Flag=0xff;
    0 ]7 c( ]5 u5 Q: d0 W+ ?) i

  126. ' t7 z/ c' Y5 E5 K/ [# e. R  y
  127. sprintf(WDVol,"Internal PN Temperature: %5.3f  \r\n",Temperature);  
    , [5 M- G( M1 r
  128. / k' R6 \& J3 S, R/ E
  129. sprintf(InVol,"Internal Reference Volt: %5.3f  \r\n",VRefint);  5 e4 o% `6 z/ D+ e1 R. s
  130. ' `1 w6 l+ E0 Q  q( U# ]( h
  131. sprintf(BatVol,"Current Battery Volt:   %5.3f  \r\n\r\n",VBATVolt);
    6 [( ^9 u( b* w% s* J% h5 c3 H, u" v/ \

  132. 5 I; y7 S7 x  u$ _+ Y( Y0 `
  133. }
    , Z" f  C( S0 B3 L

  134. 6 O% b8 p/ C& e* y! K0 s# |2 L
  135. }
    , f4 O1 k, R$ z- R  ^

  136.   k- H2 T. m8 O$ i6 X0 F
  137. //UART DMA 传输完成中断回调函数
    - V: z, s) S* ^- c6 B

  138. 8 w; |7 }5 [1 I- ?% ~) u0 }0 M
  139. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)! @0 a$ A3 O. Q0 \
  140. {# Y( X- P) c+ b
  141. * ]7 z, o& j- O) x: M
  142.   Completed=0xff;0 ^0 _) O# y% y7 c2 [+ h: P' {" x0 O
  143. }
复制代码
! P/ {+ O7 w+ g$ i' f0 _2 Q
基于上面的配置和测试代码,我们就可以看到最终的结果了。定时器周期性地触发ADC,每得到3个ADC结果就进行数据处理,然后通过UART以DMA方式传输到串口终端。注意VBat电压是测量结果再乘以3得到的。, r0 @( K, L0 A) J9 |

2 _2 O+ j4 ^3 }; ^% J6 x4 `: y! f
微信图片_20240118185941.png
& V' ]. A& r! {$ e& J
+ Z6 S: o" @# ]
微信图片_20240118185938.png
' q( U( W4 W9 V3 `
! i" |  C1 V* q! B
针对上面的应用演示,最后给几点相关应用提醒:  J. a, d8 Y& r3 o- r

5 Z) s6 r; M' L0 E4 m- {, _1、针对温度传感器做测量时,校准时使用的参考电压与实际应用不一致时要做换算,换算成相同参考电压的数据后再做计算。这点前面也提过了。1 n* V) W9 Q) s' z, \: W4 H" @
* U# e' I: x! n& ?
2、使用TIMER的TRGO触发ADC,如果选择类似比较事件、更新事件来触发ADC时,此时ADC对触发极性的选择是无效的,或者说ADC的转换仅依赖于触发事件时间点。如果是选择TIMER的Ocref信号作为触发源,此时ADC的硬件触发的极性选择是有效的,可以是上沿或下沿触发,甚至是双沿触发。这时就得根据需要选择合适的触发沿。【可以进一步阅读本公众号文章《STM32定时器触发ADC的时序话题》】. Y* w& v0 b' J9 j# u8 b
, y( B0 O, T2 [- y1 B: o
3、这里使用UART的DMA传输依次显示三个结果于串口终端,三个启动UART DMA传输的函数须保留适当时间间隔,即等上次传输完成后再启动下一次传输,因为这里每次传输使用的是同一DMA通道。否则没法全部正常输出。比如若把上面3次UART DMA传输的代码改成下面这样子:, X, o( |0 \+ w' O, k* C, U( e

9 X# c: p/ l2 m/ |4 Q1 g+ \
  1. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol));! z/ [, i# |$ J! Z1 W# l
  2. ; j+ n/ ^+ z; g8 O
  3. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol));
    ! }7 \. n5 r) N# }
  4. 5 q" U. V. K0 S* x9 f& m6 b9 f1 a
  5.   HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol))
复制代码

$ g* j2 H0 w$ S; Q; P/ @: I这时输出结果会变成下面的情形,总是只能看到一个结果的输出,即第一次启动的DMA传输结果。/ u1 G8 N& [# F0 o* y
6 r4 c! X: \' m
" E- W. y+ j6 m
! B# p& ~4 m# `: D# M! Z
如果想省事点,直接在相邻2次DMA传输间加上合适延时也行。我这里根据DMA传输完成事件来决定执行下一次发送。在DMA传输完成中断里设置Completed变量为非0值表示当前一轮DMA传输完成。% U3 U* ^5 F: W: u0 p2 R

9 ^: L$ B& }; p% ]/ k4、对于那些在中断和主程序里都会被访问的变量,记得将它们冠以volatile。
7 c& @7 ~! r3 w/ m  h6 R
$ t( h7 a3 ^* d0 Q. \下图的三路波形是我调试时辅助使用的。& H9 ^9 D: F$ U5 d& X2 x% \" i
5 ^# M1 Q  K  q! t$ o2 [
第一路表示计数器的计数变化,显然是单向向上计数模式。% ]$ H/ e8 G# e- Q
% \) Z& x' B2 C' O9 U4 F4 n  W" O
第二路是TIMER1通道1的PWM输出波形。+ F2 O, W( {9 }" e# D) p% I9 U! B

8 ^* ~, t) {, f& V" i第三路是我每次基于DMA实现UART发送时拉高拉低的波形。平常管脚电平为高,在实现DMA传输过程中拉低。
7 o  w( n3 h6 M3 l
: h6 J, B7 d# j" L/ {
微信图片_20240118185918.png

, j  g1 n- Q$ c9 i. S1 }* F6 ]* t, p+ r. j# q; l: c' Y
如有侵权请联系删除6 _4 C$ W/ V* v- t, u9 x
转载自: 茶话MCU
8 V4 T2 S; C. H% |& |- T  j) p' p( J* k+ ?" l' F
, I6 S- Q8 S- q
' t8 s$ P0 k* J. e, {( ^0 x$ E# `
微信图片_20240118185921.png
收藏 评论0 发布时间:2024-1-18 19:00

举报

0个回答

所属标签

相似分享

官网相关资源

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