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

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

[复制链接]
Cody-2045860 发布时间:2013-10-14 15:59
本例程出自STM32MED1开发板附带光盘,其工程目录路径为:\Code Package\Peripheral Devices\06 TIM\0602_Chaining
2 q( a3 w" l, y- D/ e. |/ O: \" x- h0 s' h! R+ w0 C/ K4 Q
本例程是使用TIM3作为TIM4的预分频器。下面代码出自timer.c文件。5 P% d& E, {1 r& Z' a
 
" Z: }9 v4 v0 ovoid TIM3_4_ChainConfig(u16 Period1, u16 Period2)
6 ^  y0 M5 U: W& w" F5 a{
6 ^# g$ K* n! x1 l  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
$ ~* b# ^- @7 S# s4 j$ D% j5 S) ~. A3 l  NVIC_InitTypeDef NVIC_InitStructure;
  A0 m# [! N( f( e* U: | . K6 `( o/ o5 g( Z. m
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3|3 W( c  Y6 g' `1 P- D$ g

7 u  S8 @4 Y' j6 ^) l                                   RCC_APB1Periph_TIM4, ENABLE);   // 1)+ g* A' B- k! T+ j, @/ X" o
 ) R" _: Q3 O" h. K* D. `- R+ F
  TIM_TimeBaseStructure.TIM_Period = Period1;    // 2)0 |9 {4 ^2 J5 F) n" M
  TIM_TimeBaseStructure.TIM_Prescaler = (u16)(SystemCoreClock / 1000) - 1;    // 3)5 M9 m2 z$ d: T, R/ y% m5 B  C2 V
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;4 e" d* Y& G1 l( ^/ i
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   // 4)2 C) u6 c: B! @- U9 s2 `( L
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);0 f* e# w$ s* s1 k* s
 
, l/ R5 Q" L6 M- t  TIM_TimeBaseStructure.TIM_Period = Period2;    // 5)
# p4 _) z, G% @  TIM_TimeBaseStructure.TIM_Prescaler = 0;3 ^" Y! p% v/ W
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
* d6 H, m) F# S* D( D  j3 a/ C; C; g % f1 V! H6 A9 m0 o4 P! `$ P
  TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);   // 6)6 [: v/ k. q# w! _$ Z5 v
 
5 R1 l* d/ t) f* x) |4 I  TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_External1);    // 7)
$ Q( f) _0 o: Q  TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2);    // 8). o4 k: X% T$ r7 X9 x
   s6 i9 _2 ^4 G( V5 d- {
  TIM_ITConfig(TIM4, TIM_IT_Trigger | TIM_IT_Update, ENABLE);    // 9)( t2 v/ v- \2 E4 f. H0 \" [
  TIM_UpdateRequestConfig(TIM4, TIM_UpdateSource_Global);     // 10)
  M1 |+ H+ }6 A% N% n) G # b- }. p& |+ q+ g! s" a& i7 [
  // (110 r: a: U" S& o$ ~! U5 A" ?* U
  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;+ |: I; a2 A% |
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;' n" ^" g/ `! v% V5 C
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;7 h) T; f4 K/ R+ ~7 A- n
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
0 `4 i. W7 n# F) c5 |: ?  NVIC_Init(&NVIC_InitStructure);
7 \! ~4 ]" U* n# Z" a0 l  // 11). |+ F& M+ t2 m1 u) q: I) J, W0 Q" w! a, m
 
9 I. o( J- \0 z3 I; i& _; H% g8 W  TIM_Cmd(TIM4, ENABLE);     // 12)
6 z* C# \5 `6 C  TIM_Cmd(TIM3, ENABLE);     // 13)
. ]. X  |& D" [$ {8 @/ Y1 J}2 J2 |" ~+ s# e4 t! E0 K
 
