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

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

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
测量运动自行车速度,上传给上位机软件,处理VR视频播放。正好公司有现成的stm32f1系列单片机开发板,所以我就想到了使用它来实现这个小功能。
# ^( f8 F! {, v, z7 O7 w
5 i' Q8 y6 H2 X1 T) h1. 硬件配置:
- R8 X6 }1 c. s) `6 z" Q) \  @) s5 P/ F) D
1.1. 运动自行车;' U# V4 O9 K" }, j
" [( z) g" U# d/ x
20180409144730202.png
; E$ E2 [9 H6 o( q* v5 ~
# |1 U& O0 g- q& M8 l( z5 l
1.2. 磁感应开关与专用磁铁;   
5 k3 b" e* J5 H8 X
4 ?3 m" c! n, h8 D# n, E8 n: c
20180409144808136.png 20180409144818159.png
  m/ a8 A' d; E) K* Y
2 X8 B  V( x) X9 l& P7 G
1.3. 基于Stm32f103zet6芯片的开发板(七星虫),如下图;
' r, X: C! b# C6 \; j3 U+ P
' k# u# x3 e; y
20180409144832248.png

) T) _( [0 g# e3 j1 G9 p, ?; E3 g* \4 V) Q6 y
1.4. 连接线若干;
& E! Z) r/ b# _: f% a# s7 Y0 Q7 }* b
1.5. miniusb线缆,用于给开发板供电及串口通信。% {+ y1 D4 B0 m+ P+ J) g; F3 T

% }% y9 n: ?# Z4 ]) Z/ U  V+ x
20180409144846453.png

! h5 g3 m$ s. y& l% P/ P# U, r6 b# \6 A  x- k
2. 系统描述与框图:
. E9 W# K1 r. g  r. b- k
2 [3 G1 E3 o0 V" x9 H运动自行车车轮上安装5只磁铁,通过磁感应开关检测磁铁产生信号,接入stm32开发板PE0引脚。测量出的速度值通过串口发送给PC上位机软件(mini usb线缆连接)。硬件框图如下:
! i8 ?( ]1 c" Z; E1 y1 I9 u# L; E+ ~% o% Q
2018040914485823.png
+ u+ e- l1 R! X6 Y4 |+ l6 k' T2 _2 Z9 w  w* C
4 N; ~" ^7 D! t7 b

1 g$ L6 L# X: w0 b, c3. 软件实现
- N2 t0 h2 e, D" d- Q, Y* ]* R1 v) ]& y& x( F2 O5 }: ?
3.1.设定开发板PE0引脚下降沿中断,在引脚中断服务函数里累计中断次数(即磁感应开关感应到磁铁的次数),同时每累计10次LED2交换一次状态。外部初始化代码及中断服务函数如下:
1 R5 V7 K4 }& E( H
4 V/ t9 V& R" W+ C4 u# C7 h
  1. void EXTIX_Init(void)" p% Q8 n% M9 U- Y9 A$ `; P3 C8 A
  2. {
    2 z9 }. V0 N. T* P7 ~9 V& ^
  3.     EXTI_InitTypeDef EXTI_InitStructure;
    / R/ b8 }  i3 L9 M# z1 ~8 J
  4.     NVIC_InitTypeDef NVIC_InitStructure;9 @7 l* m! y% Z1 p* c$ v
  5.     GPIO_InitTypeDef GPIO_InitStructure;
    ) w2 ~' C! U0 F7 r3 H' U& p
  6.     //  引脚端口初始化 PE0
    " X; D1 A+ _+ d! l  a7 i: u
  7.     GPIO_InitStructure.GPIO_Pin  = DEF_BIT_00;
    7 s7 z5 B; y  A% j" c  n- K
  8.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    - |9 H4 t2 E# V& _0 ^4 o$ O
  9.     GPIO_Init(GPIOE, &GPIO_InitStructure);   
    * K0 ^" s$ d! C% ~
  10.      // 启 AFIO 时钟
    7 f0 k1 c! }& _
  11.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    . W  Z$ U) U/ }0 @
  12.     //GPIOE.0 中断线以及中断初始化配置,下降沿触发% u+ O. g; S9 O+ h
  13.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource0);// 配置中断线为0
    4 V$ d6 X- C4 _' s$ \# U* o
  14.     EXTI_InitStructure.EXTI_Line=EXTI_Line0;
    % }8 F3 n9 U+ ]2 v8 _8 E
  15.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;# b1 s/ I2 r# X$ J% ~  }& T
  16.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
    0 A) ]( q* Q, J4 E8 W+ T; w
  17.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;0 [7 T, @5 t3 }; F9 n" V" i
  18.     EXTI_Init(&EXTI_InitStructure); // 初始化中断线参数" H0 q) z- G' n- @

  19. 8 a# ^$ t; F- i/ z
  20.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //使能按键外部中断通道
    7 ]; u4 t: W' N
  21.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级 2,4 r6 z% X; K6 U. p) A& D
  22.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;           //子优先级 2
    0 \/ r- i. l* O7 \
  23.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //使能外部中断通道* i8 B. x* Q2 Y4 k
  24.     NVIC_Init(&NVIC_InitStructure);                                 // 初始化 NVIC
    5 d3 M4 O: _  U& G7 @
  25. }- i  `2 d9 p1 K3 |" I
  26. // 外部中断0服务程序
    ' }. {2 h' R- g9 e) `1 y
  27. long long lSpeedCnt = 0;2 q4 k) i! S/ l; T5 E
  28. void EXTI0_IRQHandler(void)
    % i/ [6 w  B. E2 m. ]0 C& ?: w
  29. {
    . h& {) e  i! E8 Q
  30.     OSIntEnter();             // 告诉ucosii系统进入中断3 ~3 u% D  }/ M! l" v' h1 A; B  N  ?

  31. 7 D. S7 W# w3 m& g6 g% X& B
  32.     if(GPIO_ReadInputDataBit(GPIOE, DEF_BIT_00)==0) // PE0检测到下降沿4 g( K) e$ b# W1 z$ Q& v) u
  33.     {' K9 k1 U8 }# G; E& C5 M
  34.         // 累计中断次数,每隔10次改变led1状态" n( X. |* L7 C$ o8 g
  35.         if(!((lSpeedCnt++)%10))* T! G0 T1 N2 }  p- J6 C% R
  36.         {
    ' ~% Q# N9 B/ k. |0 W
  37.             BSP_LED_Toggle(2);
    ) m; p! ?! F" x; R- P( u
  38.         }
    , A$ Y  V, N7 a
  39.     }/ Z8 s& J8 K& T
  40.     EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE0上的中断标志位
    9 F6 i. M- L3 [# C, Z

  41.   L* I" x0 X; x- [' f5 j
  42.     OSIntExit             // 告诉ucosii系统退出中断
    ( a( t% k  I7 D* P' Q, B0 v
  43. }
复制代码
* k) e3 L0 J( g% |3 M: b. x7 n- E& w$ `

. k  u( u, ]1 |% P3.2.在启用一个定时器中断,周期为1s,在定时器中断服务函数里计算自行车的速度。计算方式如下:v = p / μ * C,其中:v是速度:m/s,p是磁感应开关感应频率, μ为车轮上安装磁铁个数:5,C为自行车车轮周长:1.38m。定时器中断初始化代码及中断服务函数如下:1 s, J% y8 ?4 i0 D' r$ c6 h

/ o- M0 a! j+ l
  1. /*******************************************************************************# ^9 v/ T5 F* `8 c2 d6 H
  2. * Function Name  : BSP_TIM2_Init
    ; j4 H; w/ f* ]2 h
  3. * Description    : Compute return latest speed measurement
    # W* C2 N2 v8 T6 d5 f3 ]9 N& w; ]8 n
  4. * Input          : None! j/ y+ b  s" G) G: d
  5. * Output         : s16
    6 w6 c- G) W" h# }  f4 n
  6. * Return         : Return the speed in 0.1 Hz resolution.                    
    # p2 T: D8 u/ e& i3 t# t
  7. *******************************************************************************/6 U& P" k- v9 B2 \& I$ Q7 Q) T
  8. static void BSP_TIM2_Init(u16 arr, u16 psc)
    4 _0 i7 W& F8 Q
  9. {% r/ J, [# V9 K3 {1 y5 q
  10.     TIM_TimeBaseInitTypeDef   bsp_tim2_init;   
    7 E# u* V0 M( q) D# _) S

  11. . b. ?  |( }7 @" l3 e7 e
  12.     //使能TIM2时钟, K* Z5 G* o: `% E- C
  13.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);3 l* R# F& r8 h, G6 G
  14. ! q/ Q& }0 E) ?+ k6 c: H* A
  15.   Q! p2 R! c, ^9 C! X
  16.     TIM_DeInit(TIM2);
    3 ^0 x3 @1 ^9 k! h
  17.     TIM_TimeBaseStructInit(&bsp_tim2_init);
    # u0 X+ d/ T( g$ [4 i# G8 h) {8 ]
  18.     //TIM2初始化
    ! W* a. |: G! \6 Y' u
  19.     bsp_tim2_init.TIM_Prescaler = psc;                                          //时钟预分频   定时器每隔 (psc+1)/72 us计数一次/ z, c9 o# q( ]  [/ R  u& s6 ^
  20.     bsp_tim2_init.TIM_CounterMode = TIM_CounterMode_Up;                         //向上计数5 J+ b. o; y2 e; u9 E$ p! ?, {! Q: e
  21.     bsp_tim2_init.TIM_Period = arr;                                             //计数满(arr+1)次更新重装载寄存器数据% [3 b- r: E" d: y7 x. E! E' @
  22.     bsp_tim2_init.TIM_ClockDivision = TIM_CKD_DIV1;                             //时钟不分频
    2 y4 ?3 s3 D4 J; v- Y/ ^
  23. //    bsp_tim2_init.TIM_RepetitionCounter = ;                                   //高级定时器用,这里不需设置, L) q; p- B5 H
  24.     TIM_TimeBaseInit(TIM2, &bsp_tim2_init);                                     //初始化定时器, ?7 p% ]2 I6 n& y# X
  25. & D) {( N6 F% _! s9 B- U  _% C
  26.     //设置定时器TIM2中断
    9 @1 a$ B! V. u& O" d* p3 a
  27.     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);                                  //设置定时器更新中断
    ) z* \5 i, p9 I0 X: Q+ F# _! K- g
  28.     TIM_ClearITPendingBit(TIM2, TIM_IT_Update);                                 //清除中断标志,防止刚上电时进一次中断- \, I6 e0 \! N6 T

  29. , g( }4 i* w; [% ~  P% Y
  30.     //初始化中断2 {# {3 z- f! Q, o
  31.     BSP_NVIC_Init(TIM2_IRQn, 3, 3);
    6 G( e+ H- {! N5 H
  32. . {' a  {7 w" m6 |$ A0 P- u
  33.     //使能定时器TIM2. y* }- |$ K9 f
  34.     TIM_Cmd(TIM2, ENABLE);
    % t. Z1 `# ~& N1 c- a) x0 j
  35. }
复制代码
  1. long long lvalCur;
    4 J5 F; E4 |5 u$ f' O
  2. long long lValPrev;
    * t* q" F6 p& m- u0 j$ Y
  3. float fSpeedVal;3 K! w. B, X: |
  4. void TIM2_IRQHandler(void)& Q$ }' }) S, o& G
  5. {' X1 c2 ~" E! q* S
  6.     OSIntEnter();             // 告诉ucosii系统进入中断/ S1 x, O( Q5 }. E# D3 m

  7. 7 A. u3 r- x- x0 ]
  8.     if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    0 ]; E. w; s+ _& @0 @
  9.     {      
    , N/ m  L4 f# o7 [. g8 q: X8 G
  10.       extern long long lSpeedCnt;
    $ n- z+ C4 L! ~4 f% U% k# a

  11. & D1 I# j8 K' g, M5 C2 L  V
  12.       lvalCur = lSpeedCnt;
    / d3 `' I! k# T: n/ H; A( N
  13.       fSpeedVal = (float)lvalCur - (float)lValPrev;
    ) x) n) N% T- z: D6 f  ~' X- _
  14.       fSpeedVal /= 5.0;
    ( L- S" `* p/ t( p( {' F  y
  15.       fSpeedVal *= 1.38;      : p7 V* {. E) y
  16.       lValPrev = lvalCur;
    # X# w$ i0 X" q- g3 h
  17.       TIM_ClearFlag(TIM2, TIM_IT_Update);
    8 h& p) X6 `2 I- o+ s* U9 P
  18.     }' ^; O- H, m4 r& a; y  t
  19.     OSIntExit();             // 告诉ucosii系统退出中断4 g& r0 H4 H, j9 Y# L  H

  20. ! H7 a7 U- c% y& `
  21. }
