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

【经验分享】stm32f1系列单片机实战应用

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
测量运动自行车速度,上传给上位机软件,处理VR视频播放。正好公司有现成的stm32f1系列单片机开发板,所以我就想到了使用它来实现这个小功能。8 k) K; Z' C% ?6 q+ _# ~3 T( [
+ M! X" x3 e6 r
1. 硬件配置:
; B. J; Q3 v) Q! t* `7 k
  }+ B( I/ C" S4 x! r# }5 _2 Q" N1.1. 运动自行车;0 w! S$ }9 g) b) R. t- s) W
  H7 w. j# b6 ~' n# O6 C* |
20180409144730202.png
' s" A2 G: l0 b1 s, z5 a1 f, I% A! ?
8 A: b9 f9 o6 u
1.2. 磁感应开关与专用磁铁;    1 `( V" b. i. w) o; X
5 ]% {, W; T  W6 @( O9 Z
20180409144808136.png 20180409144818159.png

( o6 g1 U8 m- ]  P3 x* ?3 ~6 H; p  p; k6 q% w; }
1.3. 基于Stm32f103zet6芯片的开发板(七星虫),如下图;" c2 c% h! j7 M

% Q5 w4 `; y8 t# J
20180409144832248.png
* x, P; g) i& P- W
% [, {" c8 I1 }6 Q  E7 W
1.4. 连接线若干;
' y$ R! M+ X, o: n4 L. p6 y- G, L5 c
1.5. miniusb线缆,用于给开发板供电及串口通信。
2 S1 K7 M4 v" c& v8 D- v& O* a; r( g. E
20180409144846453.png
+ {" L# W6 E  g8 i% U3 {; L8 {
( C- @0 i! {  \' M, ~. S
2. 系统描述与框图:4 g7 g+ z# X+ e! |
' Z( I0 G, I" Z$ X& v( I
运动自行车车轮上安装5只磁铁,通过磁感应开关检测磁铁产生信号,接入stm32开发板PE0引脚。测量出的速度值通过串口发送给PC上位机软件(mini usb线缆连接)。硬件框图如下:
' W5 U; u( s- G1 `! h# p
! ?5 P) A3 Q' b5 v3 t, j3 d
2018040914485823.png
: d) r" f- x, c6 P
# o1 B8 C" x7 n9 J. Q2 T

6 P, c: k& n$ F% U# N9 M5 I' M3. 软件实现$ }# M& c6 s0 T+ I! H( b" J

6 ]; ~" _% U5 K. n) {3.1.设定开发板PE0引脚下降沿中断,在引脚中断服务函数里累计中断次数(即磁感应开关感应到磁铁的次数),同时每累计10次LED2交换一次状态。外部初始化代码及中断服务函数如下:5 y- l7 e5 R% g( X% k

