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

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

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
测量运动自行车速度,上传给上位机软件,处理VR视频播放。正好公司有现成的stm32f1系列单片机开发板,所以我就想到了使用它来实现这个小功能。2 E" ~; V" h, s, l" t$ [& s4 m5 M
$ @& ?/ w/ c+ _  ?/ j2 B( W
1. 硬件配置:
2 w0 I. ~- D& W$ I
1 R$ l7 T: Z' C, h: y1 T" q4 \1.1. 运动自行车;1 E  v9 F. J( X! A
  P/ L* \* n) M: J. `0 L$ x# k4 z
20180409144730202.png

; s: P- [- e) Q& W! E8 y8 b
0 ~4 K: }0 E* ~' ?1.2. 磁感应开关与专用磁铁;   
5 R1 X0 c: h$ W- c- [# v0 z2 Y
  h0 Y) a4 @+ h' ^* e/ x
20180409144808136.png 20180409144818159.png

6 i/ G/ |0 h. P/ ]3 W" N; h5 ^6 i$ B1 p4 n, _
1.3. 基于Stm32f103zet6芯片的开发板(七星虫),如下图;
2 l* R5 V; a$ ?4 B
* Z/ K6 g  w% O) ^( o: f+ b
20180409144832248.png

; h3 ^: U" r" a- S0 _  f1 |, g- A2 B  n
1.4. 连接线若干;
+ @0 J  e" q" R3 U
" @1 p- m3 R6 q" ~1.5. miniusb线缆,用于给开发板供电及串口通信。$ p" o. v* ^0 O9 a6 u3 \& ^, P
7 u8 g' C+ s/ \8 b
20180409144846453.png

9 u( L" h. d+ @
1 g: y, d' V$ J& @+ E2. 系统描述与框图:- y3 g; O% S' i, @5 N3 E1 ?

! Y, t* C8 i1 Z  p# I2 h5 h; y运动自行车车轮上安装5只磁铁,通过磁感应开关检测磁铁产生信号,接入stm32开发板PE0引脚。测量出的速度值通过串口发送给PC上位机软件(mini usb线缆连接)。硬件框图如下:
( D  T5 Y! T& ]1 @- V$ C8 Z1 |( p  p1 n2 @0 ?! T2 u8 C4 ]5 f
2018040914485823.png
; e0 Z9 d. h% V4 i

4 A+ |+ F2 B, }) v: d+ X: P2 l% T" I7 A7 r5 j, y) J+ d6 a2 p6 H
3. 软件实现( R- D+ Q8 A2 D) U# ~# H5 Y

' U$ v' t+ q9 c6 U) y5 ~8 D3.1.设定开发板PE0引脚下降沿中断,在引脚中断服务函数里累计中断次数(即磁感应开关感应到磁铁的次数),同时每累计10次LED2交换一次状态。外部初始化代码及中断服务函数如下:
7 q9 X! ?" I7 l2 x3 j% f
2 Q  D% }& Z3 X! c; J
  1. void EXTIX_Init(void)
    ( Q- w! S6 K0 ^: v
  2. {
    # Q* H% X) q  F1 G* u2 ~* X8 \# E
  3.     EXTI_InitTypeDef EXTI_InitStructure;
    . I* g* P( y/ G  T; _- e
  4.     NVIC_InitTypeDef NVIC_InitStructure;
    ' c% r6 u8 R. K* u( ?
  5.     GPIO_InitTypeDef GPIO_InitStructure;
    ! w$ U( |! q1 J0 \
  6.     //  引脚端口初始化 PE0
    * P  U! u6 z9 a* u
  7.     GPIO_InitStructure.GPIO_Pin  = DEF_BIT_00;7 Z3 Q6 l6 p: \* k( l2 z) o
  8.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;8 @, ^7 L2 w$ p9 O& t! ]
  9.     GPIO_Init(GPIOE, &GPIO_InitStructure);    8 a) |0 `0 ^5 V; r6 ?
  10.      // 启 AFIO 时钟4 `4 q3 k7 k6 \2 z
  11.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    / p4 V7 i% g0 g
  12.     //GPIOE.0 中断线以及中断初始化配置,下降沿触发
    & Z* T5 F7 Y% p1 n9 S% b: X
  13.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource0);// 配置中断线为09 v' O# b) d2 A* S7 E  g! n  B
  14.     EXTI_InitStructure.EXTI_Line=EXTI_Line0;
    + G& X( k+ U3 s: o! S$ s
  15.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;. Z+ T# X  z" U- Q" Q5 w8 l; I
  16.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发; p- N' v6 N/ V, w. @3 d
  17.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    5 ^) [  n$ t: @# [3 p; |, C3 c
  18.     EXTI_Init(&EXTI_InitStructure); // 初始化中断线参数* E$ G) Y" s- O3 Y' }
  19. 8 H) g6 X6 g" V* |- ^
  20.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //使能按键外部中断通道
    " |, j0 h% I- {) _. D
  21.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级 2,8 T+ G1 H4 ^* k+ j& C* x0 p
  22.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;           //子优先级 2
    . r. ]' H" U* b+ f2 q* w3 v; r: `
  23.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //使能外部中断通道- J9 ^, A1 g! M0 ^) O# D
  24.     NVIC_Init(&NVIC_InitStructure);                                 // 初始化 NVIC
    ; Q8 _! e% K2 S4 X
  25. }- U7 z) s& y- k& o0 @8 p9 Z
  26. // 外部中断0服务程序
    - r" l  |& w, H: D: x/ g
  27. long long lSpeedCnt = 0;* P# y$ _4 T9 y! h
  28. void EXTI0_IRQHandler(void)
    ( _! n$ c4 B% R" M3 h  g8 m
  29. {
    " _7 C0 u5 _3 S; h- G. e
  30.     OSIntEnter();             // 告诉ucosii系统进入中断
    1 H" G1 }& I6 n4 @

  31. 3 D) b. ?1 W" z: \/ I  b/ f7 q8 {$ V
  32.     if(GPIO_ReadInputDataBit(GPIOE, DEF_BIT_00)==0) // PE0检测到下降沿% O  T8 }* p" P$ c3 g& Z
  33.     {% F$ W& ~) `1 [
  34.         // 累计中断次数,每隔10次改变led1状态* z7 p% }4 A$ d% _$ B
  35.         if(!((lSpeedCnt++)%10))
    ; Z% \2 n) d9 p, u8 `! o; Z
  36.         {- F$ v4 g0 y4 U+ S/ {
  37.             BSP_LED_Toggle(2);. n: `4 u( m0 C- S4 H" d/ m
  38.         }- C+ N% y/ L  k0 V" f% X; O' X
  39.     }/ }" @% V  V; p1 `! v& {
  40.     EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE0上的中断标志位6 K% L& e2 e* Q6 ^2 g8 j0 s0 W6 W5 a
  41. ' B7 l. [0 g% r: i2 C" N
  42.     OSIntExit             // 告诉ucosii系统退出中断6 y8 C# c' e) y" o
  43. }
复制代码

( Z! I! k9 O  A: |: o' p0 G1 p, R# L- N2 A" n% T5 w& l
3.2.在启用一个定时器中断,周期为1s,在定时器中断服务函数里计算自行车的速度。计算方式如下:v = p / μ * C,其中:v是速度:m/s,p是磁感应开关感应频率, μ为车轮上安装磁铁个数:5,C为自行车车轮周长:1.38m。定时器中断初始化代码及中断服务函数如下:9 T1 I. O# H6 g
) \% ^' ~1 a' _! l/ i' X0 ]) F
  1. /*******************************************************************************3 g$ Q! j( F4 z' K' E% u/ @
  2. * Function Name  : BSP_TIM2_Init
    ; ]5 s7 I, \! e6 J1 [9 H
  3. * Description    : Compute return latest speed measurement
    0 c( J6 ~0 H- \. v% D$ m+ S
  4. * Input          : None8 `- B# h8 Z  ?- x
  5. * Output         : s16; t. T6 B* \  S3 X5 u, j
  6. * Return         : Return the speed in 0.1 Hz resolution.                    
    / p& ]1 O. Z7 ?8 ^1 _! r" _
  7. *******************************************************************************/2 |% P6 n0 t2 n" l% l' m- H
  8. static void BSP_TIM2_Init(u16 arr, u16 psc)3 V- d% G' j' ?9 C0 o! m$ R+ ^
  9. {
    " u. Q8 `! W, _$ X+ j" C/ H2 j
  10.     TIM_TimeBaseInitTypeDef   bsp_tim2_init;   
    5 P7 }$ X; `. O- |+ x: L9 c

  11. 3 ?9 R7 T! u! [5 W! [1 l7 z
  12.     //使能TIM2时钟
    ( r6 `% h; K2 z; q% {
  13.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);5 r% k/ |( O% g9 e& S6 R

  14. % b$ n+ |$ d2 C: ?/ l* q) f
  15. 3 w# X: B. {/ l3 f; n3 x0 M
  16.     TIM_DeInit(TIM2);& j" @+ B( @  E. V- M6 a5 s
  17.     TIM_TimeBaseStructInit(&bsp_tim2_init);
    % o- Z, P5 R  x: P2 T! `
  18.     //TIM2初始化
    $ F! {6 O; _: G) }
  19.     bsp_tim2_init.TIM_Prescaler = psc;                                          //时钟预分频   定时器每隔 (psc+1)/72 us计数一次" B/ y  U& N, I, m( K5 m
  20.     bsp_tim2_init.TIM_CounterMode = TIM_CounterMode_Up;                         //向上计数& r5 q2 Y7 r1 J
  21.     bsp_tim2_init.TIM_Period = arr;                                             //计数满(arr+1)次更新重装载寄存器数据
    ; `: `6 G; O1 k; H. z+ G
  22.     bsp_tim2_init.TIM_ClockDivision = TIM_CKD_DIV1;                             //时钟不分频
    / C8 _& B) X; Q; V
  23. //    bsp_tim2_init.TIM_RepetitionCounter = ;                                   //高级定时器用,这里不需设置* K: r. L: h! M7 e! ]- ]1 M
  24.     TIM_TimeBaseInit(TIM2, &bsp_tim2_init);                                     //初始化定时器+ ?$ q8 F2 H& \

  25. ( m2 ^3 \( x6 @
  26.     //设置定时器TIM2中断
    7 l% L2 f3 }8 X- k9 E$ J
  27.     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);                                  //设置定时器更新中断* q0 I- N% j( g
  28.     TIM_ClearITPendingBit(TIM2, TIM_IT_Update);                                 //清除中断标志,防止刚上电时进一次中断
    & i. a2 P4 U/ Y9 O0 i
  29. 0 t# g: `& `, b$ [2 Y
  30.     //初始化中断
    4 W9 B1 g* f! I; |
  31.     BSP_NVIC_Init(TIM2_IRQn, 3, 3); & n% @, @8 ^8 x" h- v; C

  32. ' B- V7 m0 o% }6 n
  33.     //使能定时器TIM2
    % F+ X  s6 A6 |! d/ [8 U
  34.     TIM_Cmd(TIM2, ENABLE);
    2 l0 o8 j; n) ?. C
  35. }
复制代码
  1. long long lvalCur;
    ' Z4 s, m4 T0 C1 I, s' @
  2. long long lValPrev;
    9 v& M; L, q2 j# V6 n
  3. float fSpeedVal;. o; A: L% K. M7 S4 c# P
  4. void TIM2_IRQHandler(void)( g+ W4 t1 m8 t/ n4 ]
  5. {8 ]( _+ s- D/ _: N* G( `6 [6 g
  6.     OSIntEnter();             // 告诉ucosii系统进入中断* ~7 Y3 m: L8 Z, ~! |7 h# M: x

  7.   {' H8 V* L3 G8 Q
  8.     if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    3 i7 q/ q# @# Z4 N) V$ H
  9.     {      1 @7 w$ X$ _; p; |2 ?4 z
  10.       extern long long lSpeedCnt;9 M% n+ G3 B4 B
  11. $ ?% O. z: _% l  I1 |3 e# C
  12.       lvalCur = lSpeedCnt;) U% I2 V9 O4 ]
  13.       fSpeedVal = (float)lvalCur - (float)lValPrev;
      v7 y3 f3 W; v. k0 L/ \4 j/ ?
  14.       fSpeedVal /= 5.0;
    7 |( G2 q% u; y. H
  15.       fSpeedVal *= 1.38;      
    / {, o7 W; o4 m8 s+ _( R" g; }
  16.       lValPrev = lvalCur;
    ' n5 b2 ^5 D! v/ W
  17.       TIM_ClearFlag(TIM2, TIM_IT_Update);
    ; B4 O- \% u: Z3 k# n
  18.     }# a% b" C  X$ I$ k  v0 H
  19.     OSIntExit();             // 告诉ucosii系统退出中断
    $ F; M" [, `6 f) j
  20. ! c, p. B0 z' k8 s* P
  21. }
复制代码

0 y5 W9 {4 L! p7 M$ ~0 z( Z8 a% y9 Q3.3.系统共有两个任务,其中一个任务每50ms发送一次速度值给PC机,另一个控制LED1闪烁,周期100ms,用于指示系统正常运行。
( b( P2 k$ n' H
: D" N* s- x* x% w第一个任务中运行代码如下:4 o/ `6 ~8 m: J' E; I- T
* |  ]0 n% R% X
  1. while(DEF_TRUE)
    . r0 b# Z) k6 ^  [- W! Z
  2.     {              # e* [2 M# z4 l
  3.         extern float fSpeedVal;( B0 ]3 O% G8 _; i# ~% X% p, O
  4.         if((int)(fSpeedVal*100) > 9999)
    + l. u6 u0 M* U2 H
  5.         {0 g- r4 J- V" j% \8 @/ ?* p9 _4 `
  6.             printf("9999"); 1 R3 I* _8 V7 D, j# J
  7.         }0 `% L/ E2 H; e3 Z
  8.         else if((int)(fSpeedVal*100) > 999)
      H1 q! b0 e& j9 C
  9.         {
    ( z0 ?& Z3 j* y( y8 {, `9 l
  10.             printf("%d",(int)(fSpeedVal*100));
    - |: v- q6 m; C/ R! j5 {! F3 t
  11.         }. y. R8 P3 R, |) B, t
  12.         else if((int)(fSpeedVal*100) > 99)# w2 U$ L/ v" a' b! W
  13.         {# K/ Y3 Z( d9 Z+ i( ~3 N( B" }6 U( F+ o
  14.             printf("0%d",(int)(fSpeedVal*100));
    # i. [5 ^& v# k
  15.         }1 }6 ?) P7 ^2 }6 K/ {6 {  `
  16.         else if((int)(fSpeedVal*100) > 9). M6 w& b" B: @& T) b7 V* r
  17.         {4 ?6 Q: `4 T# U% V0 _( e
  18.             printf("00%d",(int)(fSpeedVal*100));
    - X. j7 p$ F+ B$ O$ U
  19.         }
    ( }* e  b: u6 y7 S1 U
  20.         else3 M- O2 I5 h9 M7 {7 G& @9 S
  21.         {
    9 n$ ^  S  Q- U* D* ]* G
  22.             printf("000%d",(int)(fSpeedVal*100));
    & p; r4 N1 `/ F- g, I
  23.         }     1 @) V4 G& y( n* K; [& q# K
  24. 4 a. R5 Z. T* X8 H' q' O6 C
  25.         OSTimeDlyHMSM(0, 0, 0, 80);4 f8 R$ i9 D) J4 g& X: G
  26.     }        
复制代码

7 G: Q! v* O- [$ S第二个任务中代码如下:
. `2 q4 c/ P2 l$ _; b( @
0 \& ^' @' n0 Z3 M
  1. while (DEF_TRUE)6 u5 D  j: \! \% O
  2.     {     
    ) `% Y& i- w" v" E; P: f; M
  3.         BSP_LED_Toggle(1);  
    ' e- O5 P2 y0 S3 }. @, q
  4.         OSTimeDlyHMSM(0, 0, 0, 100);7 _( Y+ o5 L, K" T4 R( |$ Q+ G
  5.     }
复制代码
! r4 D* v, T$ g# \9 u9 C/ Z
整体运行稳定,满足项目需求。. |5 f. `5 t$ B3 o% _1 w! J

) j8 z! y6 Z4 O4 l
; [- L8 d- O8 {. g9 {) A
收藏 评论0 发布时间:2021-11-26 17:00

举报

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