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

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

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

) [1 A; v! N9 @1 }$ j1 P3 \1 A" z
3 |  n$ U7 F" x2 T

3 m0 G) E/ x  B9 Q3 |- q' W  T+ Q很多STM32芯片里往往内置了专用的ADC通道,比方用来测量Vrefint,VBAT的分压或温度传感器的输出电压信号。不同系列所内置的模拟信号通道可能有差异。这里以STM32G4系列为例,它内置了对应于Vrefint,VBAT的三分之一分压和温度传感器的输出电压的专用模拟通道。; e, y2 I! O) b+ z$ e) Z( i
: o0 x4 F: C9 g& X) ]/ B
微信图片_20240118190028.png

5 G4 w# A' N2 Q4 s; d  T
# `: `8 w6 g- f+ M
微信图片_20240118185948.png

. |9 e% u4 u4 ^( \9 x. ~5 Q
4 |+ Z4 T0 _' t0 ]& o+ v$ E  B
下面的示例就是针对上述3个通道进行ADC,并测量相关电压和片内温度,最终得到3个结果,分别是VRefint电压,VBAT的电压,片内温度。
  h) ^9 t; V: q8 i3 p! h3 d9 r6 T0 [+ r& r% y3 f' y
微信图片_20240118190017.png

9 G1 z: j- c' }

7 B$ y% e& P& [& K; t# J% m  B实现过程是这样的,大体分四步:【有点点麻雀虽小五脏俱全的味道图片】
0 [' ~) W* m7 ^0 [; J$ l1 O2 X' N* S& E. h: l0 _& n
1、TIMER1 更新事件触发ADC的转换;
1 \- K" L  f, ]# l) I; a
( k7 c& X6 m$ M: X' u& F- l* \2、CPU基于EOC中断获取ADC结果;9 T& M0 c) h5 ^6 @
* w6 _- p4 z  {  Z, l6 @
3、对ADC结果进行换算,得到电压值和温度值存放在特定内存位置;; S1 Y* m: e# t3 J

8 w8 o5 Z- r/ I5 r9 t2 }4、基于DMA传输通过UART将最终结果在串口终端显示;$ }" u- C& `+ O. a5 R' J8 o% c
% m/ N" e+ u5 {# m- [$ r: K0 K0 u
其中,TIMER1的CH1输出PWM波形,其更新事件做ADC的转换启动信号。每次的TIMER更新事件触发ADC,3个通道扫描方式转换。这里的UART使用片内LPUART,使用它主要是考虑它跟板载虚拟串口直接相连,没有其它特别用意。5 N% K+ w  R- e$ @/ Y9 G

7 N& |" m+ Z/ T5 e7 @
微信图片_20240118190012.png

! K7 q# z- e) m; u
  q- j3 k2 U; v- k我使用STM32G474Nucleo板来进行下面实验。其中VDD=3.3v,VBAT与VDD相连。另外,ADC模块的参考电压也是3.3v., |& h! Z' x0 d" S/ f6 @4 |

' o4 d+ r" s  Q3 D, \. ^3 Q4 a使用CubeMx图形化工具进行配置,先看TIMER配置:
7 H- N. R5 P! B) [8 O
6 j) ]( [4 I; T( s: N! P: ^
微信图片_20240118190009.png
2 ?6 z! `& S; v( ~* f

& {$ J# \- V0 X+ v再看看ADC的基本配置:# t* s1 c- O9 P: b! b0 Z

" T7 n2 E, o* f, Y9 G- G* E3 d/ a
微信图片_20240118190005.png

6 t4 N3 `8 e6 C% z0 \% o  z$ ~
LPUART的基本配置:8 n4 m( l8 ^) |

: i& p) H/ ]- ?  _/ k/ O3 \2 ]5 H3 r
微信图片_20240118190002.png

5 E* o! p+ R$ J7 r" i8 G5 T" T- W
- E6 b6 T, w6 i: s. g1 O因为要使用ADC中断和UART的DMA传输,记得做ADC的中断响应使能配置和LPUART的DMA配置,这里只使用UART的TX DMA功能。9 l8 ^; P: q5 [; g8 U

; h" f7 b" t8 {
微信图片_20240118185959.png

. {8 b" y, n& P% `

# d! U5 W- _- e; B: A+ |. J使用CubeMx主要配置主要是上面这些。) T* J2 s* q2 V& k5 a7 j5 Z4 |
* D% N0 ^* n1 r. }2 t3 G
在组织用户代码前,先简单介绍下片内温度传感器的内容。该温度传感器针对不同温度有不同电压输出,其输出电压跟温度呈线性关系。ST公司针对片内温度传感器在两个特定温度【30℃和110℃或30℃和130℃】、基于特定参考电压【3v或3.3v,不同系列以数据手册为准】生成了1组校准值并存放于片内特定FLASH位置。! [0 ^8 Y# t/ k

# f3 @# q: W6 b$ b: x# u! `STM32G4系列的校准值是在参考电压为3v,30℃和110℃条件下的两个值,在数据手册里还给出了校准值的片内存放地址。& B% N! u: S, k  n4 H$ L

$ K- a7 `: A) x1 E& U
微信图片_20240118185956.png

2 }, x- h* m3 t+ N& W' D

7 H" Q1 a" S0 K0 ]% C% _针对这个温度传感器的使用,ST公司在参考手册里还给出了计算公式。其实,有无这个公式无所谓,我们不难自行推理出来。【TS_DATA代表某时刻测得的传感器输出电压对应的转换值,TS_CAL1/TS_CAL2分别表示在30℃和110℃条件下基于传感器输出电压的转换值。】! {4 h4 u( H& k9 Q% P; F+ ?+ v
' Q1 O# z5 n. z( _2 ~+ G$ V7 g- w8 w( s5 h
微信图片_20240118185953.png

0 c2 _( }! i- R

% S3 R7 h2 I' t1 _另外,前面提过,ST公司在手册里给出了温度传感器的两个温度下的校准值,但要注意生成校准值的ADC模块所用参考电压跟我们实际应用时AD模块所用的参考基准电压可能不一致。如果不一致,就必须将ADC值换算成同一基准参考电压条件下的数据。目前在ST手册里也特别强调这点了。我把上面一副图再贴一遍于此【见黄色语句提醒】。& M7 H) i. u2 k& c  C* n. A, }
+ h3 M& y6 s( c7 M* P
+ Q. J( F; H/ U

$ w' [7 T3 Q% K: b2 T: h关于这点,我们也不难理解。同一待测信号、同一ADC模块在不同基准参考电压下转换值往往是不一样的。见下面示意图加以理解。: y& z% ^- B# C8 c
6 `  K: {3 D* O! T8 v2 a9 H
微信图片_20240118185944.png
* X- r1 c9 u$ X/ c

; r9 Y) _- |) G4 X. v! V- O$ q完成各项配置后,创建软件工程。添加必需的用户代码:
3 ~: \; S* z0 E4 W( r  s: l7 U0 f4 T6 @1 L& n
  1. #define TX_Timeout (9999)3 z+ R3 x' `9 L& H9 c
  2. & n* j& i6 S; C: X) ]
  3. #define TS_CAL1_ADDR  (0x1FFF75A8)  //用于计算温度传感器数据
    0 V1 P) j% v9 X' O; A
  4. #define TS_CAL2_ADDR  (0x1FFF75CA) //用于计算温度传感器数据
    2 C* U! w; g; ^! Q
  5. 7 ]! K. M& \4 }) i
  6. #define size1 (40)
    : _- x% Q6 c3 B, \) v
  7. " i+ ?( E5 ], ]/ R1 d
  8. char WDVol[size1],BatVol[size1],InVol[size1];$ N( t, X+ b' q9 Y: y9 n$ e3 |
  9. : h% ]  E( d! y9 n  K
  10. uint16_t ts_c30,ts_c110;8 a$ ], W  P* [. x6 `

  11. ( b7 J2 o: O+ L) ?* ^) K7 N/ G
  12. uint16_t ADCResult[3],convCNT;: S9 W# p! c7 I4 x! b) v

  13. ) Z3 K6 ^3 v; k) v- }
  14. volatile  uint32_t Completed,EndofCon_Flag;# K, U0 v5 Q0 f9 f7 c6 k
  15. , r, W% Q1 h* }& z# Q7 j6 ~
  16. float    VBATVolt;//存放BBAT电压最终结果8 [9 g4 q+ f9 G2 |- T% J' l
  17. float    VRefint;  //存放Vrefint电压最终结果) P+ C! r1 a' `: F9 o  b4 q+ S
  18. float    Temperature;//存放片内温度℃最终结果: G. ]6 o/ l# X5 m1 k+ w

  19. ' \7 P9 D- V2 Y2 r
  20. int main(void)8 D- ], w6 T9 y
  21. {- o& K8 z6 e/ C6 w3 d. P* H
  22. /* USER CODE BEGIN 1 */
    & M: w" U. P+ L0 j
  23. " P  U" J' S  j. T
  24. /* USER CODE END 1 */
    : [! G& M. o9 v& `: N/ L

  25. 8 C$ D% E/ u2 ?- g1 n
  26. /* MCU Configuration--------------------------------------------------------*/
    : A: H3 z1 [; a. `: @+ M/ \

  27. 5 e$ a& ]' o9 S% d
  28. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */: m0 y3 J9 \) `' R8 h
  29.   HAL_Init();
    ) s* N% S' B9 F/ b, s

  30. 2 j% q3 f# X* ?6 t  H
  31. /* USER CODE BEGIN Init */
    & c" n+ h1 f$ U" a2 P  L
  32. ) r: r$ W; M7 y0 Y
  33. /* USER CODE END Init */
    ; d+ c* M0 @4 y. o/ A" ]
  34. 0 T! R' E4 r! h1 g7 M2 V  V
  35. /* Configure the system clock */8 t7 }  {4 M# F9 @2 U
  36.   SystemClock_Config();5 K4 c" }2 u: }0 f' S4 w" H

  37. / ^1 `2 p1 B- e% k
  38. /* USER CODE BEGIN SysInit */$ ]* f! B2 G: ^& m* l, N
  39. 9 O6 V$ z3 e2 A8 `/ M5 w7 ?4 g
  40. /* USER CODE END SysInit */
    ! t& o: y6 d0 \  T  a

  41. $ }1 ]: S; J5 A
  42. /* Initialize all configured peripherals */' P- u% q$ y8 T
  43.   MX_GPIO_Init();' e, g2 t+ P$ e
  44.   MX_DMA_Init();
    : g. y- _/ K3 w+ x8 J6 f3 q
  45.   MX_ADC1_Init();6 v- ~2 I& g' s9 D+ \+ ]
  46.   MX_LPUART1_UART_Init();' V% h8 n! j8 U& M3 d
  47.   MX_TIM1_Init();/ o( P4 P! _( V/ G) p/ p/ g
  48. /* USER CODE BEGIN 2 *// f  z0 P/ s  Z2 p( D
  49. 8 Q+ U( |5 d( @
  50.    ts_c30 = *(uint16_t *)(TS_CAL1_ADDR); //读取30℃时的ADC校准值/ o6 O) d, e7 @5 _' c' p

  51. 1 [* H/ K' V. S; a
  52.    ts_c110 =  *(uint16_t *)(TS_CAL2_ADDR);//读取110℃时的ADC校准值
    ; F& N9 X0 U' y$ Q% d

  53. ; Q' I8 n# j* X! b, v( Y6 E5 ?
  54.   HAL_ADCEx_Calibration_Start(&hadc1 , ADC_SINGLE_ENDED);//ADC校准/ X7 k) I# B# o- e" j: ]& x& r  b

  55. - W; x7 R( Y5 q. K& z
  56.   HAL_ADC_Start_IT(&hadc1);//启动ADC并开启转换中断
    3 t4 |% s  Y" Y& u  Q

  57. ' x7 ^* _  t% f; b" f0 f& l
  58.   HAL_TIM_PWM_Start(&htim1,  TIM_CHANNEL_1);$ U9 p; K9 s/ F- N) E0 F

  59. , S" m* ^5 k6 m: _

  60. 4 e7 @  E) `( ~; {- M; _
  61. /* USER CODE END 2 *// I0 ~+ h: e7 r

  62. 2 _+ C, Z1 ?6 r0 a
  63. /* Infinite loop */
    - ~" u6 y' t" J- L
  64. /* USER CODE BEGIN WHILE */
    ) h) _9 b# \: L, T. B
  65. while (1)3 `: X" c4 i0 O% x9 C$ n# L
  66.   {* i, C5 |1 ^0 P& [" D9 X
  67. /* USER CODE END WHILE */
    & ~2 Q7 d) ~0 K! u1 T- K

  68. 1 F  F* R, v2 W
  69. /* USER CODE BEGIN 3 */4 a% M' E  S" T
  70. , T8 y% S) I* f" P& t
  71. if (EndofCon_Flag!=0)
    : r3 w  r5 y9 p
  72.   {  z, i+ |& Y/ [/ Z! A, g: s
  73.     VBATVolt=(ADCResult[0]/4095.)* 3.3 * 3.;  
    " P( V# Y/ X5 o/ p! s9 Z

  74. 7 C. R- `; ~5 C5 n6 U5 ]) i
  75.     VRefint=(ADCResult[1]/4095.) * 3.3;  
    : X: s2 m' V( \4 v

  76. : Z( Y- K4 d/ l/ V3 Y
  77.     Temperature = 30.+ (88.*(ADCResult[2]-((ts_c30/1.1))))/(ts_c110 - ts_c30);/ n3 D: r6 G6 Z4 B7 U

  78. ' C; Q/ w# e$ S0 z
  79.       EndofCon_Flag=0;
    ; h7 p9 S  H, l
  80. . A& {  c: Y' @
  81. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol), TX_Timeout);
    & R+ Q5 j8 a* b7 L: S6 C& R. @& y
  82. & F$ g8 u8 G6 Y4 _" B. Q0 n6 k! _3 @& I
  83.       HAL_GPIO_WritePin( GPIOC,GPIO_PIN_3,GPIO_PIN_RESET);  //for auxiliary test' n+ q0 Z4 }; \' X  q  l2 {
  84. ) j- M/ q. S: {7 s2 f+ o4 U3 y
  85.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol));
    " s4 _0 K+ j) {2 P2 `

  86. 8 ]" C+ D" E& p8 p# N1 q
  87. while(Completed==0){}
    ! M" Y: X: ]. B0 {& I6 Y
  88.       Completed =0;
    # s! m# {: k, f/ }" j  l

  89. 9 G6 A1 d" [3 J+ [. B' }) l

  90. 5 i' G1 G/ U, _" Z8 `+ v* y. G
  91. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol), TX_Timeout);+ }) t$ ]1 \# k# m9 t
  92.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol));
    0 Y5 v3 r, p& S; o  H! S! G

  93. * X/ G) w+ {' C8 d" Q$ L  G: @8 d
  94. while(Completed==0)  {}
    0 B) S" U! Y2 ^3 @
  95.       Completed =0;
    , ^( B5 {* S4 i; x& d4 }  A: r" [
  96. 5 i5 I, C, V/ ~

  97. , G/ t+ @$ a: b
  98. //HAL_UART_Transmit(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol), TX_Timeout);/ G$ Z6 i/ A3 X3 h' d* `
  99.       HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol));
    0 `+ s/ I7 I0 \7 p
  100. 2 m+ V. \$ l9 R% j6 O0 F# N3 }& C
  101. while(Completed==0){}4 Z% G9 q* k. a. i0 s+ N7 t6 m
  102.       Completed =0;. ]0 C8 @+ V6 Y/ e4 r

  103. 0 ~6 y+ Z6 ~; B$ @. m7 m0 E: r9 t
  104.       HAL_GPIO_WritePin( GPIOC,GPIO_PIN_3,GPIO_PIN_SET);  //for auxiliary test
    ! G, J) W* R; T0 D+ D0 U- e

  105. : G9 a( p$ h$ E+ M1 G
  106.    }   
    * @4 O0 L! x: ~5 P! {2 q9 R
  107. : v) {3 d, t) S
  108.   }
    - f9 r: z0 }2 S* r: M% o
  109. /* USER CODE END 3 */* O/ a9 y: i  C
  110. }
    * K. b0 F) m# F" G$ P4 G3 o

  111. * e# a* w% }" {& i
  112. //ADC EOC 中断回调处理函数
    6 h+ f* v5 r: [
  113. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)) Q' I) Q' r; V# c& L7 s, a
  114. {5 l) o. |2 m  B5 y% D" I; k; J
  115. 4 ^: ]) L4 |# f3 [
  116.   ADCResult[convCNT]=HAL_ADC_GetValue(&hadc1); //获取转换结果并存入数组
    - m" [$ E* z+ H) _* w: K
  117. * v$ s& }: Y5 e( X' K# t2 ?. y
  118.   convCNT++;
    " D& }2 m1 d4 B2 @# C

  119. 2 d% X) I6 q2 {2 y$ v- }
  120. if(convCNT==3)  
    ' }) {- Q' C2 i* K$ Z
  121. ! @6 M* W! M4 j6 u" o) C
  122. {9 _1 L4 T1 v. ]! H5 k0 }3 g; A
  123.     convCNT=0;
      T6 n7 s& Q' K
  124. 9 S# P6 p+ i; f4 h+ i1 {
  125.     EndofCon_Flag=0xff;. Y7 [" y- x; o' a6 q

  126. $ u( J3 |2 b* C& v) k
  127. sprintf(WDVol,"Internal PN Temperature: %5.3f  \r\n",Temperature);  4 g% b3 x% R& j+ b. U  q) t& Y
  128. ' q) L( P3 M. S* t
  129. sprintf(InVol,"Internal Reference Volt: %5.3f  \r\n",VRefint);  : q: T/ ?$ J. }! {9 S) K( q0 q$ @
  130. 7 `1 h. x' c/ U& R. |
  131. sprintf(BatVol,"Current Battery Volt:   %5.3f  \r\n\r\n",VBATVolt);' }$ B- n4 W& \: h* B$ z
  132. 5 u* i1 I% X8 u# Q
  133. }
    4 l. p1 z# y# [. [1 X
  134. ( R, `) h9 U) j3 w; i
  135. }
    & C& Q$ q) x3 k+ ?5 D$ K, r

  136. # [. ]8 Q% {6 x5 P
  137. //UART DMA 传输完成中断回调函数
    ; s  D. [: o4 R+ d- m

  138. . d: ]0 w! A+ j1 B* Y3 u
  139. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
    ' n" W6 y$ d0 @& o2 R3 {/ i: {$ \9 [
  140. {3 a! X6 ?, E; D0 D/ F9 N

  141. ( ]( U2 W( w; X" N: J
  142.   Completed=0xff;
    6 J  ~  K: W/ a' v, c2 m
  143. }
复制代码
8 H* U5 t: w  E# p+ q, }
基于上面的配置和测试代码,我们就可以看到最终的结果了。定时器周期性地触发ADC,每得到3个ADC结果就进行数据处理,然后通过UART以DMA方式传输到串口终端。注意VBat电压是测量结果再乘以3得到的。- Q, l% u! ~% S! x+ u
2 Z& O% K( {! Z
微信图片_20240118185941.png

& b* l# m2 h, |3 ~0 v  F2 I# p& g# a7 x# U
微信图片_20240118185938.png
5 Y8 J/ [" ]4 t+ J8 s% H

# k( s9 b  l  t* ~5 _  |5 Z" A( z针对上面的应用演示,最后给几点相关应用提醒:; ~& h. `$ W3 r* K, D1 F" ]
* [' E$ a: l  F
1、针对温度传感器做测量时,校准时使用的参考电压与实际应用不一致时要做换算,换算成相同参考电压的数据后再做计算。这点前面也提过了。9 V/ b1 F0 X$ [2 U

- N& x+ O9 O! q) d: ]2、使用TIMER的TRGO触发ADC,如果选择类似比较事件、更新事件来触发ADC时,此时ADC对触发极性的选择是无效的,或者说ADC的转换仅依赖于触发事件时间点。如果是选择TIMER的Ocref信号作为触发源,此时ADC的硬件触发的极性选择是有效的,可以是上沿或下沿触发,甚至是双沿触发。这时就得根据需要选择合适的触发沿。【可以进一步阅读本公众号文章《STM32定时器触发ADC的时序话题》】
4 q2 y, U; q, ]4 U! f4 P$ Q
$ O5 O- _  {/ r8 S  s0 G7 c8 q2 T) o3、这里使用UART的DMA传输依次显示三个结果于串口终端,三个启动UART DMA传输的函数须保留适当时间间隔,即等上次传输完成后再启动下一次传输,因为这里每次传输使用的是同一DMA通道。否则没法全部正常输出。比如若把上面3次UART DMA传输的代码改成下面这样子:/ q# T/ C* N1 m8 G: Q3 U

  v$ X: e0 G5 i" B3 ]6 W) m( Y
  1. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)WDVol ,sizeof(WDVol));$ r/ r" @/ m2 b% k  u3 r" `
  2. # m# y1 v/ F- B* q
  3. HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)InVol ,sizeof(InVol));
    $ f! h+ N, g+ U9 \! e6 T( Q1 @# w" z

  4. & c* r# o7 ]( @+ I) p0 |
  5.   HAL_UART_Transmit_DMA(&hlpuart1, (uint8_t *)BatVol ,sizeof(BatVol))
复制代码

0 n8 X3 p# |. I6 M' y这时输出结果会变成下面的情形,总是只能看到一个结果的输出,即第一次启动的DMA传输结果。* U8 L# c/ o4 c% |, Z" |) T5 a
4 F$ y; c& C. Q
' @" D" [+ o% x2 n6 ]. Z) p: u
4 D, b9 b& _- E8 \
如果想省事点,直接在相邻2次DMA传输间加上合适延时也行。我这里根据DMA传输完成事件来决定执行下一次发送。在DMA传输完成中断里设置Completed变量为非0值表示当前一轮DMA传输完成。/ R* C& i; x' K# k: A" B

; e; ?5 X, Z  N% s4、对于那些在中断和主程序里都会被访问的变量,记得将它们冠以volatile。, m7 R+ x0 ?2 w8 Y9 i# f: _6 F: }
$ B# y; `- a' E. z+ L
下图的三路波形是我调试时辅助使用的。
0 z' B' O2 K5 b9 N: s+ {' t* S& `8 f  T' B. a$ }
第一路表示计数器的计数变化,显然是单向向上计数模式。$ `9 t2 T; e3 W& M; A( o

7 v0 a" }* G3 k7 a第二路是TIMER1通道1的PWM输出波形。
$ W% O. P* ^: T) C. N
. b$ Z- n2 ?5 q% t9 a第三路是我每次基于DMA实现UART发送时拉高拉低的波形。平常管脚电平为高,在实现DMA传输过程中拉低。
" w7 h$ R" S1 _$ h0 Y4 a
' C, a, w* ?$ y+ C# {7 `. d
微信图片_20240118185918.png

3 q7 t& ^  Q" \8 A( Y! R3 {
+ N) m: s; G' U7 q+ ~% x8 @' L
如有侵权请联系删除
1 J2 @' H4 c9 \5 J- {: F转载自: 茶话MCU
6 r% E' t; d) e% ~8 r7 e; e1 p7 R- J- ~1 ]$ F! a

9 @! T' W. R; p8 s6 X$ C4 ^

$ ]8 F  x9 J7 E0 K: W  G2 g: V8 ?$ C
微信图片_20240118185921.png
收藏 评论0 发布时间:2024-1-18 19:00

举报

0个回答

所属标签

相似分享

官网相关资源

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