- L5 l/ d# M# q$ P4 p- D' l
  1. void EXTIX_Init(void)
    " y1 |7 j+ Y  ]6 Q7 c1 N: F
  2. {; _- y/ t4 y$ p5 v# ~* B& E& `
  3.     EXTI_InitTypeDef EXTI_InitStructure;7 Z8 F3 E0 z# T
  4.     NVIC_InitTypeDef NVIC_InitStructure;0 H0 M+ Z8 Y2 |" \- F' {
  5.     GPIO_InitTypeDef GPIO_InitStructure;
    * D% O7 z# J# [0 @7 Z
  6.     //  引脚端口初始化 PE0% G* X7 o2 w  p$ {2 C6 C. D
  7.     GPIO_InitStructure.GPIO_Pin  = DEF_BIT_00;2 q9 s, q- r% ?; Q- O
  8.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;+ v  d: y6 Z: Z
  9.     GPIO_Init(GPIOE, &GPIO_InitStructure);   
    * Y- g' T, a: R/ b/ k7 ]2 ]- X
  10.      // 启 AFIO 时钟
    9 E. [4 i- L2 C( |/ L2 E$ }
  11.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    + D8 ~9 X( H7 U5 Z
  12.     //GPIOE.0 中断线以及中断初始化配置,下降沿触发# o% [  I' D) n( ]0 q& I2 o
  13.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource0);// 配置中断线为0
    % m4 w4 A8 g% t6 L, d& H
  14.     EXTI_InitStructure.EXTI_Line=EXTI_Line0;
    : Q1 S7 I( a* a) d
  15.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;" ^7 c7 P: J* @8 J! p- u
  16.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发# ]  R/ Z9 G9 B" p9 b- ]/ x
  17.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;$ Q& Z4 x% I/ m8 n" I) P  X
  18.     EXTI_Init(&EXTI_InitStructure); // 初始化中断线参数5 q9 X" [0 f$ A; l0 [# u, w; j

  19. ) T; M7 e4 ~2 q8 k
  20.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //使能按键外部中断通道
    8 L2 G9 C% k0 C4 ^! N
  21.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级 2,( a" g4 i4 i  O: G2 W2 f/ v
  22.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;           //子优先级 2% H9 A# Y; \( k: u
  23.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //使能外部中断通道
    9 q* R$ V( I1 v
  24.     NVIC_Init(&NVIC_InitStructure);                                 // 初始化 NVIC. n% K4 k( ]: p# L0 m. J# A7 D
  25. }
    6 Q% C5 T: n; v& A; J; O: z# a
  26. // 外部中断0服务程序& t( F1 q) D! n$ f& l! E
  27. long long lSpeedCnt = 0;
    7 t8 N" `& k$ T
  28. void EXTI0_IRQHandler(void)5 ^0 K& S! F% L9 ]* P
  29. {
    ( q5 \0 U' L8 \  p( q4 L8 ]
  30.     OSIntEnter();             // 告诉ucosii系统进入中断6 S& u' G6 z4 L. n
  31. * \0 t2 ^  i- o
  32.     if(GPIO_ReadInputDataBit(GPIOE, DEF_BIT_00)==0) // PE0检测到下降沿
    . ?4 M3 g+ m3 g8 e( F
  33.     {( R. ^, O; T: i) Y5 i
  34.         // 累计中断次数,每隔10次改变led1状态1 o, D4 w  G/ g" w& L. D" k
  35.         if(!((lSpeedCnt++)%10))
    2 c3 E: O7 f9 z
  36.         {- E' @3 [& T% u" k
  37.             BSP_LED_Toggle(2);, ^, H8 S% x2 H* S) B- r! o
  38.         }: ^4 R% Z# h3 W. I
  39.     }3 m5 U# u3 e% {1 F
  40.     EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE0上的中断标志位
    " ]7 w6 [5 ?; a/ j. [$ W3 m" B

  41. " r) [" I3 C# E
  42.     OSIntExit             // 告诉ucosii系统退出中断; T' e  w( g0 I2 L
  43. }
复制代码

/ C/ H% b: g% }- e
7 \: U  ~% Q3 B7 x3.2.在启用一个定时器中断,周期为1s,在定时器中断服务函数里计算自行车的速度。计算方式如下:v = p / μ * C,其中:v是速度:m/s,p是磁感应开关感应频率, μ为车轮上安装磁铁个数:5,C为自行车车轮周长:1.38m。定时器中断初始化代码及中断服务函数如下:
( d3 B- g" O0 Y, I2 o& d' O$ {$ `. `  s8 B: r* Y8 Y: a  O  I5 i) G
  1. /*******************************************************************************% z. V) I+ b  K  S* m' q
  2. * Function Name  : BSP_TIM2_Init2 o3 @2 R' S" c9 P3 E* J
  3. * Description    : Compute return latest speed measurement
    1 C+ s6 w" x3 `. n! M& c9 R; Z/ |
  4. * Input          : None7 X- @' I( T( }# W. j, u
  5. * Output         : s16
    ( k5 g: s8 K9 N) A* ~  a: C
  6. * Return         : Return the speed in 0.1 Hz resolution.                    5 L. d4 L9 i1 F. M  A3 L
  7. *******************************************************************************/
    " Y3 `  O  \* y
  8. static void BSP_TIM2_Init(u16 arr, u16 psc)
    ; S; t. Q) k; I$ ^+ l
  9. {
    $ O' {4 {$ g' s3 _5 f9 z( w  ?' {7 E6 p! U
  10.     TIM_TimeBaseInitTypeDef   bsp_tim2_init;   
    % e- [' a7 z5 i7 t, M
  11. 8 x: Y8 d# \8 R% L, B$ V- H
  12.     //使能TIM2时钟
    2 v' c. {) ?, J( }/ R
  13.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);1 N5 s/ o' w) k8 h
  14. & Y# j1 B4 T4 p0 g8 T$ `

  15. , W/ p7 H& b9 x! s2 E  h
  16.     TIM_DeInit(TIM2);- b# }, F) _6 D2 c' @- t9 b
  17.     TIM_TimeBaseStructInit(&bsp_tim2_init);
    9 b  o& K$ r% Y7 h3 W' p& G
  18.     //TIM2初始化1 X8 c% i1 n- m/ B) z' n
  19.     bsp_tim2_init.TIM_Prescaler = psc;                                          //时钟预分频   定时器每隔 (psc+1)/72 us计数一次
    8 t( i/ A4 o' M* \9 B
  20.     bsp_tim2_init.TIM_CounterMode = TIM_CounterMode_Up;                         //向上计数
    ; X& G" G: ^/ J, x
  21.     bsp_tim2_init.TIM_Period = arr;                                             //计数满(arr+1)次更新重装载寄存器数据# x/ a0 ~5 o' j5 E+ ]3 d
  22.     bsp_tim2_init.TIM_ClockDivision = TIM_CKD_DIV1;                             //时钟不分频
    1 M0 u% ?( B7 W2 ~; q' g
  23. //    bsp_tim2_init.TIM_RepetitionCounter = ;                                   //高级定时器用,这里不需设置  z% t2 d# Z' e7 K+ B4 K5 _
  24.     TIM_TimeBaseInit(TIM2, &bsp_tim2_init);                                     //初始化定时器
    , j% {2 a) W/ F4 a) U+ c
  25. 9 n- _2 Y. X* F0 K
  26.     //设置定时器TIM2中断! n" {& t3 Y+ U. B
  27.     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);                                  //设置定时器更新中断
    6 p6 x/ d0 ?* Y4 ]
  28.     TIM_ClearITPendingBit(TIM2, TIM_IT_Update);                                 //清除中断标志,防止刚上电时进一次中断
    ( t# B9 H' g" B7 E, b

  29. ) A; h' y6 q( t/ G" f. @
  30.     //初始化中断6 U$ z& E3 I% ]: F
  31.     BSP_NVIC_Init(TIM2_IRQn, 3, 3); 7 m1 ?. N3 }4 G  h' a
  32. / S4 b" ]- |5 I) S7 a9 ^
  33.     //使能定时器TIM2' J7 x/ C/ n; f8 o" o; U8 u! p
  34.     TIM_Cmd(TIM2, ENABLE);  o/ g  j% d, j9 e5 p# |; a
  35. }
