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

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

[复制链接]
攻城狮Melo 发布时间:2024-1-18 19:00
微信图片_20240118190031.png
5 c8 m: Z0 W  j5 t
8 F' g6 r; w" ~9 G: I8 ~6 ?7 e

5 o( Y+ V7 @/ X9 i& @很多STM32芯片里往往内置了专用的ADC通道,比方用来测量Vrefint,VBAT的分压或温度传感器的输出电压信号。不同系列所内置的模拟信号通道可能有差异。这里以STM32G4系列为例,它内置了对应于Vrefint,VBAT的三分之一分压和温度传感器的输出电压的专用模拟通道。
- W9 H5 a1 ~& I8 ~# I1 f2 T' f3 ]  g0 A4 L1 G8 v# O
微信图片_20240118190028.png
4 @& p; J( F4 v7 l9 u+ K& o* N

5 j& u8 O7 c% N* s' P+ @* T
微信图片_20240118185948.png
) O5 K  t# F" _% P2 L/ B

1 l' p$ P' h$ n  @) I: J) l下面的示例就是针对上述3个通道进行ADC,并测量相关电压和片内温度,最终得到3个结果,分别是VRefint电压,VBAT的电压,片内温度。
! E' h# }  z7 Q
- [* h( \# d; d
微信图片_20240118190017.png
; x$ `" `  n! k; f4 p/ M1 o

: ~. l8 T6 C1 T8 `" P3 z1 Q实现过程是这样的,大体分四步:【有点点麻雀虽小五脏俱全的味道图片】  a  z# W" n: ^1 I$ d' U; J3 R6 E

) Y! R, U6 F$ U7 c2 c' t1、TIMER1 更新事件触发ADC的转换;; ^5 [! i4 a) c2 k2 {$ l, l# d

) H6 {: d* j2 f9 x2、CPU基于EOC中断获取ADC结果;
4 J0 _0 [- F' e1 \% g% `
2 S8 T3 I( [1 k' u- a4 |3、对ADC结果进行换算,得到电压值和温度值存放在特定内存位置;
! s  N1 O0 a7 @( {  m$ y$ I2 M: F# @) L7 z2 \! _" F
4、基于DMA传输通过UART将最终结果在串口终端显示;
# g3 Z5 Z( C- ?$ ^+ W
+ D/ S5 T8 n, i1 R3 E0 R" `: I其中,TIMER1的CH1输出PWM波形,其更新事件做ADC的转换启动信号。每次的TIMER更新事件触发ADC,3个通道扫描方式转换。这里的UART使用片内LPUART,使用它主要是考虑它跟板载虚拟串口直接相连,没有其它特别用意。
" S; G% i+ W. X/ d" r) Z- D  e& X: @) l# X
微信图片_20240118190012.png
6 ?. x4 o1 W: w& a# N8 @( B5 n

/ D; L; K. {+ }# K5 ^我使用STM32G474Nucleo板来进行下面实验。其中VDD=3.3v,VBAT与VDD相连。另外,ADC模块的参考电压也是3.3v.
5 l# a* v' O6 M! E% j/ N* c1 T/ C0 T+ \5 r6 y9 K
使用CubeMx图形化工具进行配置,先看TIMER配置:* {5 X' e  e% m1 g3 m# _
/ M' C$ ^1 h2 l2 W. p5 y
微信图片_20240118190009.png
8 M8 h  z1 ^- n) y1 k
1 O. @) u: V2 q1 o0 h8 s( ?, X
再看看ADC的基本配置:- d  v$ Z+ u- ?6 v6 P/ Q" c$ l/ {
/ z5 H. h2 t5 b$ C
微信图片_20240118190005.png

8 z9 [5 A' o4 N3 P0 B- Y7 X! `* z4 ~; l
LPUART的基本配置:
# N* Y& z. U. e! M* L( g8 P7 k+ r- r7 i  a. W3 g
微信图片_20240118190002.png
- u' q- O2 B& M3 o
* ^! {- R3 ^0 Z  U# p1 g! d
因为要使用ADC中断和UART的DMA传输,记得做ADC的中断响应使能配置和LPUART的DMA配置,这里只使用UART的TX DMA功能。  S- F0 P: g" ?* F* I8 r/ p
' t/ G8 E" C: K0 P/ f/ u
微信图片_20240118185959.png
" J) N8 l4 i) e' Z+ y
' F6 n- M' I4 ^
使用CubeMx主要配置主要是上面这些。# |6 p/ {' R0 l  G0 ^) C

, @4 q; I3 T4 }0 I% E在组织用户代码前,先简单介绍下片内温度传感器的内容。该温度传感器针对不同温度有不同电压输出,其输出电压跟温度呈线性关系。ST公司针对片内温度传感器在两个特定温度【30℃和110℃或30℃和130℃】、基于特定参考电压【3v或3.3v,不同系列以数据手册为准】生成了1组校准值并存放于片内特定FLASH位置。6 z( a* ~( U, }) o

. P  \' l1 [' {& e9 T( {* O# ^STM32G4系列的校准值是在参考电压为3v,30℃和110℃条件下的两个值,在数据手册里还给出了校准值的片内存放地址。
6 Q. ^, p9 X6 R+ E0 q7 H  D3 V9 u/ J
1 l4 T. j8 e8 _# l7 u" u, A
微信图片_20240118185956.png

7 @; ?, z: {" Q5 k9 }  y

+ ], v6 C% k1 m1 ?( ~. E( R/ l针对这个温度传感器的使用,ST公司在参考手册里还给出了计算公式。其实,有无这个公式无所谓,我们不难自行推理出来。【TS_DATA代表某时刻测得的传感器输出电压对应的转换值,TS_CAL1/TS_CAL2分别表示在30℃和110℃条件下基于传感器输出电压的转换值。】
  w! y! U3 E( q9 S( n" Q/ ~9 l' P5 ~0 T6 F5 B
微信图片_20240118185953.png

; B, F! Q" E" L8 L
' l7 @) l8 H% `( Y# ^' X+ `
另外,前面提过,ST公司在手册里给出了温度传感器的两个温度下的校准值,但要注意生成校准值的ADC模块所用参考电压跟我们实际应用时AD模块所用的参考基准电压可能不一致。如果不一致,就必须将ADC值换算成同一基准参考电压条件下的数据。目前在ST手册里也特别强调这点了。我把上面一副图再贴一遍于此【见黄色语句提醒】。: G. C( h, `4 {9 M
3 W6 E5 f9 c- x9 e, L# @
1 o  Q) U% D' L- e
+ R) P% B& X# E1 j8 d
关于这点,我们也不难理解。同一待测信号、同一ADC模块在不同基准参考电压下转换值往往是不一样的。见下面示意图加以理解。' |# }3 |! D8 l0 [

5 S4 P: J8 ~3 _  ?+ O0 G
微信图片_20240118185944.png

. E& ?9 h! H7 w. `2 j% J5 Q
$ [8 R) X- e6 D; e
完成各项配置后,创建软件工程。添加必需的用户代码:6 N& [/ N3 i5 }9 Y5 p& f4 w( U
$ o* q) x% X; o5 D  s9 e6 S
  1. #define TX_Timeout (9999)8 t6 l4 }' t# v; ]
  2. 0 t6 y1 {- r/ `/ K# w4 H4 x
  3. #define TS_CAL1_ADDR  (0x1FFF75A8)  //用于计算温度传感器数据% ?) i6 H, Z* W1 o4 z
  4. #define TS_CAL2_ADDR  (0x1FFF75CA) //用于计算温度传感器数据
    : `; z; d& |- T9 G$ K: [
  5. ' P0 ?; M3 n: x7 _. v5 B5 W
  6. #define size1 (40)
    # ^/ R2 t. h% z

  7. $ n& |+ T. ~& C8 i
  8. char WDVol[size1],BatVol[size1],InVol[size1];
    + C# T! j9 Z* x( o: ]
  9. " k0 j0 `* p! X) u# O
  10. uint16_t ts_c30,ts_c110;
    ' H* R2 n5 N7 @  n/ e$ o0 [# Z
  11. ' |7 y' [3 i& D: L
  12. uint16_t ADCResult[3],convCNT;0 G! ]$ `. P! ?9 H) @8 x4 g

  13. " C3 p1 A( z( A/ L6 {$ i0 b
  14. volatile  uint32_t Completed,EndofCon_Flag;  Y  l- i: d& n" q
  15. 8 E* h9 U+ r( N
  16. float    VBATVolt;//存放BBAT电压最终结果/ l# N# y# s; g$ j! `* A
  17. float    VRefint;  //存放Vrefint电压最终结果7 q2 p0 O. P6 r9 I! Y
  18. float    Temperature;//存放片内温度℃最终结果) ^- L( ^3 l! l* _) \  s
  19. ! {2 _: S1 S+ v' q( v
  20. int main(void)
    6 W6 D+ N. S9 x% l! d, K. O
  21. {
    $ c1 b/ r: |% z
  22. /* USER CODE BEGIN 1 */1 P! }9 m8 Q& y$ Z) K

  23. ( _% ]4 w: K5 a1 K
  24. /* USER CODE END 1 */( a3 ?% f+ q* Y
  25. 9 L6 @! O( O9 a/ e
  26. /* MCU Configuration--------------------------------------------------------*/3 L6 P: i% H# k4 {+ d. p
  27. 0 c8 s  m* E  d5 T- @+ J2 q
  28. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */2 M! ^; T! }4 p2 h
  29.   HAL_Init();
    5 ]* P3 G1 J+ n% x7 j5 P! E; S

  30. 9 h, `- h& J, Q6 a  w% d! V" r
  31. /* USER CODE BEGIN Init */
    & h: \3 u: p% i9 ]& S1 K

  32. 5 w( y7 v, S1 Y! E6 Z: @; t& R
  33. /* USER CODE END Init */
    : R: {' x5 L& |2 L
  34. 2 M- O) u9 {! j  `: o( z4 W
  35. /* Configure the system clock */
    0 r/ S; @4 |9 E0 k, N3 H5 W0 r
  36.   SystemClock_Config();7 R) Z" D) U+ Y: W$ r
  37. " j! Q* @0 |0 G: v
  38. /* USER CODE BEGIN SysInit */
      }# B+ l/ i# ~3 p( J$ ~' \0 _
  39. - X" I$ O4 W; o* b" R  k6 _- X% g
  40. /* USER CODE END SysInit */* R  P# _5 j' V" g' I

  41. ; I& t$ V; w( {; p' K0 m2 W1 e
  42. /* Initialize all configured peripherals */
    ( I, K% v$ x6 @+ i3 n
  43.   MX_GPIO_Init();; \/ U) R! ^9 B0 C4 ~+ S
  44.   MX_DMA_Init();
    0 G5 R2 W7 Q: ?' ^7 V+ [. \' n
  45.   MX_ADC1_Init();
    # \3 e) {9 H7 z5 F0 \. q
  46.   MX_LPUART1_UART_Init();8 g3 K; U/ f9 I) {  ]2 o2 Z  \0 H
  47.   MX_TIM1_Init();/ _. c0 r$ |  x& m. P* s
  48. /* USER CODE BEGIN 2 */
    ; }( J! E2 [6 g- k" e4 v& j

  49. $ q6 z: ?. S% p! C. d0 o6 N, Q
  50.    ts_c30 = *(uint16_t *)(TS_CAL1_ADDR); //读取30℃时的ADC校准值
      `+ s; ]& A* e0 p0 w' ^4 w( }
  51. % p0 X% r/ Z0 l, G) m; D4 P. ^
  52.    ts_c110 =  *(uint16_t *)(TS_CAL2_ADDR);//读取110℃时的ADC校准值
    2 _$ e2 ?* i  c' @( ~* ?

  53. $ g9 q  t2 y2 J& j0 a/ Z9 \9 l
  54.   HAL_ADCEx_Calibration_Start(&hadc1 , ADC_SINGLE_ENDED);//ADC校准7 L  d" Z: @2 V, B7 x6 i) y4 U

  55. 3 ?2 p$ x7 o5 l- c
  56.   HAL_ADC_Start_IT(&hadc1);//启动ADC并开启转换中断
    ! I/ |! b! X/ B% z
  57. + t" X* C% z% B
  58.   HAL_TIM_PWM_Start(&htim1,  TIM_CHANNEL_1);
    9 g* ]# w5 B: _  B' |

  59. ! v( q9 v2 D" u4 @1 U
  60. ) O& S8 x( l; J. u: J% t; v
  61. /* USER CODE END 2 */& H9 T' v7 M4 g+ d1 K

  62. ( P7 N- |2 L5 g: e
  63. /* Infinite loop */6 o2 ^5 F0 z8 ~, Y3 Y8 U8 V
  64. /* USER CODE BEGIN WHILE */
    ) C) O2 Z  d3 k5 ~' w5 P  T
  65. while (1)
    7 n( d4 F- T& u$ ~% V# ~
  66.   {
    & i3 ^! I' E: E2 K: \0 U9 `. b
  67. /* USER CODE END WHILE */6 K( {) H( ^1 O* ~, F! z. P8 ^
  68. 9 S* Q$ x( p( N+ t% c4 V; r" e
  69. /* USER CODE BEGIN 3 */1 L5 s  `; d4 w( m; D) W
  70. : g; r4 l- X' T7 W2 `
  71. if (EndofCon_Flag!=0), M: n+ b/ `( p9 T; z
  72.   {
    + y# ?# d0 r- w3 s" E3 [
  73.     VBATVolt=(ADCResult[0]/4095.)* 3.3 * 3.;    m! R$ y* G6 O4 W
  74. & S6 k* n- ]$ Z. `( _
  75.     VRefint=(ADCResult[1]/4095.) * 3.3;  
    5 t5 Q5 C  y/ O8 S2 H0 ?) K' r  ^2 a
  76. 1 g5 V5 y- a  M2 Z
  77.     Temperature = 30.+ (88.*(ADCResult[2]-((ts_c30/1.1))))/(ts_c110 - ts_c30);
    # @7 ?( Z, L5 h7 Z5 a/ }' e! a' [

  78. . ]* B+ a! v, Q) }+ W2 q
  79.       EndofCon_Flag=0;
    2 n) Q* p( f0 o+ X' ^( W

  80. / n' l* T* c4 m% c/ w
  81. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol), TX_Timeout);
    - e' I9 M! u6 ?) n" M

  82. 1 K$ f2 B7 X6 w# O
  83.       HAL_GPIO_WritePin( GPIOC,GPIO_PIN_3,GPIO_PIN_RESET);  //for auxiliary test( ^9 N; f! ?3 m3 x+ }

  84. % f) r6 |' V- \! ^: E7 o
  85.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol));0 r8 Q; v" A! G/ P: S
  86. - f5 {& d* S& N  X
  87. while(Completed==0){}
    3 p/ a! G  C8 ~" \
  88.       Completed =0;
    3 h6 v4 l; w  h( j) c# [
  89. # S5 B8 g1 e: D. p& }6 B( R. {
  90. 5 v! t( S: `9 b7 q( H
  91. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol), TX_Timeout);
    + I* k% {8 h' F, B
  92.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol));
    0 }4 B5 C' g" \+ ~
  93. 7 s# z7 U9 ~( h' I
  94. while(Completed==0)  {}1 K8 D6 d0 Q+ k* [5 u
  95.       Completed =0;1 ?; j8 T" {- F5 i8 c& k  n* @) v8 U
  96. 7 g* M1 d9 Z) m' C0 X1 I

  97. 2 ^) N- O9 c5 E2 K# s/ ^7 M3 v
  98. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol), TX_Timeout);
      P: n6 A; ^' x2 J& X/ l
  99.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol));
    * }( b7 P. b9 w# [0 Y
  100. ) N- X" D6 S0 c+ ]$ D4 q9 L
  101. while(Completed==0){}
    ; E: q% _4 n' f3 P% N
  102.       Completed =0;
    ) H( A' U" D0 J: R/ Z" C
  103. 9 H% M  y; V8 M2 K) S
  104.       HAL_GPIO_WritePin( GPIOC,GPIO_PIN_3,GPIO_PIN_SET);  //for auxiliary test
    ' \; j# ]' i8 r4 q) V8 p

  105. 4 h3 g! M* R. I0 p$ t
  106.    }   
    ) H- Q5 T% Z; h8 K0 v5 d, \
  107. " l: v+ e* _0 }$ H! I$ _
  108.   }
    7 u5 e7 S. ~& J& ?% i( x
  109. /* USER CODE END 3 */
    . B7 l5 [" y  b/ n7 P
  110. }
    " I! R- q- N* j+ ]( ^
  111. 9 b3 f0 F, f1 Y! ~
  112. //ADC EOC 中断回调处理函数1 j1 G- n8 {' V6 l- @) ~& x
  113. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
    + g9 ~- O8 Q1 g; l( k# y( t) k
  114. {
      V0 B5 R, p( p. |
  115. 2 a5 P# s% Q' Z9 `9 l* X, Z/ q: D7 v+ F
  116.   ADCResult[convCNT]=HAL_ADC_GetValue(&hadc1); //获取转换结果并存入数组2 w1 k5 @( Q9 w# A
  117. & @, ^- [3 J: j
  118.   convCNT++;5 d, q+ H. Y2 I8 u
  119. ! C3 p0 L9 U# y
  120. if(convCNT==3)  ) `! U( v+ \, n& X7 S

  121. & C- d, m/ j! e7 w
  122. {+ x! c2 N' {* \) C, R
  123.     convCNT=0;4 g9 l3 i, K! ]& {! S. d/ ]8 M% V1 p

  124. # q8 a+ y  Y% j( o; U* s8 Y, b
  125.     EndofCon_Flag=0xff;
    ) D: s  r/ \+ K! C8 B6 R; `

  126. 4 M. z5 X' H4 D6 f
  127. sprintf(WDVol,"Internal PN Temperature: %5.3f  \r\n",Temperature);  
    % M+ k# N4 i* O, m6 A" U" u! K

  128. 4 c) ~1 }) s0 o! W( |, _6 J8 T
  129. sprintf(InVol,"Internal Reference Volt: %5.3f  \r\n",VRefint);  
    : D, K8 P0 M0 M  Q; A0 {2 d' y
  130. * m0 ^' X# L" r% ?
  131. sprintf(BatVol,"Current Battery Volt:   %5.3f  \r\n\r\n",VBATVolt);
    " X5 \8 o2 u, n( @- w0 t

  132. $ s- g/ i  z5 F, i
  133. }! m1 E5 `8 r( \0 b

  134. 1 Q  _+ a$ f% y' S; N% _
  135. }
    4 E  K& H9 R# b' f+ }- i8 L3 D$ y

  136. - x3 Q$ M+ [3 v
  137. //UART DMA 传输完成中断回调函数
    ! q& x& O' d, y/ L
  138. * z% E8 w* y- X5 m. I% ^! d/ ?
  139. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); K  T. D& h  A: K' K
  140. {
    3 }9 Y) Z2 A& p# w5 U

  141. ! s3 W$ y( ?% }) ?: \- V
  142.   Completed=0xff;9 u3 E( d1 Y  E+ X8 y& h
  143. }
复制代码

8 p5 R) \! Y* u: Y% e# O! ]/ r基于上面的配置和测试代码,我们就可以看到最终的结果了。定时器周期性地触发ADC,每得到3个ADC结果就进行数据处理,然后通过UART以DMA方式传输到串口终端。注意VBat电压是测量结果再乘以3得到的。
/ q. u: _& T- K2 W% B% M! q
4 r; \$ r- d/ s8 F: ~
微信图片_20240118185941.png

& R' N7 @1 @5 `* f2 N
3 e- S) W* o* J& X$ ]* f
微信图片_20240118185938.png
+ V5 n& A  D5 H" g  H
/ z  b0 D+ n! m# T1 r) T- P: v
针对上面的应用演示,最后给几点相关应用提醒:
% }4 U+ f* r1 P- G, W
: s1 Q1 ~! d7 U3 ?, C* v/ V; n1、针对温度传感器做测量时,校准时使用的参考电压与实际应用不一致时要做换算,换算成相同参考电压的数据后再做计算。这点前面也提过了。4 @5 J" x7 g' T/ V# @  |2 ~

3 p0 v4 y: [- o8 u$ N6 U2、使用TIMER的TRGO触发ADC,如果选择类似比较事件、更新事件来触发ADC时,此时ADC对触发极性的选择是无效的,或者说ADC的转换仅依赖于触发事件时间点。如果是选择TIMER的Ocref信号作为触发源,此时ADC的硬件触发的极性选择是有效的,可以是上沿或下沿触发,甚至是双沿触发。这时就得根据需要选择合适的触发沿。【可以进一步阅读本公众号文章《STM32定时器触发ADC的时序话题》】: A! Z) k3 O! x$ ?1 n

  J% ^/ W- g0 r1 M$ o3、这里使用UART的DMA传输依次显示三个结果于串口终端,三个启动UART DMA传输的函数须保留适当时间间隔,即等上次传输完成后再启动下一次传输,因为这里每次传输使用的是同一DMA通道。否则没法全部正常输出。比如若把上面3次UART DMA传输的代码改成下面这样子:/ A  p$ P! T) E

  g- m" C! ?- v9 [
  1. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol));
    & @: W/ M  b# \8 Q
  2. ( f5 I6 x- d) _2 \) K- P) e
  3. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol));
    2 Q/ q( T8 w9 p, i0 O1 c$ T
  4. " F: _  D! p. R* D5 o
  5.   HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol))
