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

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

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
测量运动自行车速度,上传给上位机软件,处理VR视频播放。正好公司有现成的stm32f1系列单片机开发板,所以我就想到了使用它来实现这个小功能。& z& z- F6 o9 z/ r# q

' V+ q& s6 H" o3 B% V! W1. 硬件配置:5 m7 y; F- x' {; E& [

+ K- p% L5 d0 e/ E7 b1.1. 运动自行车;
$ y8 {, U- L, X  r* _
$ o) t6 g7 q0 a$ `7 K! O
20180409144730202.png
6 O/ K+ ?; d# Z

8 D2 I6 S/ f; c5 R3 M& \1.2. 磁感应开关与专用磁铁;   
/ y5 M' ?' M# C) b
" y: E& \* }; V
20180409144808136.png 20180409144818159.png

8 \- ~% L( Y5 _( |
  \7 q- ?9 }1 |* L" [1.3. 基于Stm32f103zet6芯片的开发板(七星虫),如下图;
& Z: t5 P* C* J6 s2 {8 a6 i9 K$ d% X- l. q. m) O! C
20180409144832248.png
& H1 M. U% l0 X& s- B0 z
" D! D1 ^6 V: J5 i" N% e4 i
1.4. 连接线若干;
, d- t# ^+ V+ U' x
3 X. h+ R( S5 y! F+ _1.5. miniusb线缆,用于给开发板供电及串口通信。
7 @; a8 J" s  ]- ]' ^9 S/ i6 Z) @4 B$ p, J2 ]' K
20180409144846453.png

( j4 k( T) S3 \' P/ i+ \6 k3 Y) G9 v" u( ?" s2 O. P
2. 系统描述与框图:) Z( x! g& T! E& x& F: p% K
; R# h: m5 t/ P. C$ t
运动自行车车轮上安装5只磁铁,通过磁感应开关检测磁铁产生信号,接入stm32开发板PE0引脚。测量出的速度值通过串口发送给PC上位机软件(mini usb线缆连接)。硬件框图如下:" }% V. i0 ?8 D& L% e1 B: d! n3 y/ X/ V

+ F9 @% |6 P" `1 g
2018040914485823.png

( D4 T: Z6 \$ C) g0 _- ]% \+ Z/ E4 y. V+ G4 }# R) X  S! f
; w0 O. ~, }9 K8 O( [6 O
3. 软件实现4 v( _" _1 K- y
% T8 Z: L/ ~0 G5 w- q
3.1.设定开发板PE0引脚下降沿中断,在引脚中断服务函数里累计中断次数(即磁感应开关感应到磁铁的次数),同时每累计10次LED2交换一次状态。外部初始化代码及中断服务函数如下:: Z1 V# m- [# ]- O/ f/ X
& l6 P( T* p+ u; \4 {6 {5 J
  1. void EXTIX_Init(void)" e7 I1 l6 p% R2 f; j+ ?1 y
  2. {
    ' f$ D  Y  }4 e7 @4 H
  3.     EXTI_InitTypeDef EXTI_InitStructure;
    4 ^  Q1 M: C5 c$ C
  4.     NVIC_InitTypeDef NVIC_InitStructure;
    5 M; c4 a1 L- r) m) ?$ w' ^4 @! m5 F
  5.     GPIO_InitTypeDef GPIO_InitStructure;6 n3 `* B( C. y! O+ T
  6.     //  引脚端口初始化 PE06 W5 @3 k' u9 g; Y
  7.     GPIO_InitStructure.GPIO_Pin  = DEF_BIT_00;/ G) h+ A& l# U- B/ v& o
  8.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;& l$ v9 T* q; a& p7 H
  9.     GPIO_Init(GPIOE, &GPIO_InitStructure);    ; \% I0 M# G5 M7 y' T( |
  10.      // 启 AFIO 时钟
    ) n; \7 b5 U4 r, u' E3 [) Q$ S
  11.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    * h6 ?. R/ n; L; E2 ~
  12.     //GPIOE.0 中断线以及中断初始化配置,下降沿触发3 }4 F, f: L! T5 `
  13.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource0);// 配置中断线为0
    ' f( U7 M* O2 S2 {( J; B
  14.     EXTI_InitStructure.EXTI_Line=EXTI_Line0;' m3 m6 E6 I1 M
  15.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;/ A$ X- E# z4 F2 q
  16.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发2 u8 S: I! r; a2 ~9 ~2 T
  17.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    ; d# W) ^0 K) w! ^, N
  18.     EXTI_Init(&EXTI_InitStructure); // 初始化中断线参数
    9 `; G1 n9 h1 v- d+ A6 I  U

  19. - y) Z7 V. [8 d" c/ C) E* [
  20.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //使能按键外部中断通道
    " T. ~- Q+ T: F; k3 O  H) W
  21.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级 2,
    , h3 [; d- q( w% U- P
  22.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;           //子优先级 2& _% a% C' u1 h1 C! n: _
  23.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //使能外部中断通道
    $ n6 }9 x8 F! Q
  24.     NVIC_Init(&NVIC_InitStructure);                                 // 初始化 NVIC; r: t" N" ~) Q
  25. }) c) [- M$ {; U! z! U
  26. // 外部中断0服务程序9 `- f( N' }- j! _
  27. long long lSpeedCnt = 0;$ Q. k& `( q& o& V' t. a1 @! P9 z
  28. void EXTI0_IRQHandler(void)" D% g0 V+ W6 L) j) \& u
  29. {% B6 q, S$ r1 G( {% I6 M3 Q, F
  30.     OSIntEnter();             // 告诉ucosii系统进入中断
    . O+ R" ?1 X% F9 l* _
  31. 3 C& E4 Q+ n, S5 I& e
  32.     if(GPIO_ReadInputDataBit(GPIOE, DEF_BIT_00)==0) // PE0检测到下降沿* Y9 L3 a$ c, U" a: R
  33.     {' a$ o" |1 S0 }% F3 k2 |* v' t, D
  34.         // 累计中断次数,每隔10次改变led1状态4 _4 l( l4 N6 C( y; F1 P7 F
  35.         if(!((lSpeedCnt++)%10))' d5 W: Z8 O& D; x* Z
  36.         {
    9 v; e" M2 ^, T) ^/ _
  37.             BSP_LED_Toggle(2);* S6 p4 u+ O4 D1 ]) T3 d
  38.         }
    / q/ V) ]* h1 V( A! q
  39.     }$ {& r  b# N( `4 }% j+ R$ c
  40.     EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE0上的中断标志位
    , z. L2 k* U* {& p8 I0 I) w

  41. 5 l1 V3 ~8 |) R: g
  42.     OSIntExit             // 告诉ucosii系统退出中断
    ! f7 O  q) ~9 R/ {3 n" G* X
  43. }
复制代码

' n2 v" f5 {7 ]8 w: L4 i' H
+ k$ _! v  b4 v) }3.2.在启用一个定时器中断,周期为1s,在定时器中断服务函数里计算自行车的速度。计算方式如下:v = p / μ * C,其中:v是速度:m/s,p是磁感应开关感应频率, μ为车轮上安装磁铁个数:5,C为自行车车轮周长:1.38m。定时器中断初始化代码及中断服务函数如下:
% O& j1 F' _' r' x! I6 M1 }9 k  P  M: w* x- _: W1 f
  1. /*******************************************************************************" \& i7 ]+ g0 V* n) t
  2. * Function Name  : BSP_TIM2_Init7 }9 m  z  H5 R9 C0 g
  3. * Description    : Compute return latest speed measurement
    # N) C$ P! T, i5 O  {: {" d: I
  4. * Input          : None
    ; j6 K) E- h& `/ `$ E
  5. * Output         : s16" y% ~! m6 f& ?7 a, _$ W  G
  6. * Return         : Return the speed in 0.1 Hz resolution.                    & K3 @3 y, @0 b: _2 ^3 Z2 Y# G
  7. *******************************************************************************/7 r% B" q. C5 K
  8. static void BSP_TIM2_Init(u16 arr, u16 psc)
    ( w5 F) ^# |! F% V2 ]2 l/ H
  9. {) U4 q; M  y0 ^9 F7 G3 P
  10.     TIM_TimeBaseInitTypeDef   bsp_tim2_init;   
    . I- N: x* H1 H+ B9 j5 X2 O
  11. ! z0 T$ L' l0 g4 ~" {+ Z2 z/ |
  12.     //使能TIM2时钟
    / d' G0 ~6 Y% N
  13.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);4 t, j, G9 x1 ]# |7 I$ _
  14. " Q$ ?" {0 T9 O% [
  15. & \6 y" s  U$ p/ U/ N0 s' c$ e
  16.     TIM_DeInit(TIM2);
    8 M6 T/ u2 ^( L
  17.     TIM_TimeBaseStructInit(&bsp_tim2_init);3 k8 w, _) z6 E
  18.     //TIM2初始化
    * C: e7 H& P+ b2 e" k1 k
  19.     bsp_tim2_init.TIM_Prescaler = psc;                                          //时钟预分频   定时器每隔 (psc+1)/72 us计数一次
    7 @. N) Q6 Z- ]1 J, k5 U% @
  20.     bsp_tim2_init.TIM_CounterMode = TIM_CounterMode_Up;                         //向上计数: [& y0 b5 P! N6 l
  21.     bsp_tim2_init.TIM_Period = arr;                                             //计数满(arr+1)次更新重装载寄存器数据
    / f6 p! v  o' A7 t
  22.     bsp_tim2_init.TIM_ClockDivision = TIM_CKD_DIV1;                             //时钟不分频
    . S4 a" o" [$ J7 o
  23. //    bsp_tim2_init.TIM_RepetitionCounter = ;                                   //高级定时器用,这里不需设置
    6 X2 Q' _" O; ]: Z: [3 a
  24.     TIM_TimeBaseInit(TIM2, &bsp_tim2_init);                                     //初始化定时器9 v+ T5 D) |2 f% o. D/ Q' I. j  j
  25. 0 ^  }( D( @( [- {- v  e" a* k
  26.     //设置定时器TIM2中断# T5 q* {& E! U8 t
  27.     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);                                  //设置定时器更新中断
    # [- c& M/ @/ S* `+ G
  28.     TIM_ClearITPendingBit(TIM2, TIM_IT_Update);                                 //清除中断标志,防止刚上电时进一次中断
    * D! Z2 n, P$ i2 U: B6 g9 C
  29. " ?* o. g0 Y& k$ z7 ~+ d
  30.     //初始化中断
    $ [% V) f, s% Y& b8 w
  31.     BSP_NVIC_Init(TIM2_IRQn, 3, 3);
    ; b, G. Q1 Q; p+ k8 U% S
  32. & ^. @. V8 ]& s) [. F  k) a
  33.     //使能定时器TIM2& J9 h. U" r6 N
  34.     TIM_Cmd(TIM2, ENABLE);
    ) t# W4 \9 c+ K! T/ f0 {3 Y" M$ K5 S( F+ T
  35. }
