搜索
查看: 1735|回复: 0

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

[复制链接]

该用户从未签到

3

主题

3

帖子

0

蝴蝶豆

新手上路

最后登录
1970-1-1
发表于 2013-10-14 15:59:34 | 显示全部楼层 |阅读模式
本例程出自STM32MED1开发板附带光盘,其工程目录路径为:\Code Package\Peripheral Devices\06 TIM\0602_Chaining

本例程是使用TIM3作为TIM4的预分频器。下面代码出自timer.c文件。
 
void TIM3_4_ChainConfig(u16 Period1, u16 Period2)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3|

                                   RCC_APB1Periph_TIM4, ENABLE);   // 1)
 
  TIM_TimeBaseStructure.TIM_Period = Period1;    // 2)
  TIM_TimeBaseStructure.TIM_Prescaler = (u16)(SystemCoreClock / 1000) - 1;    // 3)
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   // 4)
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
 
  TIM_TimeBaseStructure.TIM_Period = Period2;    // 5)
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
 
  TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);   // 6)
 
  TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_External1);    // 7)
  TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2);    // 8)
 
  TIM_ITConfig(TIM4, TIM_IT_Trigger | TIM_IT_Update, ENABLE);    // 9)
  TIM_UpdateRequestConfig(TIM4, TIM_UpdateSource_Global);     // 10)
 
  // (11
  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  // 11)
 
  TIM_Cmd(TIM4, ENABLE);     // 12)
  TIM_Cmd(TIM3, ENABLE);     // 13)
}
 
在对定时器的寄存器进行配置前先应通过调用函数RCC_APB1PeriphClockCmd()使能相应定时器的时钟,如代码行1)。代码行2)是设置TIM3的周期,即设置寄存器TIM3_ARR的值。代码行3)是设置TIM3的预分频器值。由于TIM3的从模式控制器被禁止,TIM3预分频器的时钟由内部时钟CK_INT提供。全局变量SystemCoreClock定义于system_stm32f10x.c,如下代码所示:
 
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz;
 
由此可见,代码行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
 
下面是文件stm32f10x_it.cTIM4的中断处理代码:
 
void TIM4_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM4, TIM_IT_Trigger) != RESET)  // 1)
  {
    LED_Toggle(LED1);
 
    TIM_ClearITPendingBit(TIM4, TIM_IT_Trigger);
  }
 
  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)   // 2)
  {
    LED_Toggle(LED2);
 
    TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
  }
}
 
代码行1)是判断TIM4是否产生触发中断,若产生了触发中断,则反转开发板上LED1的状态,而后清除该中断的挂起状态位。同理,代码行2)是判断TIM4是否产生更新中断,若是则反转LED2的状态,然后清除中断挂起位。
 
函数main()位于main.c文件中:
 
int main(void)
{
  /* Code here configures LEDs on board */
 
  TIM3_4_ChainConfig(1000, 3);          // 1)
 
  while (1)
  {
    /* Waiting for interrupts */
  }
}
 
代码行1)将TIM3的周期设为1000,也就是每秒TIM3将产生一个更新事件,同时TIM4产生一个触发事件,由于TIM4的触发中断已开启,其对应的中断处理代码将得以执行,即LED1的状态将翻转。TIM4的周期设为3,也就是说3秒后,TIM4将产生更新中断,LED2的状态将翻转。
 
了解更多,请点击访问我们的首页
 
 
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-5-12 17:22 , Processed in 1.162509 second(s), 30 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表