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

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

[复制链接]
Cody-2045860 发布时间:2013-10-14 15:59
本例程出自STM32MED1开发板附带光盘,其工程目录路径为:\Code Package\Peripheral Devices\06 TIM\0602_Chaining。
* k; T  l& L/ N" w: f* ^# ^/ W7 }6 U% a- |( P; A% ?
本例程是使用TIM3作为TIM4的预分频器。下面代码出自timer.c文件。
( g, A. I4 \# @5 \5 F3 e7 c + r4 X: e* _" z0 V; d; F+ f8 M
void TIM3_4_ChainConfig(u16 Period1, u16 Period2)
& D1 v& I( Z8 f! m: E{
7 I. I# c$ i8 A4 B+ @" C  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;* x# ?# x7 I2 w0 O
  NVIC_InitTypeDef NVIC_InitStructure;
- Y7 l+ k! y+ u# _: |" D 
% q6 F2 ^) L/ W+ X8 Y  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3|
. r! ]6 P0 g$ s5 X  X" a2 \, w; [
4 b" Z' B7 b7 Y' b' y" \
                                   RCC_APB1Periph_TIM4, ENABLE);   // 1)9 l8 A# ^/ V7 F+ J
 
- L2 p7 g) Z5 A7 g  TIM_TimeBaseStructure.TIM_Period = Period1;    // 2)9 A9 d% _& i& z
  TIM_TimeBaseStructure.TIM_Prescaler = (u16)(SystemCoreClock / 1000) - 1;    // 3)
0 Y  U7 w& L! r* d4 S, `' Y# \, v4 n  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
; y9 A4 Z; |9 C3 i2 ~6 o/ n  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   // 4)$ J6 @4 t+ K) R* j) {
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
! N. O. d2 ?4 J 7 z. Q, y5 s/ R0 _9 s6 T
  TIM_TimeBaseStructure.TIM_Period = Period2;    // 5)
) ]9 G1 N; y; h4 P+ s# r! Q  TIM_TimeBaseStructure.TIM_Prescaler = 0;0 S& {6 ]8 @) t
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);( ?! {' [- m; Q' a# s
 
9 [0 w6 V) u/ N; T7 A  TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);   // 6)! P8 U; z: i' u
 
8 q: g' s# S) [$ [1 ], u  TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_External1);    // 7)
$ v# S4 x/ k& z3 f( E- o  TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2);    // 8)7 ]2 n0 C5 @) N3 z2 i9 v1 _5 S
 ! X' S" y6 I6 k# R) {5 y: T
  TIM_ITConfig(TIM4, TIM_IT_Trigger | TIM_IT_Update, ENABLE);    // 9)- c! e2 Y6 i# G' Z3 a
  TIM_UpdateRequestConfig(TIM4, TIM_UpdateSource_Global);     // 10)
7 v$ R( q: ~) F! S" m4 q( R* e4 P 
+ T4 L( r3 S/ H  // (11# Z. d7 ~/ k  w0 x
  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;/ S' H/ r8 ~  w& T7 r5 k2 \
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  E" \' d$ `# O9 U1 ~% d' R8 h  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  {0 \* e3 l, h# Y. I  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;; z) {1 U( m/ T- k$ V$ r2 y* c: [
  NVIC_Init(&NVIC_InitStructure);
