请选择 进入手机版 | 继续访问电脑版

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

基于STM32CUBEMX的程序时间计时器(简单易用)(STM32L496)

[复制链接]
tsuibeyond 发布时间:2018-5-28 13:15
本帖最后由 tsuibeyond 于 2018-5-28 13:18 编辑
/ g) t4 V$ C: d" L5 H) Y( o& A( |5 y5 m/ i4 q: c" H  C
很惊喜收到STM32L496,只写了关于它的一个帖子,实在有点少,这里补充一个自己常用的一个程序计时器,基于STM32CUBEMX,很简单方便,也很实用,希望各个技术坛友喜欢
( q$ Q5 q) \7 ]# h  T! ], N) f2 c" {0 V2 Z  G/ s2 @
这个是我上个帖子的地址,https://www.stmcu.org.cn/module/forum/thread-615906-1-1.html,本部分内容是基于这个帖子的工程实现的。& p3 q* [0 [( g7 ?

- h2 p" r- l) s9 I% [% k8 ]9 h注意:
! F4 L, F, A5 i' C0 n7 cRTOS有点占用heap,所以,需要修改写heap大小配置7 u7 a) l: Q: [6 t2 d' E; @9 Z8 d
我的:) M5 n$ f. J! i0 T" U6 B
1.png
5 f3 \; E+ W! \' J( O 4.png & H0 _$ p+ g3 n: Z
最后,这里就不会出问题了! b+ ~1 K$ k: ]' q
3.png + A  x2 A) w/ U, S
$ B) T/ j3 I" v  p, o
回归正题
" J# N- O) k0 E4 b0 y我们的功能是基于心跳定时器的
: @" Y' L/ Y4 Y0 `) G 2.png
' T% ~. E1 |1 W$ [2 L1 p+ x! v# I
+ F% k) F/ {. q& A1 q5 [: l6 a在工程上添加文件3 [+ {4 A: p/ s% B
time.c2 ]" B9 S. L4 L! `8 }! }
#include "time.h". {& J2 \0 B% W4 |' @: [
#include "stm32l4xx_hal.h") S9 U9 P, K0 ?. [& B2 |- [

. Q* p5 Q0 P+ evolatile unsigned long long sysTickUptime;
% j9 e& g0 ?) m" v0 U! ?float cycle_T[20][3];& a) l. m" x  @% r0 c8 t% _
unsigned long long time_consume[GET_TIME_NUM][2];! Y$ T5 N# o1 _; }1 U
int task01_time_comsume_us;- w, {" T( o# \6 X) _- ~
int task02_time_comsume_us;8 B3 T% ^4 t  D" H) f
int task03_time_comsume_us;
0 O& H, V: h& G& ]% R6 \% f; W( ^+ HDet_t det_t_s;
( D4 n0 K, [  ^, }" @1 U$ L0 h+ X7 D+ K
float get_cycle_time(int item)7 s& s2 d' K7 ~& f
{
( ?' s, j- W% K8 A) T  cycle_T[item][OLD] = cycle_T[item][NOW];    //上一次的时间
- y7 @& N/ C; `; e2 f  cycle_T[item][NOW] = get_sys_time_us()/1000000.0f; //获取当前时间
, b$ ^1 X9 H$ G2 |4 k) N8 `9 b; V  cycle_T[item][NEW] = ( ( cycle_T[item][NOW] - cycle_T[item][OLD] ) );//获取两次时间差4 _. m2 I3 n7 ~! q9 g! w3 |
  return cycle_T[item][NEW];
4 U6 V2 m+ d' V3 g+ ?$ F5 T}* G! i# T2 C) I0 k% G9 P

3 M$ ^) Q) U6 r. vunsigned int get_sys_time_us(void)' }/ Z& C: u2 W' p
{6 ~6 G2 w# g; V, M) k6 Y) r  ?
  register unsigned int ms;
6 C# V' P3 |' _6 T3 t  unsigned int s_load;* G, W$ ^- ]# x; R
  unsigned int s_val;
0 l/ p9 J: k( |" }0 o  unsigned int value;
+ g2 o+ e  j+ C; ]4 j  s_load =SysTick->LOAD ;1 `4 Y# B# m0 P9 Y1 z/ s1 u
  s_val=SysTick->VAL;4 l; e7 x- i- E' ]6 \7 e2 M
  ms = sysTickUptime;
2 _- \; g8 A+ ~) t8 `1 q  value = ms * 1000 + (s_load - s_val) * 1000 / s_load;//获取us级的计时% P: U& [: g3 o% U; Y
  return value;
: K+ t3 i) ^# r& m}
/ F7 R& s% z# F  Z, ^  V2 n* {1 j% l+ V4 z. I& _/ G8 u
void time_inc_tick(void)  //在心跳中断中添加,每一次心跳,执行一次
! e. ^# Y7 V5 V3 T' F{: A" X" J" m# w3 Q! t1 u
  sysTickUptime++;9 O1 b' N+ m- {3 x3 K. Q  k/ Y
}
( U( c' ]0 ?$ h) I; g7 f0 f% s

" n. H8 U( `+ G6 d7 N4 W* g: I0 Z9 e8 A1 P
time.h0 {. }2 k" ~9 L5 d# S
#ifndef __TIME_H_2 y, S: x, j2 r
#define __TIME_H_7 n# ]; j. M* O
; |1 S7 Z2 F' N% r0 D' D
#define GET_TIME_NUM     10        , s. v. ~! t$ _& n# |  n
enum1 F: r5 e- j9 s7 i+ m1 j! p
{
% L) p4 j1 Y# O8 i' x6 E& ~  NOW = 0,( B7 \7 L: w5 @
  OLD,
/ l- Q/ f( [6 e/ P# @' ?& ^' T  NEW,% E) x+ h: Q  n# g) F
};
) B8 O: K, v( m8 e9 oenum
) W0 V# k0 Q0 y{: J6 `' G! l5 G$ D) ~# {
  task01_index = 0,8 w1 ]/ E! J; ?2 u! W, ?
  task02_index,
& f3 T: I/ A* A  R7 p5 Z  tasl03_index,; f" ?0 e0 L) f9 E
};
5 [! x+ C  W% q! O7 Y4 e/ {9 ptypedef struct+ f, d9 w* ^6 Y2 m1 p- v9 o
{2 l8 S( X2 ]7 u" W( x$ q  t) R
    float det_t_task01_s;
" o- ]+ H) w. c7 y! L7 [        float det_t_task02_s;
/ I9 b; J& y( [9 A- Y: u        float det_t_task03_s;4 |' A' f2 P- b% E6 R8 U: W' ~; m$ ?

) U3 f8 C5 l5 V0 f- v1 E* @4 W}Det_t;
) I) G9 O0 S3 h2 vextern Det_t det_t_s;' r6 b4 h( J$ S6 V
extern unsigned long long time_consume[GET_TIME_NUM][2];" L) G9 D  B- k. h0 ~4 f
extern int task01_time_comsume_us;
0 }5 \  k* A- O* c7 ~! dextern int task02_time_comsume_us;
0 O& K1 O8 }7 }9 p' l' r3 |+ Fextern int task03_time_comsume_us;5 f* p4 T: j  P' @) `# N

1 f$ }+ ~  y1 e+ l4 lextern volatile unsigned long long sysTickUptime;2 @; h0 B9 p8 E0 @) f8 r8 p) R
extern float cycle_T[20][3];
+ ~& j9 U. _; Q- R4 L
& n, h( U7 v8 B# [  {extern float get_cycle_time(int item);1 L0 e3 u3 D- S. u
extern unsigned int get_sys_time_us(void);, X! a+ c$ w% d9 l: U1 B
extern void time_inc_tick(void);# ?+ C% b+ S7 c  o, P9 B

0 s! c+ K' x: d#endif. v9 ~1 q" r6 C6 R" m

8 S1 t# A+ [/ Z' K: l5 y+ ^1 F! m9 @& J) n' W1 g
在stm32l4xx_it.c中补充void SysTick_Handler(void)代码! c* C; I9 F7 [4 g+ Z, K% X* m
/******************************************************************************/1 ~' L5 U1 F: ?2 ~5 F& U- m# c
/*            Cortex-M4 Processor Interruption and Exception Handlers         */
, ^5 s3 Q& x" U6 }7 W* n) i/******************************************************************************// E9 a8 Y' _4 Z6 x& r! p
3 g. ?; `: {8 \
/**; ]) }! X' _& S7 J. y3 f
* @brief This function handles System tick timer.7 P5 J3 S" e8 w! \  `9 s  N
*/( ~/ y; N( f. d/ K/ ~' t
void SysTick_Handler(void)
. f6 w: i. w  L4 c1 M9 o' J{
8 @! h) d% e. j  /* USER CODE BEGIN SysTick_IRQn 0 */
2 b8 m" d% M  x$ n0 G  K
3 [8 {- L) ^+ N6 U  /* USER CODE END SysTick_IRQn 0 */
4 t( [4 c7 D$ b: K" H* @; l7 C  osSystickHandler();
9 h1 b! _1 X3 V2 z0 N( w( ^  /* USER CODE BEGIN SysTick_IRQn 1 */: ~  r! B0 P% f2 X8 O
  time_inc_tick();
4 Y7 l9 `0 h# n5 h. Z4 t& R' R& S  /* USER CODE END SysTick_IRQn 1 */8 g0 H' f5 y. |! h/ v8 Q
}
8 z# `! ^/ u% f% E8 s! L: m* |  k

$ @2 ?' Y+ @3 f+ z3 |
" f* ^/ p2 [9 S$ q0 d0 \' m接下来,在任务中测试$ R; J( F1 M" a& _4 f
/* StartTaskLED function */2 Q7 E5 l( R- @0 }
void StartTaskLED(void const * argument)! j* j( i/ Q' S; @, V1 N
{
0 a# j' r- r2 g3 p7 S  /* USER CODE BEGIN StartTaskLED */: R5 K  v$ [9 `2 B4 C3 t( f
  //static uint16_t myQueue01_data;
$ J! O  Q7 q8 G/ I, [* ]  Z8 s  /* Infinite loop */) @; y# `  B4 O* e' u! t
  for(;;); ]# t! {+ a9 ~, r8 e
  {# k4 w. C0 B$ S1 ^, ~3 |9 C+ C
    time_consume[task01_index][0] = get_sys_time_us();
( Z' s0 S* Z, f0 ~    det_t_s.det_t_task01_s = get_cycle_time(task01_index);
+ s, A6 @( F$ t; b) q    HAL_GPIO_TogglePin(GPIOB, LD3_Pin|LD2_Pin);
- |$ @: U+ E. W$ r    //osSemaphoreRelease(myBinarySem01Handle);// 释放信号量( b* h; d; F- u1 S; o* o4 E/ ~  V
    //osMessagePut(myQueue01Handle, myQueue01_data++, osWaitForever);7 u7 ]7 g3 f* X
    time_consume[task01_index][1] = get_sys_time_us();% M: L' o0 S' a6 d4 o
    task01_time_comsume_us = time_consume[task01_index][1] - time_consume[task01_index][0];
7 @1 E4 }8 q+ l' E, x    osDelay(600);
1 ^& ~2 w2 H( a- B3 _  }6 o0 ?' o% e5 B* R' p4 P
  /* USER CODE END StartTaskLED */& [2 m4 K9 m2 r! n4 O
}) Q5 |3 I0 j  q  d3 U/ ?
% y% _5 C) Q1 h) H  a! D
; J; j% |: H6 W' T$ T
打开live watch窗口查看(IAR在这一点上比MDK好用很多). j: m* q+ y8 t$ \3 p5 N
5.png % n* o* C4 T9 L
可以看到,task01执行时间为16us,每0.6s执行一次
, ]! X2 x! c4 n& M9 N4 R
# K/ d6 P: m6 `' ^& z TEST.part02.rar (2.66 MB, 下载次数: 4)
1.png
5.png
收藏 评论1 发布时间:2018-5-28 13:15

举报

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