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

STM32MED1开发板例程解析(一):多个定时器链接

[复制链接]
Cody-2045860 发布时间:2013-10-14 15:59
本例程出自STM32MED1开发板附带光盘,其工程目录路径为:\Code Package\Peripheral Devices\06 TIM\0602_Chaining
" n3 [1 y/ E6 J! ?# K" z, U; B4 D3 K% v% ~# j
本例程是使用TIM3作为TIM4的预分频器。下面代码出自timer.c文件。# Z, [* b  C# ?! b
 
: [- ^4 v+ s% x* T5 c6 X: lvoid TIM3_4_ChainConfig(u16 Period1, u16 Period2)- H! C6 I4 Q' D  ~: C
{* j$ X" j- `' ]0 W
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;- i; q6 K9 |# k0 C9 r# o; d
  NVIC_InitTypeDef NVIC_InitStructure;
* v# V4 A$ _7 R) c7 T 
( s/ H* Z: h1 \8 K3 q7 M  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3|
1 ^) J2 j3 y: P, I

, E/ n- b/ r$ V6 D: ~, l                                   RCC_APB1Periph_TIM4, ENABLE);   // 1)
: b  w' a) c; a- i% Y: L2 c7 p $ P8 f) X1 N4 t, O7 F
  TIM_TimeBaseStructure.TIM_Period = Period1;    // 2)* P: s- N& C, p7 o, a0 I  O
  TIM_TimeBaseStructure.TIM_Prescaler = (u16)(SystemCoreClock / 1000) - 1;    // 3)5 ^) k% W, R/ H3 _- t2 P
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
: |& @3 f5 A* Y( L6 l3 ~3 Z6 n+ A  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   // 4)
3 ?, q5 s! c  S: R  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);0 n* h; J0 q% [6 R
 
! B* _/ c7 A. K& g  TIM_TimeBaseStructure.TIM_Period = Period2;    // 5)6 }: J( ?7 o0 l# R. v, [. V1 W
  TIM_TimeBaseStructure.TIM_Prescaler = 0;/ B& f: f0 X( V& V* K) s. f
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  z' G% I0 _) N' V 8 C5 z8 X8 o) |) i5 |* y! D; O
  TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);   // 6)
9 ]8 y! T1 A, t 
7 V" J# j, I9 Z/ K( C+ q( Q  TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_External1);    // 7). F( m" T7 i4 `' ~  h5 X
  TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2);    // 8)
2 P( z8 \2 Z/ K- _ % M; c- e% G5 ~) Z) ~- n
  TIM_ITConfig(TIM4, TIM_IT_Trigger | TIM_IT_Update, ENABLE);    // 9)
2 B! H( i* _# o" y  g  TIM_UpdateRequestConfig(TIM4, TIM_UpdateSource_Global);     // 10)
; N3 t: R7 r  b, b 1 X( v  E8 ]: D2 ]
  // (11
: c3 L' ?% n1 \6 a, K( [  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;+ _4 [8 X9 p1 N  n* U& S
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;) b) F0 n9 o" ?+ m5 g
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;( a/ h5 q) b0 l: i6 P; D3 r7 a. q
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;5 [' m" w  ^: s+ t* n3 N# n
  NVIC_Init(&NVIC_InitStructure);
" f$ C* ^3 t. w7 H  // 11)" x; n) J' [3 o& a" g
 
3 _, e( C" I6 A" z  TIM_Cmd(TIM4, ENABLE);     // 12)1 _8 @* p1 |) M* }) l
  TIM_Cmd(TIM3, ENABLE);     // 13)" j' L. @5 f$ n
}' |0 \$ o* ?0 M: [( Y. P
 ! J# X' z, F( @  d: a6 m
在对定时器的寄存器进行配置前先应通过调用函数RCC_APB1PeriphClockCmd()使能相应定时器的时钟,如代码行1)。代码行2)是设置TIM3的周期,即设置寄存器TIM3_ARR的值。代码行3)是设置TIM3的预分频器值。由于TIM3的从模式控制器被禁止,TIM3预分频器的时钟由内部时钟CK_INT提供。全局变量SystemCoreClock定义于system_stm32f10x.c,如下代码所示:3 |# X- M% r9 t$ `* Z# q# j
 
$ a% q7 c5 e3 @uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz;' e7 L& N2 I- W8 J) N% S( d+ y# E3 M
 