" L3 g) i  L5 X% e在对定时器的寄存器进行配置前先应通过调用函数RCC_APB1PeriphClockCmd()使能相应定时器的时钟,如代码行1)。代码行2)是设置TIM3的周期,即设置寄存器TIM3_ARR的值。代码行3)是设置TIM3的预分频器值。由于TIM3的从模式控制器被禁止,TIM3预分频器的时钟由内部时钟CK_INT提供。全局变量SystemCoreClock定义于system_stm32f10x.c,如下代码所示:
( n6 q1 G9 B" x8 \9 A: t+ I5 g 
, v4 {. W; t. m& L9 Cuint32_t SystemCoreClock = SYSCLK_FREQ_72MHz;
3 y1 `) e0 [2 }5 v 2 w4 m% r7 h3 j
由此可见,代码行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)分别开启TIM4TIM3
0 X+ k% K2 T+ _( e$ u % L+ K) G, F: O1 }/ r+ _
下面是文件stm32f10x_it.cTIM4的中断处理代码:$ O! a$ R( h9 F8 R6 `
 
; O2 ^* |" u) O' z8 U  O, Nvoid TIM4_IRQHandler(void)( l& m$ y2 t* L1 ~
{- y; j! u# w/ k) M' G
  if (TIM_GetITStatus(TIM4, TIM_IT_Trigger) != RESET)  // 1)3 H* L0 j0 }% Y, N
  {0 F. H& W* x5 s0 G! v
    LED_Toggle(LED1);
! Z" p$ N) Z9 {: a  d( c5 A. R: J 
( G  E' n* H  A4 ~# Y8 n    TIM_ClearITPendingBit(TIM4, TIM_IT_Trigger); 4 ]  Z; B7 ~0 p4 ?, v5 y# r
  }9 I( t3 p% v* N( T7 ]7 j5 R
 
; ?) p! G, [' |  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)   // 2); |6 X7 e4 ?5 Q1 ~7 d" t
  {; u, K- ]: J( X4 v6 b+ |4 U" Z
    LED_Toggle(LED2);
% `- Q. j/ |, f4 f1 O8 Z 
  s$ s9 E9 b4 f" ]% k8 U6 x1 P    TIM_ClearITPendingBit(TIM4, TIM_IT_Update);% n' Y+ x' C% @) s4 k1 ^
  }
; R6 |/ g; u: z! m5 N' Q- M+ c" q' ?8 D}
4 ~" q  \4 x" l. [4 v3 A% Y+ w6 e' v 
; ?: z! O* @% t  [' k代码行1)是判断TIM4是否产生触发中断,若产生了触发中断,则反转开发板上LED1的状态,而后清除该中断的挂起状态位。同理,代码行2)是判断TIM4是否产生更新中断,若是则反转LED2的状态,然后清除中断挂起位。& F& I2 t3 i3 b0 a4 t
 
: I: m6 V0 I$ |$ C7 |3 x3 m函数main()位于main.c文件中:
; f2 f& x; q5 G0 O, u3 T# |1 e% w1 B + g8 b! }0 k  ?; a/ z2 j
int main(void)" y4 e1 _8 y0 j$ u8 y: ^% }$ h3 Z; D1 R
{
# @  n* a5 W  d$ W4 ^0 r& v5 e  M  /* Code here configures LEDs on board */3 l* L, h7 t# \0 D
 
5 q3 O3 J- F) m4 U, c8 M  TIM3_4_ChainConfig(1000, 3);          // 1)
+ I: @) P" R4 @- Z0 a5 H # c/ B# Y; a* y: t/ n2 z5 h
  while (1)
7 G7 t& d( D7 i) P' t+ T2 f  {
( f/ M# i; O) R+ w, S    /* Waiting for interrupts *// k5 d+ F( H% E. ?
  }
9 ?9 F' w- Y$ w! m: S" {9 k7 o9 H}
4 f  T. F, O5 q4 K 
. G* H: q$ V9 T代码行1)将TIM3的周期设为1000,也就是每秒TIM3将产生一个更新事件,同时TIM4产生一个触发事件,由于TIM4的触发中断已开启,其对应的中断处理代码将得以执行,即LED1的状态将翻转。TIM4的周期设为3,也就是说3秒后,TIM4将产生更新中断,LED2的状态将翻转。) j6 t, s9 M. m% L' `; E6 c8 b' Z! K2 |# R
 
( ]1 k/ Q5 g9 N" H" X了解更多,请点击访问我们的首页
, y4 d1 Z% n' P4 R5 ~: v2 v 
4 s3 b; H5 F3 x 
收藏 评论0 发布时间:2013-10-14 15:59

举报

0个回答

所属标签

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