复制代码
  1. long long lvalCur;3 Y* O% b+ H1 m" S" p' s9 D
  2. long long lValPrev;
    3 I$ j' j* o6 J2 o$ V1 b% C
  3. float fSpeedVal;2 @( D0 G2 A9 h+ o; n
  4. void TIM2_IRQHandler(void)& H' f; W" N; v% o
  5. {
    " o* n  K9 _* n; D. `- q! g" `9 @
  6.     OSIntEnter();             // 告诉ucosii系统进入中断. v, G& V7 e, T9 l
  7. ! L" L* C( h" ]" \+ P; J
  8.     if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)/ a, U! d" y5 P, T) S2 ]! a( k
  9.     {      , {/ v" r% K6 @
  10.       extern long long lSpeedCnt;" B& p6 B8 g6 I( A5 ?- ^
  11. 6 O3 `& f/ Q$ o5 V
  12.       lvalCur = lSpeedCnt;4 g7 n1 j# A2 n
  13.       fSpeedVal = (float)lvalCur - (float)lValPrev;
    7 Z6 i. g* S4 Q7 p
  14.       fSpeedVal /= 5.0;0 L  u7 o7 [. C) |. R
  15.       fSpeedVal *= 1.38;      
    . i( N; `& x, ]
  16.       lValPrev = lvalCur;
    3 A3 S0 U1 ?( ~# q1 S
  17.       TIM_ClearFlag(TIM2, TIM_IT_Update);
    7 r& r) @6 S! Z! P2 Q- g
  18.     }1 L" M  A9 o8 s- T" p+ t1 M3 v, s
  19.     OSIntExit();             // 告诉ucosii系统退出中断8 z# |4 ~0 e8 ~' l6 H% s- ?
  20. - t, i- |: o# `, g, l1 @
  21. }
复制代码

. F, L+ Z% o+ F, @' }, \9 y3.3.系统共有两个任务,其中一个任务每50ms发送一次速度值给PC机,另一个控制LED1闪烁,周期100ms,用于指示系统正常运行。9 V  v* q! a" X. K, O4 |
; ], ^9 V% R& V; Y% X' s( k
第一个任务中运行代码如下:- N( i! C: t0 y/ a' B/ x( G1 M# R

, x+ B9 a5 C1 s2 t: A# V+ P! D/ F* z% R
  1. while(DEF_TRUE)
    . ]. a2 y; y" r6 Y
  2.     {              
    ' y$ M6 z) H) ?8 D/ E) m$ S
  3.         extern float fSpeedVal;7 I+ ~# d! a4 ~9 s8 E2 h1 B8 o2 O
  4.         if((int)(fSpeedVal*100) > 9999)4 j% I! ?  `. Y2 p/ o
  5.         {1 x: v, c5 B3 [! X4 l
  6.             printf("9999");
    . h6 m- N! R9 S, u6 U
  7.         }0 B: _. f$ r8 D- n8 z4 a
  8.         else if((int)(fSpeedVal*100) > 999)! G' j  [* ^/ M' h
  9.         {. B* C4 J4 K  W7 @- B7 V: Z) [
  10.             printf("%d",(int)(fSpeedVal*100)); % I; i+ V2 y, r
  11.         }: R! Z% T7 W: `
  12.         else if((int)(fSpeedVal*100) > 99)
    ' X' A5 |& p$ v- l$ |# }' W
  13.         {# S4 `5 r4 L+ Q! U) f
  14.             printf("0%d",(int)(fSpeedVal*100)); 4 i- M  M' T9 p, c  Y1 C; [
  15.         }$ p$ q, L9 Q, ~& [/ L  ?6 M
  16.         else if((int)(fSpeedVal*100) > 9)
    3 d4 ]' l% @  j. M, @9 V" i+ o
  17.         {
    0 y2 i& Z: _1 w4 w% s0 \+ e
  18.             printf("00%d",(int)(fSpeedVal*100));
    8 [0 f# y+ N: y5 Y2 f
  19.         }" W, E3 s* A4 f: j+ H, ]1 q9 z
  20.         else
    ) j% D7 A' i2 l5 _7 T
  21.         {
    ( J9 x3 P. j- k- r" c# R
  22.             printf("000%d",(int)(fSpeedVal*100));
    0 h, q  y& M5 |  }
  23.         }     
    ) ]3 V; E4 V7 \$ V/ k

  24. 7 r# \3 ~7 Q$ g, V) G
  25.         OSTimeDlyHMSM(0, 0, 0, 80);  k2 `* i, ~/ O% a7 p
  26.     }        
复制代码
7 R  A& O/ [; L! l+ n: Z# y& ~
第二个任务中代码如下:
5 a' `- b' d! k! E8 [
9 A  y6 w: b' [0 g3 r
  1. while (DEF_TRUE)- F9 |# Z' h& i( P: X% `% k4 h+ Y4 o$ d
  2.     {     . ^( _0 {3 @8 f/ K
  3.         BSP_LED_Toggle(1);  
    5 Q# P; K# e* p+ p% |) c8 r4 A
  4.         OSTimeDlyHMSM(0, 0, 0, 100);
    + t; o; ?9 N0 Y
  5.     }
复制代码
& j& l& ^0 x9 \$ e
整体运行稳定,满足项目需求。
# s# a  F0 g; N% J& J
' O& l' Y1 S2 P  D4 ~1 w4 u! R
1 j) _' i$ ]$ [
收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答

所属标签

相似技术帖

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