复制代码

% j( e5 T! J$ x# W$ U, Z4 R这时输出结果会变成下面的情形,总是只能看到一个结果的输出,即第一次启动的DMA传输结果。% F6 {3 _1 e5 G. p# l' Y

: a5 _. ~) O9 x; t8 m
5 E$ y. p5 s6 U8 U8 m

5 L# g, ?; n& x  s  e6 _$ E如果想省事点,直接在相邻2次DMA传输间加上合适延时也行。我这里根据DMA传输完成事件来决定执行下一次发送。在DMA传输完成中断里设置Completed变量为非0值表示当前一轮DMA传输完成。3 {) o6 f' @9 k) a

* q2 M% w! `! P4、对于那些在中断和主程序里都会被访问的变量,记得将它们冠以volatile。
( L: _0 ^+ q5 P/ I+ p$ _0 m2 w
& O7 s7 l  A; k9 y0 x下图的三路波形是我调试时辅助使用的。5 t& [) M5 A1 e7 f7 a  D4 S1 _

  q- [/ U2 ~& e! {0 t( p第一路表示计数器的计数变化,显然是单向向上计数模式。
. u5 N8 T6 M, K
: B( J% t0 a( K: K4 P第二路是TIMER1通道1的PWM输出波形。
9 Q" X& S3 G5 @& [/ k: Q' z) u" d, a  y0 {6 @% W9 }" u
第三路是我每次基于DMA实现UART发送时拉高拉低的波形。平常管脚电平为高,在实现DMA传输过程中拉低。. |, a5 A1 R, B& m8 R& G1 E
$ a/ ^, I7 r7 K3 }! h
微信图片_20240118185918.png

4 d% ^3 A( D  k( Q) t: s, P, H* V8 V
如有侵权请联系删除
/ l8 _: {" y' A& ^" R转载自: 茶话MCU
+ s0 \5 K2 \. U$ Q+ [
1 i& v& N6 z2 ^
$ T( q8 M7 V/ G
- r; b) H% k  M1 t$ y7 }
微信图片_20240118185921.png
收藏 评论0 发布时间:2024-1-18 19:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版