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

【经验分享】stm32与HC-SR04超声波传感器测距

[复制链接]
STMCU小助手 发布时间:2022-1-16 18:12
首先,先来看一下这个模块的基本功能和原理。
HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。像智能小车的测距以及转向,或是一些项目中,常常会用到。智能小车测距可以及时发现前方的障碍物,使智能小车可以及时转向,避开障碍物。
注意是5v输入,但是我用stm32 的3.3v输入也是没有问题的。
( I6 Y* q. t7 O1 \0 Z7 L
892371-20160405175004984-1373897222.png

2 @  k! t! X# ]$ T2 ^
二.工作原理
      1.给超声波模块接入电源和地。
& U4 g6 w) W2 m8 j0 P$ Y8 s; [      2.给脉冲触发引脚(trig)输入一个长为20us的高电平方波
      3.输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;(此时应该启动定时器计时)8 Y% b& n3 w4 F# C+ U8 M. i
      4.当超声波返回被模块接收到时,回波引 脚端的电平会由1变为0;(此时应该停止定时器计数),定时器记下的这个时间即为超声波由发射到返回的总时长。, B( d4 _/ E: F& A/ n( d
      5.根据声音在空气中的速度为344米/秒,即可计算出所测的距离。
      要学习和应用传感器,学会看懂传感器的时序图是很关键的,所以我们来看一下HC-SR04的时序触发图。
892371-20160405175234031-1177610742.png    
* J: \( O  \: \8 }; ?' j! i! W; b
    我们来分析一下这个时序图,先由触发信号启动HC-RS04测距模块,也就是说,主机要先发送至少10us的高电平,触发HC-RS04,模块内部发出信号是传感器自动回应的,我们不用去管它。输出回响信号是我们需要关注的。信号输出的高电平就是超声波发出到重新返回接收所用的时间。用定时器,可以把这段时间记录下来,算出距离,别忘了结果要除于2,因为总时间是发送和接收的时间总和。
下面是亲测可用的驱动程序。
芯片型号为stm32f103zet6,超声波测距后通过串口打印到电脑上面。
驱动和测距;
  1. //超声波测距
    : T8 D& J! n  f1 i" t

  2. ! K( x$ M, G$ \- n( d8 t" o
  3. #include "hcsr04.h"' E$ R9 F* c5 a9 Q3 b1 V4 L

  4. ) K1 N1 D# L2 g' T8 L& T1 [
  5. #define HCSR04_PORT     GPIOB
    : w& h( ?1 A5 O" h! f" p
  6. #define HCSR04_CLK      RCC_APB2Periph_GPIOB% x, U$ D0 x  {/ P4 J; y0 j
  7. #define HCSR04_TRIG     GPIO_Pin_5
    + S4 c+ t6 H9 S3 q4 I6 k
  8. #define HCSR04_ECHO     GPIO_Pin_6
    : z% r7 t! A' E1 x& l% g1 c

  9. , v/ |% g, m4 w( U! f# M; s" E' H
  10. #define TRIG_Send  PBout(5)
    & d' b0 B; Y6 R
  11. #define ECHO_Reci  PBin(6). X) |7 q( E3 W5 |# f, B& d

  12. ' ]6 ^1 O4 \* @( N) K8 b
  13. u16 msHcCount = 0;//ms计数3 y8 C1 Y( {6 f( F" c, l$ K

  14. + q. p; ~' W2 o
  15. void Hcsr04Init()
    - K; h) Z$ Z# u/ _; |  @9 \# ~
  16. {  : Z# S$ N1 a8 K. _/ W# Z  d
  17.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;     //生成用于定时器设置的结构体
    . w. @) E, L* o$ j0 E2 `! |
  18.     GPIO_InitTypeDef GPIO_InitStructure;" F8 V$ D6 V/ Y9 B# e, y; Z
  19.     RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
    - R( v/ w! p, S# d+ a4 E# l" d
  20.      
    $ t5 E1 w! g  r; Y9 d, `
  21.         //IO初始化2 I# l) L4 H- M' y
  22.     GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;       //发送电平引脚
    9 Y$ P4 l$ B: o! E8 G1 `9 h" s) y6 I
  23.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    & z' @# E' h! ?
  24.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
    * \* [( q  ]- h7 u
  25.     GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);1 v1 D4 w, A4 `! i$ d
  26.     GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);9 N) f  R$ H& V& d; f
  27.      4 P- X# Z" g% x6 K
  28.     GPIO_InitStructure.GPIO_Pin =   HCSR04_ECHO;     //返回电平引脚
    3 ]8 O8 L- h7 t. [  V3 X
  29.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    5 z6 {9 U! ~, T$ I$ q% b
  30.     GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);  ( r' N- h7 S$ \0 B' H7 L2 L. Y
  31.         GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);   
    * ~9 k$ _1 m" I
  32.      # g/ w% l6 i4 n$ [. k- J% t/ r6 K$ s
  33.             //定时器初始化 使用基本定时器TIM6( d& r3 s  p# T$ Y( {6 L+ |, l
  34.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);   //使能对应RCC时钟% ]1 V# H. L, E3 P
  35.         //配置定时器基础结构体
    / B/ J$ |" |) i+ q. s
  36.         TIM_DeInit(TIM2);1 J: U- ]  f2 j; g3 Q( ~
  37.         TIM_TimeBaseStructure.TIM_Period = (1000-1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到1000为1ms" z' X! w  R% r9 D
  38.         TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值  1M的计数频率 1US计数
    & \9 ~7 a# ]" H) F
  39.         TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
      ^7 s" |& Q  ?! p. q# k$ Y
  40.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    0 }  [& v$ W6 l' u9 f6 Y9 H
  41.         TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位         
    " [8 Z! h/ M9 ]2 o- i
  42.         - j: v6 B8 ?- T  k5 A& p1 i
  43.         TIM_ClearFlag(TIM6, TIM_FLAG_Update);   //清除更新中断,免得一打开中断立即产生中断& L7 J% a9 K  b9 }
  44.         TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);    //打开定时器更新中断7 a6 v8 V( e# V, j
  45.         hcsr04_NVIC();6 [+ g2 k4 }/ H
  46.     TIM_Cmd(TIM6,DISABLE);     , w6 M# m/ J# L: v4 I1 S; N
  47. }2 J$ }* X$ c1 {. m, l0 W9 Z
  48. 8 z6 N$ `9 C+ M' t& A/ [- A- _

  49. 4 n% E# v" P, @( O) e2 q; ?5 l6 {
  50. //tips:static函数的作用域仅限于定义它的源文件内,所以不需要在头文件里声明( e' l7 Q- `+ ^
  51. static void OpenTimerForHc()        //打开定时器8 K- q& @, W9 [
  52. {5 m' x; C6 E2 v* Q" o
  53.         TIM_SetCounter(TIM6,0);//清除计数
    ) Z8 j6 C# L5 t0 J
  54.         msHcCount = 0;
    1 A6 R8 L9 ~* u% k( s' R
  55.         TIM_Cmd(TIM6, ENABLE);  //使能TIMx外设5 z0 _% i( B( w) w( j0 L
  56. }& u# I+ K' P" }6 s$ W' D
  57. & F+ D# q: x! Q( N7 q9 q+ Q
  58. static void CloseTimerForHc()        //关闭定时器; _( k4 J- N2 f& T
  59. {
    , v/ k# B& e% T8 g
  60.         TIM_Cmd(TIM6, DISABLE);  //使能TIMx外设" v( \& ^$ f% Y
  61. }. _: F  e" V; N8 @* b4 s, l: }) |5 h

  62. 2 K# v0 V, v: q, j! v
  63. * W* z2 p- n* {3 w! L, D
  64. //NVIC配置
    ( g/ h3 Y! h1 a. {8 v
  65. void hcsr04_NVIC()3 h( Q4 W; a1 s+ K% n8 M
  66. {
    6 T1 {- B8 G! i
  67.             NVIC_InitTypeDef NVIC_InitStructure;2 N/ s# V; O1 [
  68.             NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    2 b8 t! Q2 |8 y% M1 k5 A
  69.     : s. h6 N6 R7 C" o3 v- P
  70.             NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;             //选择串口1中断
    ) N# c0 c. _. Y. z- J0 X% p
  71.             NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //抢占式中断优先级设置为1) D* h* o1 `+ w# K4 ~
  72.             NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         //响应式中断优先级设置为17 X; ]9 g/ S$ d& `8 H3 t* Z0 ]" Q
  73.             NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //使能中断
    ) ^+ Q9 L$ L, a. C( i( S
  74.             NVIC_Init(&NVIC_InitStructure);! D9 ?& }: s+ c4 B' i/ j" B
  75. }
    # N* ]' b$ `; s" K; B5 G7 p

  76. 3 y# Y& C+ [, ^, l; A
  77. & E$ H% i  H9 X
  78. //定时器6中断服务程序
    ; Z6 d. o2 f- J/ O$ T0 R! H
  79. void TIM6_IRQHandler(void)   //TIM3中断
      X# G# ^% M% N9 x- v- ]0 ?: ^+ `; Q) s
  80. {
    1 T: a4 \: e$ y; Z
  81.         if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否# P) S- R' N; ~6 T& c2 r
  82.         {+ e6 Y, y: m# p. k5 [1 s, ]
  83.                 TIM_ClearITPendingBit(TIM6, TIM_IT_Update  );  //清除TIMx更新中断标志 , r4 [8 M1 B* G6 _8 u1 {" N$ U
  84.                 msHcCount++;7 K& @  N& }8 F% Z/ C; i+ w1 a
  85.         }
      Y' M7 N: q. G  n& V, j0 C
  86. }
    ( o( N) u" Y, \) H/ {" O+ A2 ^
  87. # H& ~/ w- _* P4 G  v5 j. _

  88. : {* Z6 d  o+ O1 v8 O' ?
  89. //获取定时器时间
    - m+ r4 T9 {6 _: ~9 v; X. x& z
  90. u32 GetEchoTimer(void)
    1 C, M: M: s% X( O8 N/ d. X$ P7 q
  91. {9 I' X! H* N4 z8 i8 _$ ]
  92.         u32 t = 0;, ]! ]0 p5 k% K9 [' L
  93.         t = msHcCount*1000;//得到MS
    ) p) S1 s! j0 i' p; {  b9 X+ t
  94.         t += TIM_GetCounter(TIM6);//得到US$ g9 R% e' u3 W) q( B
  95.           TIM6->CNT = 0;  //将TIM2计数寄存器的计数值清零0 B  _2 W8 A+ u
  96.                 Delay_Ms(50);' C: g- B) ?# }, b8 i: M
  97.         return t;$ f- c- O, V% D, x5 b2 W
  98. }& u/ a. |, T' o* r7 y
  99. ; M) J7 Q* _( g" J8 o: T( Y) a3 [
  100. ( w! R* T7 z- {4 T
  101. //一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号
    0 U. _5 e% x, x8 e
  102. //为了消除余震的影响,取五次数据的平均值进行加权滤波。& i5 D* f3 k; e% s9 Z4 |
  103. float Hcsr04GetLength(void )
    2 e; `. ~* k2 S0 h& J' d' t3 j- C
  104. {
    3 Y5 q; @4 j  s5 N8 ]$ B( q
  105.         u32 t = 0;
    # U: J& e" l, ]1 \
  106.         int i = 0;
    , a! R4 q% K! @8 u7 s# J
  107.         float lengthTemp = 0;
    4 z& Q. e- \' r( y6 F/ s% n
  108.         float sum = 0;3 G" k! H9 B5 y  f$ k, Z
  109.         while(i!=5)! A1 Q% v$ f( q* |
  110.         {
    & t% J& ]+ F8 g  I! T6 e' J
  111.         TRIG_Send = 1;      //发送口高电平输出
    6 j+ T3 u+ d2 c3 t
  112.         Delay_Us(20);1 N) n; u3 V" J( o" p2 a1 w+ L
  113.         TRIG_Send = 0;) C( c) b# W& {  l; _1 z7 }6 p
  114.         while(ECHO_Reci == 0);      //等待接收口高电平输出
    ( t) W5 d4 o9 l3 F
  115.             OpenTimerForHc();        //打开定时器
    , K. j1 r0 Z% C" [
  116.             i = i + 1;& [+ e* p% W$ @
  117.             while(ECHO_Reci == 1);
    % j2 x/ d$ I6 N  n! }
  118.             CloseTimerForHc();        //关闭定时器
    7 Q5 h% x, r% }: k, k: W5 e
  119.             t = GetEchoTimer();        //获取时间,分辨率为1US
    , U! x+ A7 m$ L7 \
  120.             lengthTemp = ((float)t/58.0);//cm6 f$ k# S9 D% {4 P+ h& M
  121.             sum = lengthTemp + sum ;
    / U- f% r! L6 a" a: s& L1 ?
  122.         
    ! T2 ]) r) V- r5 m& C6 G$ o2 G4 Y
  123.     }9 G) e& o, U: i- v, u
  124.         lengthTemp = sum/5.0;
    / a$ g3 W- }% y1 L; P! ~
  125.         return lengthTemp;* u" g2 `* l4 C& r, H2 @
  126. }
    8 _. m3 C1 \% B

  127. + q7 q/ a2 L0 c7 A, L" F: t
  128. 6 D% w& o$ x) \5 t0 L1 U
  129. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::' C) Q8 t' W2 W% J2 g$ Q; X
  130. ** 函数名称: Delay_Ms_Ms
    8 P+ N, L7 d( T/ V9 h% t
  131. ** 功能描述: 延时1MS (可通过仿真来判断他的准确度)            & I9 s' C. m- ]4 u
  132. ** 参数描述:time (ms) 注意time<65535
    ! J. @7 f" K( T
  133. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
    1 E% j6 l2 Y$ H  ]6 I
  134. void Delay_Ms(uint16_t time)  //延时函数
    ! y% k1 C) t' B
  135. {
    7 P( m7 @( X  B* \* n; |4 v
  136.     uint16_t i,j;
    " w! O, a* W9 _- z6 |: ^
  137.     for(i=0;i<time;i++)) z$ B; ^+ Z& s( k6 [
  138.           for(j=0;j<10260;j++);' U4 g) R9 v; Z0 y
  139. }
    ; a3 k4 n3 f, `/ I0 \& ]
  140. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    2 ~  N/ ~4 f/ X  W- J
  141. ** 函数名称: Delay_Ms_Us
    ; C: _: c) b! Q- x/ ]
  142. ** 功能描述: 延时1us (可通过仿真来判断他的准确度)
    1 K. s, T, v! A7 W8 U% @; c$ b! N
  143. ** 参数描述:time (us) 注意time<65535                 ! J/ }; b1 v0 M- H4 A! G! h
  144. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
    ( D/ n! v8 X" z8 `  c2 y
  145. void Delay_Us(uint16_t time)  //延时函数; c- P% M* {# V4 u9 `& W; G
  146. {
    5 o2 l2 Q8 C$ T
  147.     uint16_t i,j;) K5 W5 d  `2 P( ?3 G5 p
  148.     for(i=0;i<time;i++)
    # }! j8 U9 Z6 F! M/ R) u% b; P
  149.           for(j=0;j<9;j++);; N4 V. j& N9 e3 F: ]: e7 z, T0 s
  150. }
复制代码
: x4 s! N" O4 r9 i# l& N- I* j
但是关于USART的函数我就不往上写了,这个简单的串口打印大家应该都会写。下面简单贴一下我的主函数吧。
  1. /*0 W1 H2 X/ c3 D! J  Q. e
  2. 教训:实验前一定要检查引脚连接是否正确,万不可搞错,不然又要烧坏芯片!!!!
    ! N- l0 v7 s# @
  3. 3 V2 U) Y! v1 h/ V3 e: S" G
  4. */8 I9 o1 |( X" L# S- B7 o  p, M: a

  5. 8 [( }' G% f, t  O- I3 P+ }
  6. #include "hcsr04.h"$ |% F* w. ?2 g  }
  7. #include "chao_usart.h"
    9 S: x7 j+ _$ r- E  ]
  8. 5 k0 O( Z. L) \' P
  9. int main()- E0 b6 f3 T3 o  i8 ~; D
  10. {  j" T1 I- _3 v% q/ B
  11.    
    ) B* N8 z) Q5 ~! I; Q
  12.         float length;
    , {# C* i$ C  J
  13.         
    9 {" P0 I, D- v1 p/ r
  14.         GPIO_cfg();
    ( l' I( d1 U' S( o6 x- d+ Z
  15.       NVIC_cfg();
    + _% S# n  c0 e' H9 l
  16.         USART_cfg();    - |( n1 F6 n. \; w/ C
  17.         printf("串口初始化成功!\n");
    - Q" \  a! U9 P  Z$ G# B9 l
  18.    
    9 t* ^! V! t( b/ I9 C, n5 Y
  19.         Hcsr04Init();    5 Z4 Y) t( q* M% ~! V( \( J6 F7 b
  20.         printf("超声波初始化成功!\n");//测试程序是否卡在下面两句上面
    * W1 `$ y( t0 A+ g3 Z# c, r* I

  21. : \0 f. F1 O9 H* y- }
  22.         length = Hcsr04GetLength();$ a  C" g) T$ F0 g
  23.         printf("距离为:%.3f\n",length);
    * M; Y1 I$ y$ o+ k
  24.     ! o. i7 v/ @. }5 u
  25.    
    8 L" A- ~7 u# x! L4 r5 A5 D$ h! R
  26. }
复制代码

& f2 D$ _' h: {6 X; k$ a* f, Z) b- |1 Z
实验结果:

( Q! x% c- h0 o  I- x1 C; S* g, Z3 m 1083998-20170608202310075-325550842.png
9 v1 I" k9 m1 I9 b: Y0 m5 r. V* p9 j6 m7 C! h
好了,其实这个模块很简单,但是要是把他用的很好的话还是比较困难的,比如用超声波做一个四轴定高的程序,还是有一定的挑战性的。
写这篇博客的目的不仅仅是介绍这个模块的使用,其实这种使用介绍网上一搜一大把,我只是想纪录一下,我在做这个模块的时候遇到的一些其他的问题。
其中有一个小插曲,就是当吧写好的程序烧进去之后,运行时总是出现每次返回一个同样的比正常值小的多的数据,比如说0.034cm,这明显是一个错误的数据,但是刚开始的时候,不知道为什么
总是这样,多次复位从新上电总是这一个数据。让我很是苦恼。但是幸运的是,在这样的情况中间,他又会有时出现一两个正常的的数据,让你有点摸不着头脑。
上网查了一下才慢慢明白,这种现象叫做“余震”,网上关于余震的解释大致有三种:
  1、探头的余震。即使是分体式的,发射头工作完后还会继续震一会,这是物理效应,也就是余震。这个余震信号也会向外传播。如果你的设计是发射完毕后立刻切换为接收状态(无盲区),那么这个余震波会通过壳体和周围的空气,直接到达接收头、干扰了检测(注:通常的测距设计里,发射头和接收头的距离很近,在这么短的距离里超声波的检测角度是很大的,可达180度)。
* e: h4 j- |3 k; H+ h+ t! i9 Y3 z) g  2、壳体的余震。就像敲钟一样,能量仍来自发射头。发射结束后,壳体的余震会直接传导到接收头,当然这个时间很短,但已形成了干扰。另外,在不同的环境温度下,壳体的硬度和外形会有所变化,其余震有时长、有时短、有时干扰大、有时干扰小,这是设计工业级产品时必须要考虑的问题。0 e" U( ?7 @# v, d  T- W
  3、电路串扰。超声波发射时的瞬间电流很大,例如某种工业级连续测距产品瞬间电流会有15A,通常的产品也能达到1A,瞬间这么大的电流会对电源有一定影响,并干扰接收电路。通过改善电源设计可以缓解这种情况,但在低成本设计中很难根除。所以每次发射完毕,接收电路还需要一段时间稳定工作状态。在此期间,其输出的信号很难使用。
1 h, ^' x- F/ N- O# P' J
消除上述现象的方法之一就是在检测的时候多次循环检测,取平均值,也就是加权平均滤波,一个简单的滤波处理。就是下面这一段:
  1. int i = 0;" w0 u9 T) ^9 k' B' e$ u
  2.         float lengthTemp = 0;
    ; ], N$ |; S: U% {% [
  3.         float sum = 0;( W  o+ d4 n  M6 A/ q
  4.         while(i!=5). V4 @9 d) u/ v6 u8 H' D5 O
  5.         {
    1 E- y- \! b7 V( y: ^, q; ]
  6.         TRIG_Send = 1;      //发送口高电平输出. h3 [$ A$ N' y% d
  7.         Delay_Us(20);* X' R# m7 _, z" ?+ X2 t
  8.         TRIG_Send = 0;8 a6 A2 Z: k1 ]& b5 ]0 X
  9.         while(ECHO_Reci == 0);      //等待接收口高电平输出6 H. B: t& P- ?% c3 g& O8 `
  10.             OpenTimerForHc();        //打开定时器. n  V$ M4 p2 b" H; o% \
  11.             i = i + 1;' G9 Z& j% o" |# u; O7 A) U
  12.             while(ECHO_Reci == 1);- L0 H9 s& V0 }, m5 ]% e* h
  13.             CloseTimerForHc();        //关闭定时器2 N* U, T  r. k2 I0 H; [# r
  14.             t = GetEchoTimer();        //获取时间,分辨率为1US
    ; w1 {5 J5 {  m# R: a1 Q8 e' m
  15.             lengthTemp = ((float)t/58.0);//cm
    & u% z4 T2 D( n# a6 \! d5 ?/ o1 m
  16.             sum = lengthTemp + sum ;3 [' B& H4 V( \  r$ l1 S( `
  17.         3 |& L, \4 I: i" T2 c- s
  18.     }# L' r+ ~- m2 v3 F8 N& T
  19.         lengthTemp = sum/5.0;% X0 [8 K: `& I
  20.         return lengthTemp;
复制代码

( z; g: D$ U/ J/ n: O
: H9 b% ]7 ]9 Y; ~3 N# t! g
加了这个之后,基本上就没有出现余震现象了。
还有一点就是测试程序前一定要检查引脚有没有接错,不管多有把握,也要看一遍,不然很容易出大事的,一个芯片也许就因为你的大意给GG了。切记,这个应该也算我们这个行业的基本素养吧。
( t( Y! n$ q, Y; c+ Z! B2 v1 E
收藏 评论0 发布时间:2022-1-16 18:12

举报

0个回答

所属标签

相似分享

官网相关资源

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