复制代码

0 Q1 \! l* [4 b/ D4 j' Z! G: V3.3.系统共有两个任务,其中一个任务每50ms发送一次速度值给PC机,另一个控制LED1闪烁,周期100ms,用于指示系统正常运行。
0 p$ i$ {( c2 J4 h6 q+ \1 i! g6 d9 ?* d4 u- P/ T: P* P( g
第一个任务中运行代码如下:
5 V% ?5 ]3 f' O" S
( j( E% \$ S. p- D0 X' _! w  G( r) `
  1. while(DEF_TRUE)
    ) M/ }( H  o6 L- _
  2.     {              
    1 x% v0 B6 }9 h- b2 D' ?
  3.         extern float fSpeedVal;
    ) Z' w% _1 @9 N- q+ m
  4.         if((int)(fSpeedVal*100) > 9999)6 s& _- U9 |! s1 u
  5.         {' Z6 W& q$ l+ Z
  6.             printf("9999"); 8 X& C( O' a) K
  7.         }
    * W' E7 l' D/ S$ S( s/ L
  8.         else if((int)(fSpeedVal*100) > 999)
    0 S, w' C  |5 }
  9.         {- {! k4 \* d+ a# o
  10.             printf("%d",(int)(fSpeedVal*100));   o* J; y2 [0 f
  11.         }
    5 E5 i/ l  s9 o( |2 C1 f
  12.         else if((int)(fSpeedVal*100) > 99)/ o' j: ]! x0 F& d6 W  o. g5 y
  13.         {
    + d5 U  p2 a! O9 J
  14.             printf("0%d",(int)(fSpeedVal*100)); 0 Q2 W1 O$ r% a
  15.         }
    5 _/ j% {8 }! P' F
  16.         else if((int)(fSpeedVal*100) > 9)9 Y$ {5 Y" q) A* u, D& p5 d; X
  17.         {
    , u8 I9 S5 S% t: v& k
  18.             printf("00%d",(int)(fSpeedVal*100));
    / P( Y$ B+ u, z! ]
  19.         }; n, z8 {+ h/ L8 `8 w- X3 e: Q7 R
  20.         else
    5 C4 o# Y% T; o) u2 E* o( A" [
  21.         {
    0 }8 i* \3 K2 R
  22.             printf("000%d",(int)(fSpeedVal*100));
    % E0 j- w, N, i
  23.         }     
    # m0 A- A, c, v/ \& U: Q
  24. 4 u1 l" H6 H) h, K- K- a" C
  25.         OSTimeDlyHMSM(0, 0, 0, 80);7 ^" g. U$ B$ q9 U9 m/ ]; E6 {
  26.     }        
复制代码
" s0 J% D' K# [) Z1 Q
第二个任务中代码如下:5 [: G3 R. \/ H; y/ \3 T4 ~
3 l4 w7 o  c% \$ o# y
  1. while (DEF_TRUE)
    % C" p/ f; M, Y; j& p0 ]- }; i* _$ y& s
  2.     {     
    ) j" W# ~! M# c% D
  3.         BSP_LED_Toggle(1);  
    4 @& q4 W% v1 ?9 F5 m" D
  4.         OSTimeDlyHMSM(0, 0, 0, 100);! L5 P! P, z4 J7 E' |
  5.     }
复制代码
: n  Q+ o, Y7 E2 O
整体运行稳定,满足项目需求。
( y$ C9 J7 w: I, x1 y4 V
7 m. E  g2 d! e/ G( Q* C7 @2 h4 C6 j6 ]* A  K! p
赞 收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版