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

获取STM32代码运行时间的技巧

[复制链接]
STMCU-管管 发布时间:2021-6-22 10:02
前言
, Y% x* F  e8 ^6 D, a* Z$ r6 ]: i$ }8 k9 K& J5 H* {

2 P2 h8 B/ C1 F1 r# ]测试代码的运行时间的两种方法:; l  c7 Q" `2 ]! U
) v6 K/ X1 `# B5 O! j

: F2 i! w& j, K* V# p8 u8 ?1、使用单片机内部定时器,在待测程序段的开始启动定时器,在待测程序段的结尾关闭定时器。为了测量的准确性,要进行多次测量,并进行平均取值。
: v4 w& k. e7 d
7 ?6 q+ K/ F# ]# `

) D/ ?! d/ K. Z/ T2 W/ ~2、简便。
( d; _/ f7 Q  |$ ?( h: F' Z7 R8 e$ v; Q
" c) Z$ R  |" n  Z+ o2 o
借助示波器方法的实例# n0 F, W1 w$ \! ?+ c/ T) V
    Delay_us函数使用STM32系统滴答定时器实现:6 X" O, Z# I3 }4 j
  1. #include "systick.h"7 m# C7 n- X% t5 c5 K2 g

  2. 2 c* ^7 a' E7 a7 q% X8 F
  3. /* SystemFrequency / 1000    1ms中断一次
    / g6 U, @7 l/ Y; u) C$ C
  4. * SystemFrequency / 100000     10us中断一次  V5 m2 j6 `$ ?. }; K' b
  5. * SystemFrequency / 1000000 1us中断一次2 q% }* s+ ~( C4 p& h& _4 R8 P
  6. */
    1 a, Z/ u: |$ v1 {5 P8 z
  7. ' ]8 x8 a/ ~6 D3 d" Y- g
  8. #define SYSTICKPERIOD                    0.0000016 D- L' J$ X& W
  9. #define SYSTICKFREQUENCY            (1/SYSTICKPERIOD)% i6 m) i( n: O# O7 w

  10. # [' e! e9 k" S- C. M  Q
  11. /**0 o6 O* K7 e& V& k; J6 f
  12.   * @brief  读取SysTick的状态位COUNTFLAG- d% M% u( r8 v& x# F
  13.   * @param  无
    5 R: F! L: j; A" R
  14.   * @retval The new state of USART_FLAG (SET or RESET).  O4 u! v7 S5 S( G9 G* J. I
  15.   */" T0 ]/ N: _/ {, m, Z" }- q
  16. static FlagStatus SysTick_GetFlagStatus(void)
    ; n3 h9 @3 Z$ S
  17. {% Q8 x2 P- O/ M; [+ Q+ k
  18.     if(SysTick->CTRL&SysTick_CTRL_COUNTFLAG_Msk)
    ! y; J' f4 t4 O4 i
  19.     {
    9 ]$ }7 ?9 n+ p5 C1 \: y! A
  20.         return SET;
    3 `6 ]$ g9 s; S- I3 r7 ]
  21.     }
    6 r. C. h+ u* G6 }, ]
  22.     else5 g- |( Z% j. H7 L
  23.     {! L$ t# A) f' Q" ?% c; I2 N
  24.         return RESET;- P% R  @4 q5 W& b- A/ i
  25.     }
    , b: d* f% R# q0 o' f, j# m
  26. }
    6 o+ e- \8 d% [# C% o* I. S

  27. 5 c$ T- q5 |5 `$ t) j5 J  B$ z
  28. /**
    ; O0 v0 G  S+ s
  29.   * @brief  配置系统滴答定时器 SysTick
      F& `* I6 d) s: h/ A( t  N# \/ d
  30.   * @param  无! j/ b% ~2 u% N6 v) p# `
  31.   * @retval 1 = failed, 0 = successful
    $ x9 Y- g. {$ E+ G8 g0 \
  32.   */
    7 m; B5 K: y2 d: ]' K! n
  33. uint32_t SysTick_Init(void)* l1 {% |4 U! N1 d9 h8 s  G( @
  34. {
    ) k% O- N) f' |
  35.        /* 设置定时周期为1us  */
    # Z5 v3 Q; T4 `: J8 c0 e
  36.     if (SysTick_Config(SystemCoreClock / SYSTICKFREQUENCY))
    , S% a: a  k% g/ X; \: `
  37.     { ; E1 [; m4 h# r
  38.         /* Capture error */ 3 w5 f& n! Y" M( t# P- G5 z% P% N
  39.         return (1);9 O8 K' @" f* n* k$ d" E( ]
  40.     }
    8 ?" a1 m7 |7 _) d4 X

  41. - E  {' W: p; n6 F# }, k7 X
  42.     /* 关闭滴答定时器且禁止中断  */
    ' |, w* |! z/ p! p6 z5 e5 h& G
  43.     SysTick->CTRL &= ~ (SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);                                                  
    4 d- @2 v) `- R# v& y
  44.     return (0);
    7 i' ?) E9 p. C9 ^4 F" B
  45. }# D! t" U' `2 \$ p2 W
  46. 3 R; i& k" C5 D  E# `
  47. /**; {6 c# z+ [8 W6 P- T
  48.   * @brief   us延时程序,10us为一个单位5 A- m- B2 h/ m) w" l2 c6 ~
  49.   * @param  
    , Y- f! D% z- m2 [* W
  50.   *        @arg nTime: Delay_us( 10 ) 则实现的延时为 10 * 1us = 10us. _5 p( @) t7 U; M' p# A: y! v
  51.   * @retval  无$ Z/ [$ Q5 o0 `, Y
  52.   */
    2 s3 a3 q$ z: y
  53. void Delay_us(__IO uint32_t nTime)
    4 ?8 q, f8 i( \5 J& [" [1 o9 k
  54. {     
    7 e9 E  r+ ~$ N7 ~% s/ K, q
  55.     /* 清零计数器并使能滴答定时器 */  
    ) ~" Z) |  G4 l; d5 l$ m
  56.     SysTick->VAL   = 0;  4 h$ u/ f& p7 a6 T9 p: ]6 V; U
  57.     SysTick->CTRL |=  SysTick_CTRL_ENABLE_Msk;     
    ( i7 w+ [3 m  |: n8 r; M6 f

  58. ) H2 G: u. G& C5 s( N! e: }
  59.     for( ; nTime > 0 ; nTime--)
    : I7 K6 e/ ^' s# T4 j
  60.     {
    7 f4 m7 P& B' A$ C" v* Z
  61.      /* 等待一个延时单位的结束 */4 z5 _& k& B( Z) f5 Z& D
  62.      while(SysTick_GetFlagStatus() != SET);
    . k) R( y! c( A+ @+ L
  63.     }
    ( a- ]# P! b; r6 c" {7 s
  64. % t3 s) y. `; J! ?$ ^( F
  65.     /* 关闭滴答定时器 */0 x3 J& S7 B, m2 O! N
  66.     SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;* `+ k& c8 C" P
  67. }
复制代码
检验Delay_us执行时间中用到的GPIO(gpio.h、gpio.c)的配置:+ B! }. f& L8 |3 H6 f5 a# N  b/ N8 n
  1. #ifndef __GPIO_H- A8 Q4 S; X- \# `) _8 W
  2. #define    __GPIO_H% p+ S, ~; q$ J$ {8 j

  3. 4 q8 i( u; R; V! S; Z
  4. #include "stm32f10x.h"/ r  Q9 r' {/ u* p: R) O/ d( x
  5. 7 @* h7 ~3 A: \0 r
  6. #define     LOW          0
    $ X1 O1 H$ V* `" g1 ]8 p9 m( f
  7. #define     HIGH         1) W2 Z# ]2 }; W" v
  8. ( w; V8 |1 d8 D, q7 C
  9. /* 带参宏,可以像内联函数一样使用 */
    7 ^5 `8 Z3 R  e! D! M
  10. #define TX(a)                if (a)    \
    % q# [1 |6 U0 D3 R0 H2 s$ j
  11.                                             GPIO_SetBits(GPIOB,GPIO_Pin_0);\& H5 ~2 c( g) `; M1 W) l
  12.                                         else        \
    # K7 |' _6 N: i2 g: q
  13.                                             GPIO_ResetBits(GPIOB,GPIO_Pin_0)
    # z  `4 f! N" B$ z/ Y+ s. T4 a
  14. void GPIO_Config(void);
    7 k- p  p8 _1 Z! X

  15. ( p; M; [8 b9 D2 @7 C5 d
  16. #endif# A* o: J: f7 ]5 x, f

  17. , c8 F( m( n0 ^6 ~+ E! q0 n
  18. #include "gpio.h"   
      F; S9 M( d: _  n3 F& M

  19. 0 t* a3 t8 c3 C1 x5 w
  20. /**3 Z9 E  h/ G/ H) \: |
  21.   * @brief  初始化GPIO
    6 z5 w% W2 _2 G+ K& ^, h! s9 N+ s
  22.   * @param  无' V( @0 J; r. `6 H$ q9 c' P
  23.   * @retval 无. ~9 l  b) @& M) |9 n
  24.   *// Z' S" U4 L1 T6 ^# I
  25. void GPIO_Config(void)
    6 ?% I" n( z4 @+ V& l$ m5 O/ V
  26. {        + C& F8 {8 L( d6 V: i9 P6 Y' H
  27.         /*定义一个GPIO_InitTypeDef类型的结构体*/- S5 g- h8 O4 C. ?" q
  28.         GPIO_InitTypeDef GPIO_InitStructure;& T9 Q% y& i3 o4 g- z

  29. 8 T+ I; B: u3 k8 Q3 h. b! y( G& f7 i
  30.         /*开启LED的外设时钟*/  o7 y' u8 n" `* c
  31.         RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
    ) k1 ~+ y/ G% j4 D1 ~9 L
  32.                                                            ! L' z: N  K/ h! {* v5 [* j8 F9 v
  33.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;    ) q5 D, C) _  a
  34.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     
    ' V8 i0 L, q% s9 S8 ^
  35.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; : ~9 g" Q- A( R0 H+ h
  36.         GPIO_Init(GPIOB, &GPIO_InitStructure);    . G- i; W% _1 K1 x" e% v" a
  37. }
复制代码
  在main函数中检验Delay_us的执行时间:3 a, p; W% {! ?& ]: ]2 T/ h& e

4 _& b& O; F. x

  1. 3 B6 _' p3 V$ A2 \
  2. #include "systick.h"
    4 [" I; X; H: B
  3. #include "gpio.h"8 |% w' J' }& q7 @- Y9 M8 L
  4. # ]8 p2 l: R1 q
  5. /**% b0 d7 s. ]2 K* f/ p
  6.   * @brief  主函数
    : w+ e* ^) Y& x
  7.   * @param  无  & }0 _- j5 L2 D- W( J1 A: _( z8 l
  8.   * @retval 无
    * e9 V5 L) t& U' `5 Q$ y# l* y
  9.   */' P$ ~# U0 d1 @1 x
  10. int main(void)
    + H4 [- T8 K' e+ Y0 k( b$ d5 e
  11. {    % Q* h% u  z0 d1 ]* Z3 _" Y  \  F
  12.     GPIO_Config();
    3 `/ g3 g( d  U/ \' I( z
  13. 4 \! U( [# H- T; W" f& Y$ W
  14.     /* 配置SysTick定时周期为1us */, A% q5 r  w1 \0 j$ \
  15.     SysTick_Init();$ C; q1 g( F- j

  16. 2 u  V! b+ C- T3 \5 v4 t" D
  17.     for(;;)
    2 c* {( W& L1 `3 H
  18.     {
    ) m! r8 ^1 z. f6 R$ t- j
  19.         TX(HIGH);
    2 N7 E5 P: i$ C  o( i
  20.         Delay_us(1);; u6 Q3 g6 w+ j' @
  21.         TX(LOW);. [( Z. O4 l* D  D6 l8 [8 r& U$ i+ q
  22.         Delay_us(100);3 X! r' B8 Y/ W+ K9 i9 j
  23.     }     
    $ }" Y3 E. m( B% h( D' w
  24. }
复制代码
示波器的观察结果:5 {/ w* x2 P% N7 r
11.png
+ v! c" _0 }. S! S" T% X可见Delay_us(100),执行了大概102us,而Delay_us(1)执行了2.2us。
1 \( y# v4 h) p) g1 W
# I9 {7 B2 U1 t! C8 {更改一下main函数的延时参数:2 O7 o) ~7 @0 c$ M8 ]/ M7 ?
  1. 3 r; J/ U/ Z+ T1 z& p" D" v
  2. int main(void)$ S( R& Y; u3 |4 ^
  3. {    0 d4 q, V2 ~" m+ D. f4 k
  4.     /* LED 端口初始化 */. `  U1 B( l+ j  V( o1 p' d8 g" }
  5.     GPIO_Config();
    6 P1 j3 ^; \* C- U. B3 B3 M$ G) l

  6. 2 W' C+ O$ t. a; n. N% y* y- [  X
  7.     /* 配置SysTick定时周期为1us */. w3 G% y0 W6 a" k
  8.     SysTick_Init();) }8 W) n$ k6 [( @9 x3 n* J6 H

  9. 0 t4 y8 i0 i2 [
  10.     for(;;)
    ; U3 z& I7 k8 J4 `' K
  11.     {: A0 X4 u9 s! W- m- Y* h% h& J( X
  12.         TX(HIGH);
    8 D6 z; R1 k: ~% g5 u
  13.         Delay_us(10);
    & t( k0 S( O/ }! X8 A/ O7 S, Z
  14.         TX(LOW);' f, w: B2 A4 l0 \
  15.         Delay_us(100);" r( O. o+ N! E
  16.     }     
    3 Z/ G' A1 h3 Q/ v2 ~5 T$ A$ v
  17. }
复制代码
示波器的观察结果:
3 a  J# }- V3 \  D8 |7 J1 R

12.png


* `/ F1 F2 {. U) g+ ^- u3 [  y8 l/ D3 l# O
    可见Delay_us(100),执行了大概101us,而Delay_us(10)执行了11.4us。
/ P! B0 m, [4 ~% C; N2 U  [, S; u) M( u8 f+ X, ]3 k) O5 y
    结论:此延时函数基本上还是可靠的。6 L! |8 l# c2 [1 c, E

8 `" T2 u2 S1 u: h5 [! I使用定时器方法的实例7 C8 {( A  u  h) v' h  s  |8 Z
* W) m. p' ~3 o0 m& G8 g+ b
    Delay_us函数使用STM32定时器2实现:% S0 l! f% Z5 Z6 a1 Y

0 f2 S% |" W- O9 D( l
  1. #include "timer.h"
    ( c. I' T4 J( O. |
  2. , E9 e" l6 U% D4 _
  3. /* SystemFrequency / 1000            1ms中断一次& g! h8 G* z( T7 c
  4. * SystemFrequency / 100000     10us中断一次
    1 Q6 S, B1 p. {+ M' E
  5. * SystemFrequency / 1000000         1us中断一次
    # @  m- [' y' L( u& d, H* Y( r
  6. */
    0 z  R$ ]9 i' `' K. P4 P
  7. % R# h' p0 }7 T# h. T% S" H
  8. #define SYSTICKPERIOD                    0.000001! I- \* r/ Q' N  x
  9. #define SYSTICKFREQUENCY            (1/SYSTICKPERIOD)9 }; `0 S: i+ {9 F0 U6 U3 g* V- Y
  10. & _* n- x3 L4 Q$ D
  11. /**  ?3 K7 D5 ?/ \! E% o
  12.   * @brief  定时器2的初始化,,定时周期1uS
    0 U* |! T) m. J, d$ u# ]) q
  13.   * @param  无, i, f; y0 H( N# G
  14.   * @retval 无
      g& }  i$ L( m# E
  15.   */; ]( B- g. A+ J. w
  16. void TIM2_Init(void). ?/ P2 s8 ]4 r
  17. {
    " b: j0 S( F# z
  18.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    $ _' g* |( g+ z" _( U
  19. 1 z# ]& e! L4 K; y. ^
  20.     /*AHB = 72MHz,RCC_CFGR的PPRE1 = 2,所以APB1 = 36MHz,TIM2CLK = APB1*2 = 72MHz */4 c( K. S3 j7 ?
  21.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    ! _# p6 |+ p6 e# e  G4 j
  22.     , y* h3 I" s; h* x
  23.     /* Time base configuration */         : y* b3 N0 l, `+ ?
  24.     TIM_TimeBaseStructure.TIM_Period = SystemCoreClock/SYSTICKFREQUENCY -1;/ ^9 @1 H2 o, [+ ]/ ^
  25.     TIM_TimeBaseStructure.TIM_Prescaler = 0;
    ! _9 A; F7 g2 z8 J, {: H# Z" n
  26.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;; V& x( k" k5 Y; r2 s
  27.     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);/ A  J% C; M: l
  28.    
    , G$ \; z  ]# Q7 w6 V. C( d* W
  29.     TIM_ARRPreloadConfig(TIM2, ENABLE);0 r7 x# ^! ?6 C6 Y) S6 a
  30.     5 C  d# f! V% a/ q
  31.     /* 设置更新请求源只在计数器上溢或下溢时产生中断 */
    8 l$ x; u7 e, [1 l0 J8 x" F
  32.     TIM_UpdateRequestConfig(TIM2,TIM_UpdateSource_Global);
    , f" y" X" Q' ?4 u% F8 Z
  33.     TIM_ClearFlag(TIM2, TIM_FLAG_Update);
    ( e5 V6 q, U: K' T' o. f7 R7 z
  34. }3 p: f0 T5 H) t9 o! i
  35. ' \/ {8 m( f* c& u& c
  36. /**
    7 p& K9 _' U0 T9 K+ h8 ]& k9 f
  37.   * @brief   us延时程序,10us为一个单位: H& x, `; a) m
  38.   * @param  
    " P1 X/ h  E. q2 ]
  39.   *        @arg nTime: Delay_us( 10 ) 则实现的延时为 10 * 1us = 10us) R$ \! a& X; L4 v) l/ Z
  40.   * @retval  无; E' l7 r! Q( r( o/ D+ o9 u/ M1 s
  41.   */- I( A* A7 A5 s8 J6 X. R! n
  42. void Delay_us(__IO uint32_t nTime): ?# c7 {- @8 T" s6 S( V
  43. {     - Y% k1 ^* N$ B2 [
  44.     /* 清零计数器并使能滴答定时器 */  
    8 c0 A. `, Q" _  u
  45.     TIM2->CNT   = 0;  ' U: C* u, H6 G% J
  46.     TIM_Cmd(TIM2, ENABLE);     
    ! ~' I* K7 d! H/ S4 N% I

  47. & p: M. ~9 |) w" R7 d
  48.     for( ; nTime > 0 ; nTime--)
    6 ~# P/ Z+ F8 i. P
  49.     {: K8 J1 u0 m# B% l( Q+ x
  50.      /* 等待一个延时单位的结束 */( J/ ^6 V/ Z7 M- P
  51.      while(TIM_GetFlagStatus(TIM2, TIM_FLAG_Update) != SET);: D7 {$ Q( m6 F
  52.      TIM_ClearFlag(TIM2, TIM_FLAG_Update);
    ' |( b1 o9 C6 Z5 Z& P+ G* p+ F
  53.     }
    $ c& Q" c! w- p# s2 _

  54. 0 |, e, A, ?/ K! M
  55.     TIM_Cmd(TIM2, DISABLE);5 @- v( ^  s2 ^: l' D+ v& W0 l
  56. }
复制代码
  在main函数中检验Delay_us的执行时间:
; [7 G1 [+ Q: S' x) w

  1. 9 i. u: w+ ?8 Y+ N0 P. ^
  2. #include "stm32f10x.h"' l/ W+ O" R& v
  3. #include "Timer_Drive.h"
    7 q3 ~7 S1 @+ G7 {6 f
  4. #include "gpio.h"
    & @6 Q+ m7 M: A( j& |( a& K: H/ n
  5. #include "systick.h"
    $ l' C- [3 L! A

  6. : z. S2 |* n9 B& g( N/ I
  7. TimingVarTypeDef Time;3 Y* L/ Z- a! G$ q3 y
  8. 1 {3 p4 j* r, |  o, l2 _  m
  9. int main(void)
    $ t2 D, Y5 L6 c, D; h8 y, L
  10. {   
    ) y( C& \9 m* E( |* v1 l
  11.     TIM2_Init();    & k6 W$ v+ _& C1 v& i: O
  12.     SysTick_Init();
    4 u6 j! c7 B3 D8 l7 U2 u5 N
  13.     SysTick_Time_Init(&Time);$ w: y2 L" z9 a
  14.    
    + ?5 b( P/ ?* B. r
  15.     for(;;); f9 w/ V- d# [1 ]( ~
  16.     {" A; Y" q$ P7 L, ^) K! c( @" ~
  17.         SysTick_Time_Start();
    5 x. q9 `- k, v) {; _2 ?7 F8 _$ v
  18.         Delay_us(1000);# G# V4 e$ j6 _5 e
  19.         SysTick_Time_Stop();6 R% b7 L, [; r) _* P
  20.     }     
    & ^2 T' {" C5 w2 X- z3 l" e
  21. }
复制代码
怎么去看检测结果呢?用调试的办法,打开调试界面后,将Time变量添加到Watch一栏中。然后全速运行程序,既可以看到Time中保存变量的变化情况,其中TimeWidthAvrage就是最终的结果。* `* Z' A- z& q4 O
13.png   S. N3 ~+ f, ?% o
    可以看到TimeWidthAvrage的值等于0x119B8,十进制数对应72120,滴答定时器的一个滴答为1/72M(s),所以Delay_us(1000)的执行时间就是72120*1/72M (s) = 0.001001s,也就是1ms。验证成功。$ B) j; D: I6 y1 [

' \! S6 H  j& x+ r! ]    备注:定时器方法输出检测结果有待改善,你可以把得到的TimeWidthAvrage转换成时间(以us、ms、s)为单位,然后通过串口打印出来,不过这部分工作对于经常使用调试的人员来说也可有可无。. `* }( ^$ p9 N3 v) g2 {
1 P) K) m- o; u$ Z8 z
两种方法对比
' i8 \9 e% ~* r% M2 m3 i# m5 _6 V软件测试方法
) s. k3 _6 O1 F9 s
  `  A4 _$ D/ ^3 p$ \    操作起来复杂,由于在原代码基础上增加了测试代码,可能会影响到原代码的工作,测试可靠性相对较低。由于使用32位的变量保存systick的计数次数,计时的最大长度可以达到2^32/72M = 59.65 s。7 I) W  x* r9 B; E% E2 [9 s9 I3 i# B

' J4 h- i3 A$ x2 b示波器方法+ l+ e, M( f6 S0 I: |; g* J* M) Q( o/ N

" b8 y" Z0 G$ D" Q( Z. v( k4 S    操作简单,在原代码基础上几乎没有增加代码,测试可靠性很高。由于示波器的显示能力有限,超过1s以上的程序段,计时效果不是很理想。但是,通常的单片机程序实时性要求很高,一般不会出现程序段时间超过秒级的情况。
# n) i7 v2 {- b  @1 p  p
+ b" t# V# W0 P* d/ T2 b1 q9 R, o# x9 a8 C
1 w( w; K, J' S6 Z

/ h8 S1 k  [; K  n/ G
4 u1 ~, f- m1 C
; d- C% M8 t! w& f6 e
4 e6 u+ z( v1 G+ K) v
+ E& M' V5 ~# S% S# \% P* u' t0 b/ x" X) i7 k. x% J
. z6 h; F7 S, W* ?

4 Z+ h- {/ g6 p% f
5 l" f% _# k9 R4 g9 y5 A
收藏 评论0 发布时间:2021-6-22 10:02

举报

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