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

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

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
测量运动自行车速度,上传给上位机软件,处理VR视频播放。正好公司有现成的stm32f1系列单片机开发板,所以我就想到了使用它来实现这个小功能。
$ k$ q1 v# w  l! M
& X& i8 b/ a* B5 l$ L1. 硬件配置:
/ A3 ~" ~% M: y- q. U
/ @" g% a% j% e  \1.1. 运动自行车;
# q1 x! m! h' D. I
* r5 }1 w& Z0 K5 s; s: M
20180409144730202.png
9 d+ z( L6 A, B, q
( J, E3 y) ?9 ~% u1 Y* j+ s
1.2. 磁感应开关与专用磁铁;   
0 m; R7 r3 j/ n+ c( S/ X: P+ m; n( X  T- Q$ ?) m' q6 Y
20180409144808136.png 20180409144818159.png
" S, J( d9 A% ]' f  g: D

" O; ]5 y; H' g! W% N; P! J1.3. 基于Stm32f103zet6芯片的开发板(七星虫),如下图;
& C1 i+ ~" N; r+ A1 c
. E* b5 |) O) e7 @! y6 ?5 o
20180409144832248.png

) [. [" {' t! g# @2 M3 u' O+ [1 t7 z7 P" w! ^
1.4. 连接线若干;
# M& o2 h3 I( b5 n. o! j) ~7 u
1.5. miniusb线缆,用于给开发板供电及串口通信。
! y6 y* a. o& G, E8 _
5 z1 \! @. F, T# M6 ~  _
20180409144846453.png
6 r; R( X5 u0 {' Z- b5 C# B# n
7 C: ]6 P, ]2 r' r, [
2. 系统描述与框图:
7 R1 N+ [' E6 K; O- L+ }
% U. c4 k8 A/ f' X. v运动自行车车轮上安装5只磁铁,通过磁感应开关检测磁铁产生信号,接入stm32开发板PE0引脚。测量出的速度值通过串口发送给PC上位机软件(mini usb线缆连接)。硬件框图如下:4 l: P( N9 x3 ^# `1 f  N( ^) D

$ N9 e. D( b5 ^
2018040914485823.png
, ?5 ]' l/ r6 }+ D( R* D
; t$ A0 j/ I: v1 a1 c* j1 N' ^4 [
& N8 Y- m& R4 c1 y
3. 软件实现
( y& G% N7 l8 Y* D4 M# [/ j! V
6 ~7 @4 |; G; O' Y' _3.1.设定开发板PE0引脚下降沿中断,在引脚中断服务函数里累计中断次数(即磁感应开关感应到磁铁的次数),同时每累计10次LED2交换一次状态。外部初始化代码及中断服务函数如下:0 S& P8 X) y' y9 ?# N: ?0 ^  e5 G
, ]$ j3 q4 i: h
  1. void EXTIX_Init(void)
    7 v+ C2 D: E! H  ?& [$ v
  2. {
    $ w  u1 V/ b! A
  3.     EXTI_InitTypeDef EXTI_InitStructure;
    % m! ^. m4 c" ~( y( C/ S2 ~
  4.     NVIC_InitTypeDef NVIC_InitStructure;  k$ u2 M$ S2 n' V4 x( ]! X
  5.     GPIO_InitTypeDef GPIO_InitStructure;
    5 I- t9 e3 k3 m# G9 p
  6.     //  引脚端口初始化 PE0  b+ q4 _, J1 k
  7.     GPIO_InitStructure.GPIO_Pin  = DEF_BIT_00;! X- y7 [. c7 ]  V
  8.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;2 V4 }2 ?5 Y. T& R  r+ g, S
  9.     GPIO_Init(GPIOE, &GPIO_InitStructure);   
    , p4 B* A+ u( Q; N7 I1 H, S0 v
  10.      // 启 AFIO 时钟
    8 c' e; Q6 K7 l+ w# P7 d% Q/ l# |
  11.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);3 ?; o6 {% t0 X4 z
  12.     //GPIOE.0 中断线以及中断初始化配置,下降沿触发
    % m+ F, y! K& F5 C* I$ X
  13.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource0);// 配置中断线为0+ G7 K1 S2 j1 T) b! l9 E
  14.     EXTI_InitStructure.EXTI_Line=EXTI_Line0;
    : T- O- J  m2 ?7 O
  15.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    9 B) Z. g; \2 q5 U1 b, z/ Z
  16.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
    , H9 _$ l; o) U9 \$ U* {0 ^: C
  17.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    ( ~' z# I5 }; r+ A
  18.     EXTI_Init(&EXTI_InitStructure); // 初始化中断线参数
    2 \9 A1 R. D1 a; G0 m& H5 O6 q
  19. 4 \1 W" ]0 L$ O( e
  20.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //使能按键外部中断通道* t0 B  i7 _/ K
  21.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级 2,
    1 x4 F$ }; ~- `0 Q& X
  22.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;           //子优先级 2" T9 Q0 `& g" q6 k7 b. [
  23.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //使能外部中断通道  u5 M* B) R' a; x
  24.     NVIC_Init(&NVIC_InitStructure);                                 // 初始化 NVIC2 u5 N1 S* |2 e/ n
  25. }3 [; Z: j( I7 s; e0 S; ^
  26. // 外部中断0服务程序
    / X+ O- _  A4 T6 k# d2 B, b
  27. long long lSpeedCnt = 0;
    8 v* F- r- {3 t2 c% O
  28. void EXTI0_IRQHandler(void)# U  j3 |1 X# a' o' e! l
  29. {
    ' `+ D8 g2 q8 L
  30.     OSIntEnter();             // 告诉ucosii系统进入中断
    1 A! A/ n: k( T2 J, X$ `* n
  31. ; w# X# ]* ?% C7 @, b
  32.     if(GPIO_ReadInputDataBit(GPIOE, DEF_BIT_00)==0) // PE0检测到下降沿
    1 z. E5 h; t. g! i! ?
  33.     {- Q* G, S' X; W+ M
  34.         // 累计中断次数,每隔10次改变led1状态4 q# X6 L9 K& }$ [" J! L6 l
  35.         if(!((lSpeedCnt++)%10))
    0 l# W! a! V4 x2 n5 e7 G$ w! ^
  36.         {# `* W! C, d2 u! S5 |
  37.             BSP_LED_Toggle(2);' m3 r' S5 h8 J, r  A2 P
  38.         }
    - l/ u+ l' I$ R* V/ D7 t* {  P$ \. i
  39.     }
    . i* Y) I3 h* l9 J
  40.     EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE0上的中断标志位
    ; U9 ^" A# O+ x+ h9 n+ y! w

  41. : ?( v( g; P( u" _5 M
  42.     OSIntExit             // 告诉ucosii系统退出中断
    " Y& C9 L1 [" I7 A% F9 l. \4 l
  43. }
复制代码

+ j& o( j- G0 H. X% }# v9 _9 W" O7 W8 U, J& \' U% _8 Z/ i
3.2.在启用一个定时器中断,周期为1s,在定时器中断服务函数里计算自行车的速度。计算方式如下:v = p / μ * C,其中:v是速度:m/s,p是磁感应开关感应频率, μ为车轮上安装磁铁个数:5,C为自行车车轮周长:1.38m。定时器中断初始化代码及中断服务函数如下:
' k; P, f  y! [9 e4 v; T
/ w2 X# k# _" ^( X: q
  1. /*******************************************************************************2 g$ P- B! I& m+ C+ R
  2. * Function Name  : BSP_TIM2_Init
    + Z$ e6 f4 D9 Z' v
  3. * Description    : Compute return latest speed measurement
    : b6 h: v/ R7 r% l5 M
  4. * Input          : None& r& b/ L( a( P3 }. B5 ^' S
  5. * Output         : s16
    6 j) z4 D2 g1 }" |4 H0 }" m/ t
  6. * Return         : Return the speed in 0.1 Hz resolution.                    
    # U7 `, s6 C: X3 ?; T. h
  7. *******************************************************************************/
    6 x5 x- B6 B; B
  8. static void BSP_TIM2_Init(u16 arr, u16 psc)5 r3 n+ R1 Q9 P; T& J6 _0 N
  9. {
    3 W6 p+ f9 w; d, P
  10.     TIM_TimeBaseInitTypeDef   bsp_tim2_init;    , K; |1 P3 h" e' {# O( I
  11. ; m* j& z" t6 O
  12.     //使能TIM2时钟3 P% S" F  k+ ~5 `3 I
  13.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);9 E9 t0 [/ }* n( @& r2 }) t
  14. ' [5 O% F& W# `. Y4 a

  15. 7 b% y, }+ e5 B  @. c1 Z' F
  16.     TIM_DeInit(TIM2);4 O; G9 a, |1 U2 @4 ]# A
  17.     TIM_TimeBaseStructInit(&bsp_tim2_init);, D. i! A, O3 m1 T7 w1 S3 \4 n: s
  18.     //TIM2初始化8 m4 u0 T" C0 Z6 c- l
  19.     bsp_tim2_init.TIM_Prescaler = psc;                                          //时钟预分频   定时器每隔 (psc+1)/72 us计数一次
    : Y; E! O& M) S2 _' n( F) |
  20.     bsp_tim2_init.TIM_CounterMode = TIM_CounterMode_Up;                         //向上计数5 P: O. y/ v3 T
  21.     bsp_tim2_init.TIM_Period = arr;                                             //计数满(arr+1)次更新重装载寄存器数据
    6 q  I, c5 N: C
  22.     bsp_tim2_init.TIM_ClockDivision = TIM_CKD_DIV1;                             //时钟不分频! {# e2 K& X6 s6 L9 b
  23. //    bsp_tim2_init.TIM_RepetitionCounter = ;                                   //高级定时器用,这里不需设置
    ! d. ?) _4 h, M" r0 O
  24.     TIM_TimeBaseInit(TIM2, &bsp_tim2_init);                                     //初始化定时器
    ( y+ Z& S' Q1 ~; b4 C4 ^
  25. : f, D. Q: t: t9 @; [# f
  26.     //设置定时器TIM2中断) }( ^9 [7 U) H0 m3 g) N' O
  27.     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);                                  //设置定时器更新中断3 D) l0 |! g' I$ C
  28.     TIM_ClearITPendingBit(TIM2, TIM_IT_Update);                                 //清除中断标志,防止刚上电时进一次中断
    4 _4 W* {5 ^, B
  29. : I3 e8 N& x# y. R
  30.     //初始化中断1 I6 H7 ]/ t( D7 T; M
  31.     BSP_NVIC_Init(TIM2_IRQn, 3, 3); " J% {: C1 s, u- y- n
  32. ( m9 i  @# e* H# t  n+ o9 }/ t" C5 p, b
  33.     //使能定时器TIM2- [' j3 @' w% w1 f% g
  34.     TIM_Cmd(TIM2, ENABLE);# X# G4 f, A4 Q" W& z% x
  35. }
复制代码
  1. long long lvalCur;
    ; {" w' c  ]2 o1 L
  2. long long lValPrev;5 `. q/ m0 r1 V1 w
  3. float fSpeedVal;
    7 A( e# b% x! g9 A8 L
  4. void TIM2_IRQHandler(void)
    9 ]6 U- {5 T% h" @2 L: h1 b
  5. {
    2 f8 R9 }: j- Z) }( O9 U/ c1 p5 t
  6.     OSIntEnter();             // 告诉ucosii系统进入中断
    , O* X* [) k( f7 E" ?) \
  7. + R" d/ n, N7 T' k3 C+ D$ P  b
  8.     if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    * M$ \& M5 V- M, H( \" \
  9.     {      ! m* t: t! r. V. ~2 i! P. v4 i
  10.       extern long long lSpeedCnt;1 @" R- {7 a6 Y5 ]' F8 G# w1 V1 Q
  11. . w1 e& G' b( |) k+ f* ]; C+ B# [
  12.       lvalCur = lSpeedCnt;* T1 z4 E9 h2 x6 u
  13.       fSpeedVal = (float)lvalCur - (float)lValPrev;- \, u' ^- W8 A2 Q4 c5 P9 P& P
  14.       fSpeedVal /= 5.0;# N9 D+ W8 _( g$ q
  15.       fSpeedVal *= 1.38;      4 L' ]6 O  K$ C2 O+ [3 q4 K$ O
  16.       lValPrev = lvalCur;- `$ [7 S3 ?  \! D& R+ e: }, r
  17.       TIM_ClearFlag(TIM2, TIM_IT_Update);
    8 L; v2 B( J. g$ d$ a" f
  18.     }
    , B& K3 m7 U* N- Y
  19.     OSIntExit();             // 告诉ucosii系统退出中断  f" ^4 l2 P7 P3 G$ l9 e* O- T

  20. $ H4 d( l6 z+ K5 I8 E
  21. }
复制代码

, |+ Q5 b# ~" o: _3.3.系统共有两个任务,其中一个任务每50ms发送一次速度值给PC机,另一个控制LED1闪烁,周期100ms,用于指示系统正常运行。+ D  T/ a8 v9 ?' X4 A
5 L' a, V0 s+ C8 w8 S  L. u
第一个任务中运行代码如下:/ v. p% U3 P3 a+ T
! F1 R" i1 J3 q; P0 Q6 ^. e
  1. while(DEF_TRUE)
    + @% S' p% z' @; u- z/ r
  2.     {              
    2 i" I* _, c+ }+ i
  3.         extern float fSpeedVal;( e9 U3 @! v4 b' m6 ]9 \
  4.         if((int)(fSpeedVal*100) > 9999). u9 S9 J0 y. ]* ?' J4 o# g( O
  5.         {
    5 C" A* B/ {3 |; B6 n
  6.             printf("9999");
    7 C+ A. C5 p# W+ w9 k$ r8 t$ t
  7.         }( O: }" ^" j; ~$ f2 _% |/ N2 `
  8.         else if((int)(fSpeedVal*100) > 999)5 i$ s, J0 D  c& e5 j1 X* Z5 a
  9.         {: v6 Y$ x- ~) Y: r! N
  10.             printf("%d",(int)(fSpeedVal*100)); , Y3 h) G# L9 ~7 T4 B+ U9 d
  11.         }  ^( S. `7 h* X
  12.         else if((int)(fSpeedVal*100) > 99)
    - u6 H. q& F: a: h
  13.         {6 X5 p: y& w. N/ J. f% O* p7 X+ T
  14.             printf("0%d",(int)(fSpeedVal*100));
    ' c. q9 }/ q9 \! g' a
  15.         }
    9 @& n$ b3 B9 b' B+ _
  16.         else if((int)(fSpeedVal*100) > 9)
    9 w& m* y# |6 j# u
  17.         {
    ! \" Y& ]9 ~- {1 j
  18.             printf("00%d",(int)(fSpeedVal*100));
    ! Z1 ^& F' V9 |* [
  19.         }: r+ V( [- X% a$ z$ e( {+ a! U
  20.         else$ x0 F% ^! Z, l3 k6 g, M
  21.         {
    : A3 o/ a( |8 k8 O9 }* C7 U
  22.             printf("000%d",(int)(fSpeedVal*100));
    ( g& W& m! @7 S; Z- R
  23.         }     
    9 R/ |- x; z' ?# R2 w! P0 `6 y

  24. 4 `- L2 b+ N0 B9 l" I' G
  25.         OSTimeDlyHMSM(0, 0, 0, 80);( k2 M1 U+ @, L9 ^
  26.     }        
复制代码
2 |4 B2 N! n' T$ ]+ B
第二个任务中代码如下:
$ n# w. S; s8 h# r$ _# t: i; m1 P0 w& C" o7 J
  1. while (DEF_TRUE)
    , B4 v% p! q& P1 \
  2.     {     6 i4 T' c/ T4 `( d
  3.         BSP_LED_Toggle(1);    H* L, B$ a9 h# G; h, q0 n+ y& p
  4.         OSTimeDlyHMSM(0, 0, 0, 100);
    " B" ^  ]5 `; j( n- {: }& Z; }
  5.     }
复制代码

, X6 s  s) b# U# Q, [: ]整体运行稳定,满足项目需求。
5 n# K1 ]$ v" H- r1 T
3 b2 }+ G" F/ x0 n9 c( F, ~) s/ N) d# n* K. j5 {) Y# I( o
收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版