复制代码
  1. long long lvalCur;7 Y" C0 m7 F# Z2 v, k& ~3 r
  2. long long lValPrev;
    ( o, `( Y1 _  ?
  3. float fSpeedVal;
    ( ]1 i( Z- f6 [( C' \+ S  A% T
  4. void TIM2_IRQHandler(void)
    0 m; H' Z8 f8 @0 `
  5. {* y. c" C' M  q
  6.     OSIntEnter();             // 告诉ucosii系统进入中断7 P' ]  F' ?: q7 c- v+ j
  7. ( k, Z! J/ d2 U( _1 u
  8.     if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)3 D, }8 x4 J2 b) P( @  F6 q! r
  9.     {      ' k* U+ P. H5 p' }+ v6 M4 \0 e8 {
  10.       extern long long lSpeedCnt;
    5 |+ [! y: b0 H* u! ~9 }; A

  11. ; q' _& R- s1 x5 a3 M
  12.       lvalCur = lSpeedCnt;
    6 x2 @2 V; n$ i! M
  13.       fSpeedVal = (float)lvalCur - (float)lValPrev;
    ' N& u6 Q5 P8 p; ?9 d5 H- I* l2 n
  14.       fSpeedVal /= 5.0;
    $ I# {; Q- z  h) b
  15.       fSpeedVal *= 1.38;      
    / g4 L- P* X( Z
  16.       lValPrev = lvalCur;6 D, g& I6 N5 K  L1 g6 N) H
  17.       TIM_ClearFlag(TIM2, TIM_IT_Update);
    : H1 s) R" q) i! x+ G% L6 ?, ?
  18.     }
    ( T& N0 L2 e' A# ^6 P: G
  19.     OSIntExit();             // 告诉ucosii系统退出中断) U" y( g% w+ s$ w

  20. / E& T! {& P! W9 M. g+ v/ V9 N
  21. }
复制代码

5 w/ z0 G+ W9 h6 t$ g3 J3.3.系统共有两个任务,其中一个任务每50ms发送一次速度值给PC机,另一个控制LED1闪烁,周期100ms,用于指示系统正常运行。7 C1 w7 V4 @* @
  k8 u6 V! H8 e1 P( i: |. z
第一个任务中运行代码如下:$ K; W! t" z+ \3 J: K
" L- @  V; E4 _( ?- c% ~7 X
  1. while(DEF_TRUE)9 F; r9 J% ~$ t' v9 {/ k, G
  2.     {              
    * X8 M, y% j4 t# C% \
  3.         extern float fSpeedVal;
    # X7 e) d3 d  ^) X
  4.         if((int)(fSpeedVal*100) > 9999)
    & t% d& J( X9 R! d5 n' q. G2 q( O
  5.         {9 v3 n0 M& Z+ W, D0 X  a
  6.             printf("9999");
    4 H8 T7 N! Z/ m
  7.         }
    5 i. Q/ l: J9 H, Q3 j4 P
  8.         else if((int)(fSpeedVal*100) > 999)
      t  v8 f: d( L& u( n: G8 G( G
  9.         {# b; Z. k4 y, Y
  10.             printf("%d",(int)(fSpeedVal*100));
    ) @/ a: V: J* d
  11.         }
    # C3 G- J  b/ f- q2 c
  12.         else if((int)(fSpeedVal*100) > 99)# |! r4 q/ I1 ]# x7 o: W
  13.         {
    1 K0 Y, `7 X& f; R% Z- L7 z
  14.             printf("0%d",(int)(fSpeedVal*100));
    : q4 O4 a7 y5 {: b8 N
  15.         }2 Q! _  X) r& e+ U1 r3 r
  16.         else if((int)(fSpeedVal*100) > 9)4 P/ E# V# C! t; v+ H  p0 r+ x
  17.         {
    5 A$ Q% E2 W0 c' }9 a9 n: Q$ N
  18.             printf("00%d",(int)(fSpeedVal*100)); & b2 z2 X% \$ E
  19.         }
    2 C* y8 T7 w) [$ Q$ t/ K& [& I
  20.         else7 k8 i1 }1 i! C; K- W& ^; D
  21.         {  I5 G% Q) m4 d7 i9 Y; e
  22.             printf("000%d",(int)(fSpeedVal*100)); % d& Q3 a+ P6 E/ u# N9 z( m
  23.         }     
    0 \+ r0 r/ Y2 A. E
  24. 1 e9 Q8 I2 O* w; G$ D
  25.         OSTimeDlyHMSM(0, 0, 0, 80);
    . z  e4 g; ]3 x  Q
  26.     }        
复制代码
8 ?$ a1 f1 j4 c1 e, U$ V- y
第二个任务中代码如下:) L4 V) _9 A! @" _$ f7 W& s% C9 e7 {

% ^1 D( v5 _  c( D( T. V
  1. while (DEF_TRUE)
    6 y% j7 U! x. U6 c2 P# B7 r
  2.     {     3 p8 O. n$ c! a' {) P! f7 A1 l" q4 v
  3.         BSP_LED_Toggle(1);  
    / x$ Y; A/ m: C: m
  4.         OSTimeDlyHMSM(0, 0, 0, 100);3 h3 S( j/ U- }$ `% b
  5.     }
复制代码
1 H* ]- C. p" x+ s2 M1 ~* B! @
整体运行稳定,满足项目需求。
) r8 Z7 x+ o' Q7 t! x8 j2 K( H6 x9 t

* h( V3 Q- x" u7 C2 H; t. Y% \
收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答

所属标签

相似技术帖

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