( m4 i" i% X7 w6 v! d由此可见,代码行3)将预分频器值设为SystemCoreClock / 2000 – 1,则预分频器的输出时钟CK_CNT=1000Hz,也就是说TIM3的计数器每1ms计数一次。代码行4)将计数器模式设置为向上计数模式。也就是说定时器使能后,计数器将从0开始计数,每1ms计数一次,计数到TIM3_ARR中值时产生更新事件,计数器将重新从0开始计数。代码行5)是设置TIM4计数器的周期,也就是寄存器TIM4_ARR的值。TIM4的预分频器值设为0,计数模式同样是设为向上计数。代码行6)将TIM3的更新事件设为其触发输出源,代码行8)则将TIM3的触发输出选为TIM4的触发输入,即每当TIM3产生一个更新事件,TIM4就将收到一个触发信号。代码行7)是选择TIM4的从模式:外部时钟源模式1,即将TIM4的触发输入脉冲作为TIM4计数器的时钟。这样一来,TIM3将每Period1 ms产生一个更新事件,此时TIM4产生一个触发事件,TIM4的计数器将计数一次,经过(Period1*Period2) ms的时间后,TIM4将产生一个更新事件。代码行9)是开启TIM4的触发及更新中断。代码行10)是指仅当TIM4计数器上溢或下溢时更新事件。代码段11)是配置并开启TIM4的中断通道。代码行12)及代码行13)分别开启TIM4TIM34 `4 G0 Y; r0 ]" O7 j  T
 6 z3 A: e) Z3 l9 I! ~
下面是文件stm32f10x_it.cTIM4的中断处理代码:
1 d9 n! Y4 w+ V9 V* a, k: ^/ A 
, Y2 n6 X+ r1 h, ?void TIM4_IRQHandler(void)% w  ]# r: A! C- M- y' ~* g
{
8 N  ^7 o& o1 y6 d* q; G5 m  if (TIM_GetITStatus(TIM4, TIM_IT_Trigger) != RESET)  // 1)
5 N, ~0 C* H# d  {
  @  e& M9 ~" `9 Q2 u2 W3 Q8 w    LED_Toggle(LED1);
( J1 K6 a+ e4 x 
0 w+ P" Q  m' R7 z/ N    TIM_ClearITPendingBit(TIM4, TIM_IT_Trigger);
% |# D2 O0 E' k/ _  }
' N+ w. ]" K- h 
8 V! l: w# y# h8 B. q1 d5 V  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)   // 2)" `5 O# P- \7 |0 z9 \$ f
  {
# j5 b" q: f- k- X+ ^2 M    LED_Toggle(LED2);
8 r) d+ ^# d$ v- n5 c 
, M0 x% V/ r2 ?2 ~    TIM_ClearITPendingBit(TIM4, TIM_IT_Update);) o. H& T; {4 G
  }
, G  w9 Z5 U1 |) O+ ?}
  V( G" B- W$ T2 ^8 C, m 
( @& p! O: C2 n0 w代码行1)是判断TIM4是否产生触发中断,若产生了触发中断,则反转开发板上LED1的状态,而后清除该中断的挂起状态位。同理,代码行2)是判断TIM4是否产生更新中断,若是则反转LED2的状态,然后清除中断挂起位。* p) k0 k1 \# i. o+ M% H
   ]( |" ?4 U7 c) x- E9 ?, D9 I7 T) ]
函数main()位于main.c文件中:
+ u( i2 z& b2 x8 y 
$ F/ T3 W1 o% F5 k( K+ r! V; f( uint main(void)
- i$ ~" m2 r' n7 J{
2 I6 r* t% ?) a. }7 }  /* Code here configures LEDs on board */1 T1 Q' K, F0 B( k) @
 
' M( C: o3 _0 n5 r6 U" {  TIM3_4_ChainConfig(1000, 3);          // 1), Y* k0 A3 z( r) i# f
 . _, W3 s4 m: Q5 H9 i
  while (1)& |# X3 M. ?/ n/ ?* q# y) T
  {! d3 w8 h2 t8 v( \' a/ m6 r
    /* Waiting for interrupts */5 I3 I. i  y3 M+ K3 z0 X
  }
$ ]. O8 j3 n2 i( l& g6 A0 m% c}* t/ t: f2 e" S' z9 l& t1 |1 P+ H. I
 
& y5 q- F  J9 U7 n" e代码行1)将TIM3的周期设为1000,也就是每秒TIM3将产生一个更新事件,同时TIM4产生一个触发事件,由于TIM4的触发中断已开启,其对应的中断处理代码将得以执行,即LED1的状态将翻转。TIM4的周期设为3,也就是说3秒后,TIM4将产生更新中断,LED2的状态将翻转。; g7 ^. E) h! V8 u, {! [7 a
 2 I  |" {, d- _  ~9 k/ e4 F" B
了解更多,请点击访问我们的首页
' B& J! |4 p/ y 
3 t2 L: @1 v1 W( D 
收藏 评论0 发布时间:2013-10-14 15:59

举报

0个回答

所属标签

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