8 K6 u6 {: K1 P" A, u  // 11)
" o# r4 v; E* M6 z: t' q( L3 J 
; l' ~: n, P5 C  TIM_Cmd(TIM4, ENABLE);     // 12)+ w, s% c, ^7 F% S
  TIM_Cmd(TIM3, ENABLE);     // 13)5 P1 ]4 L" W1 ]0 w8 y
}+ l0 i( B7 m; f8 b% V1 u0 g
 
# G3 _$ I; j( t& ^1 _在对定时器的寄存器进行配置前先应通过调用函数RCC_APB1PeriphClockCmd()使能相应定时器的时钟,如代码行1)。代码行2)是设置TIM3的周期,即设置寄存器TIM3_ARR的值。代码行3)是设置TIM3的预分频器值。由于TIM3的从模式控制器被禁止,TIM3预分频器的时钟由内部时钟CK_INT提供。全局变量SystemCoreClock定义于system_stm32f10x.c,如下代码所示:
6 C! [, p' O. u. S* }5 e( Y/ o$ a   K+ m, w6 W; L5 Y+ G3 A5 v& m
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz;1 s4 }- L$ t* D
 6 I: B! F, X+ t& y4 l# S
由此可见,代码行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)分别开启TIM4及TIM3。
. {+ u# l, p: r/ Q1 ]4 H 
4 z2 C1 A8 L# ]  ]0 ?+ {1 t+ J3 u; s下面是文件stm32f10x_it.c中TIM4的中断处理代码:
3 s$ Q  m3 F2 q* k6 I2 ^ 
/ ?. k4 O! A$ |: A, gvoid TIM4_IRQHandler(void)
& `3 C/ C$ \6 ]& \$ [3 N: {{4 M& w" v9 _8 h( h
  if (TIM_GetITStatus(TIM4, TIM_IT_Trigger) != RESET)  // 1)
! X/ H0 g6 L5 q0 s, ~; w6 I  {6 q" J7 g- E) y# N  R  F- `
    LED_Toggle(LED1);* C0 p2 h  J  I+ x
 
7 Z- }& o+ l+ L8 l7 X    TIM_ClearITPendingBit(TIM4, TIM_IT_Trigger);
, g. V) u' ]# x% d  }7 i5 I+ Y5 n8 [1 G! L& N8 W
 
  A# \! N  v: F. i2 w9 z% O( t  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)   // 2)/ J- ?( E6 c/ a0 z% @8 H
  {
! M( g9 n: v9 p& k( ]6 Z    LED_Toggle(LED2);# o( T7 C4 _5 Q& c3 r) ]  W4 S& @/ u
 
1 C/ P% y/ g; M0 ?# d    TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
& g' Z; n' `" P1 v; h; P+ C3 L+ _  }4 g+ b) s( i; `8 D! O6 t4 ?$ y
}' s" }9 T# ^7 M& M/ p. H
 * M; I7 O) d* o2 \
代码行1)是判断TIM4是否产生触发中断,若产生了触发中断,则反转开发板上LED1的状态,而后清除该中断的挂起状态位。同理,代码行2)是判断TIM4是否产生更新中断,若是则反转LED2的状态,然后清除中断挂起位。
: `. J" Q3 m  u , A: Z8 K0 ]& C$ q" {/ v+ b
函数main()位于main.c文件中:. o4 Q; h* U8 \8 t! p; X
 - ^( a! Y9 {! E3 H
int main(void): K6 z! l8 z" P
{3 U2 X* s; H; |
  /* Code here configures LEDs on board */
8 N' B7 b3 b* e& X% x 
. I  r; @" e) E  g) t# Y  TIM3_4_ChainConfig(1000, 3);          // 1)
( w: e: D+ U4 W( `. J. ` 
7 k( \2 B$ s9 S  while (1)1 U7 t1 l3 b& t8 c( b
  {
; a# P3 ~  f9 N3 f/ _* H; W, }    /* Waiting for interrupts */
5 Q1 N+ G+ T, G& h  }
/ y5 H2 t; n8 [3 R+ h& p+ k8 A}8 n3 _; X5 V$ B4 C0 B5 h7 O! m& m
 + ^& F# {" N9 r4 ~* H, h& {& O
代码行1)将TIM3的周期设为1000,也就是每秒TIM3将产生一个更新事件,同时TIM4产生一个触发事件,由于TIM4的触发中断已开启,其对应的中断处理代码将得以执行,即LED1的状态将翻转。TIM4的周期设为3,也就是说3秒后,TIM4将产生更新中断,LED2的状态将翻转。* ~4 Z5 [6 Q5 R
 
/ a: J' `4 A3 _2 T: y2 S; {了解更多,请点击访问我们的首页
& s1 y: ~2 V; K" f- |. s 
/ ^4 m. d+ r2 m1 G4 S# a 
赞 收藏 评论0 发布时间:2013-10-14 15:59

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版