STM32定时器同步模式 四种

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_30567891/article/details/78988828

 
 
  1. typedef struct {
  2. uint32_t MasterOutputTrigger; //主模式选择。选择具体模式发送到TRG0上。
  3. uint32_t MasterSlaveMode; //主定时器的从模式使能与失能位(TIM_MASTERSLAVEMODE_ENABLE或TIM_MASTERSLAVEMODE_DISABLE)
  4. }TIM_MasterConfigTypeDef; 


MasterOutputTrigger:
     这个位可选择主模式下将要发送到从定时器以实现同步的信息
(TRGO) 。这些位的组合如下:
000 : 复位 ––TIMx_EGR 寄存器中的 UG 位用作触发输出 (TRGO) 。如果复位由触发输入生成(从模式控制器配置为复位模式),则 TRGO 上的信号相比实际复位会有延迟。
001: 使能––计数器使能信号(CNT_EN) 用作触发输出 (TRGO)。该触发输出可用于同时启动多个定时器,或者控制在一段时间内使能从定时器。计数器使能信号可由CEN控制位产生。当配置为门控模式时,也可由触发输入产生。当计数器使能信号由触发输入控制时,TRGO 上会存在延迟,选择主/从模式时除外
010 : 更新 –– 选择更新事件作为触发输出 (TRGO) 。例如,主定时器可用作从定时器的预分频器。
011 : 比较脉冲 –– 一旦发生输入捕获或比较匹配事件,当 CC1IF 被置 1 时(即使已为高电 平),触发输出都会发送一个正脉冲 (TRGO)
100 : 比较 ––OC1REF 信号用作触发输出 (TRGO)
101 : 比较 ––OC2REF 信号用作触发输出 (TRGO)
110 : 比较 ––OC3REF 信号用作触发输出 (TRGO)
111 : 比较 ––OC4REF 信号用作触发输出 (TRGO)


一、一个定时器作为另一个定时器的预分频:

使用TIM1作为主定时器,TIM2为从定时器,当TIM1发生更新事件时,TIM2计数器+1.在主循环中
  循环改变TIM1的更新周期,TIM2开启更新中断,在中断中翻转LED电平.

主定时器初始化:


 
 
  1. void MASTER_TIMx_Init(void)
  2. {
  3.   TIM_ClockConfigTypeDef sClockSourceConfig;
  4.   TIM_MasterConfigTypeDef  sMasterConfig;
  5.   
  6.   /* 基本定时器外设时钟使能 */
  7.   MASTER_TIM_RCC_CLK_ENABLE();
  8.   
  9.   /* 主定时器基本功能配置 */
  10.   htimx_MasterTIM.Instance = TIM1;
  11.   htimx_MasterTIM.Init.Prescaler = MASTER_TIM_PRESCALER;
  12.   htimx_MasterTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
  13.   htimx_MasterTIM.Init.Period = MASTER_TIM_PERIOD;
  14.   htimx_MasterTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  15.   HAL_TIM_Base_Init(&htimx_MasterTIM);
  16.   /* 定时器时钟源选择 */
  17.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;    //使用内部时钟源
  18.   HAL_TIM_ConfigClockSource(&htimx_MasterTIM, &sClockSourceConfig);
  19.   
  20.   /* 主模式配置 */
  21.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  22.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  23.   HAL_TIMEx_MasterConfigSynchronization(&htimx_MasterTIM,&sMasterConfig);
  24.   
  25. }


从定时器初始化:


 
 
  1. void SLAVE_TIMx_Init(void)
  2. {
  3.   TIM_ClockConfigTypeDef sClockSourceConfig;
  4.   TIM_SlaveConfigTypeDef  sSlaveConfig;
  5.  
  6.   /* 基本定时器外设时钟使能 */
  7.   SLAVE_TIM_RCC_CLK_ENABLE();
  8.   
  9.   /* 从定时器基本功能配置 */
  10.   htimx_SlaveTIM.Instance = TIM2;
  11.   htimx_SlaveTIM.Init.Prescaler = SLAVE_TIM_PRESCALER;
  12.   htimx_SlaveTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
  13.   htimx_SlaveTIM.Init.Period = SLAVE_TIM_PERIOD;
  14.   htimx_SlaveTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  15.   HAL_TIM_Base_Init(&htimx_SlaveTIM);
  16.   /* 定时器时钟源选择 */
  17.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ITR0;
  18.   HAL_TIM_ConfigClockSource(&htimx_SlaveTIM, &sClockSourceConfig);
  19.   /* 从模式:外部触发模式1(内部定时器触发)*/
  20.   sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;          // 从模式:外部触发模式1
  21.   sSlaveConfig.InputTrigger = TIM_TS_ITR0;                  // 输入触发:选择 ITR0 作为输入源
  22.   sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; // 触发极性:上升沿
  23.   sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; // 触发预分频:无
  24.   sSlaveConfig.TriggerFilter = 0x0;                          // 滤波:本例中不需要任何滤波
  25.   HAL_TIM_SlaveConfigSynchronization(&htimx_SlaveTIM,&sSlaveConfig);
  26.   
  27.   /* 外设中断配置 */
  28.   HAL_NVIC_SetPriority(SLAVE_TIM_IRQ, 0, 0);
  29.   HAL_NVIC_EnableIRQ(SLAVE_TIM_IRQ);
  30. }
二、定时器门控模式

    使用TIM1作为主定时器,TIM2为从定时器。
    当TIM1的OC1REF发生高电平时,TIM2计数器使能运行。
    在主循环中将LED2灭掉,在TIM2的更新中断中点亮LED2,所以只有TIM2发生高频率的更新事件才能维持LED2点亮。

   将TIM1的CH1配置为PWM1模式,这样修改比较值就可以修改OC1REF,使OC1REF占空比为50%就可以使LED2低频闪烁.

 主定时器初始化:



 
 
  1. void MASTER_TIMx_Init(void)
  2. {
  3. TIM_ClockConfigTypeDef sClockSourceConfig;
  4. TIM_MasterConfigTypeDef sMasterConfig;
  5. TIM_OC_InitTypeDef sOCConfig ;
  6. /* 基本定时器外设时钟使能 */
  7. MASTER_TIM_RCC_CLK_ENABLE();
  8. /* 主定时器基本功能配置 */
  9. htimx_MasterTIM.Instance = MASTER_TIMx;
  10. htimx_MasterTIM.Init.Prescaler = MASTER_TIM_PRESCALER;
  11. htimx_MasterTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
  12. htimx_MasterTIM.Init.Period = MASTER_TIM_PERIOD;
  13. htimx_MasterTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  14. HAL_TIM_Base_Init(&htimx_MasterTIM);
  15. /* 定时器时钟源选择 */
  16. sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  17. HAL_TIM_ConfigClockSource(&htimx_MasterTIM, &sClockSourceConfig);
  18. /* 主模式配置 */
  19. sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  20. sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF;
  21. HAL_TIMEx_MasterConfigSynchronization(&htimx_MasterTIM,&sMasterConfig);
  22. sOCConfig.OCMode = TIM_OCMODE_PWM1; // 使用PWM模式,通过控制比较器值就可以控制OCxREF
  23. sOCConfig.Pulse = MASTER_TIM_PERIOD/ 2; // 比较值
  24. sOCConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
  25. sOCConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  26. sOCConfig.OCFastMode = TIM_OCFAST_DISABLE;
  27. sOCConfig.OCIdleState = TIM_OCIDLESTATE_SET;
  28. sOCConfig.OCNIdleState = TIM_OCNIDLESTATE_SET;
  29. HAL_TIM_OC_ConfigChannel(&htimx_MasterTIM,&sOCConfig,TIM_CHANNEL_1);
  30. }

从定时器初始化:


 
 
  1. void SLAVE_TIMx_Init(void)
  2. {
  3. TIM_ClockConfigTypeDef sClockSourceConfig;
  4. TIM_SlaveConfigTypeDef sSlaveConfig;
  5. /* 基本定时器外设时钟使能 */
  6. SLAVE_TIM_RCC_CLK_ENABLE();
  7. /* 从定时器基本功能配置 */
  8. htimx_SlaveTIM.Instance = SLAVE_TIMx;
  9. htimx_SlaveTIM.Init.Prescaler = SLAVE_TIM_PRESCALER;
  10. htimx_SlaveTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
  11. htimx_SlaveTIM.Init.Period = SLAVE_TIM_PERIOD;
  12. htimx_SlaveTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  13. HAL_TIM_Base_Init(&htimx_SlaveTIM);
  14. /* 定时器时钟源选择 */
  15. sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  16. HAL_TIM_ConfigClockSource(&htimx_SlaveTIM, &sClockSourceConfig);
  17. /* 从模式:外部触发模式1(内部定时器触发)*/
  18. sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED; // 从模式:外部触发模式1
  19. sSlaveConfig.InputTrigger = TIM_TS_ITR0; // 输入触发:选择 ITR0 作为输入源
  20. sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; // 触发极性:上升沿
  21. sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; // 触发预分频:无
  22. sSlaveConfig.TriggerFilter = 0x0; // 滤波:本例中不需要任何滤波
  23. HAL_TIM_SlaveConfigSynchronization(&htimx_SlaveTIM,&sSlaveConfig);
  24. /* 外设中断配置 */
  25. HAL_NVIC_SetPriority(SLAVE_TIM_IRQ, 0, 0);
  26. HAL_NVIC_EnableIRQ(SLAVE_TIM_IRQ);
  27. }

主函数:

 
 
  1.   /* 主从定时器初始化 */
  2.   MASTER_TIMx_Init();
  3.   SLAVE_TIMx_Init();
  4.   /* 使能主从定时器,并开启从定时器的中断 */
  5.   HAL_TIM_Base_Start(&htimx_MasterTIM);
  6.   HAL_TIM_Base_Start_IT(&htimx_SlaveTIM);
  7.   /* 点亮LED灯,使用不同频率闪烁 */
  8.   LED2_TOGGLE;
  9.   /* 改变TIM1的比较值,修改OC1REF电平 */
  10.   __HAL_TIM_SET_COMPARE(&htimx_MasterTIM,TIM_CHANNEL_1,MASTER_TIM_PERIOD/ 2);
  11.   /* 无限循环 */
  12. while ( 1)
  13. {
  14. /* 主循环中总是关闭LED2,在TIM2中断点亮LED2 */
  15. /* 所以可以通过LED2的亮灭观察到TIM2是否使能启动 */
  16. LED2_OFF;
  17. /* TIM2作为从定时器,只有在OC1REF高电平的时候才运行,
  18. 这里可以修改TIM1比较值改变OC1REF的占空比% 达到改变LED2亮灭时间*/
  19. }
定时器2的回调函数:

 
 
  1. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  2. {
  3. if(htim->Instance == SLAVE_TIMx)
  4. {
  5. __HAL_TIM_CLEAR_IT(&htimx_SlaveTIM, TIM_SR_TIF);
  6. LED2_ON;
  7. }
  8. }
三、定时器同步----触发模式

  使用TIM1作为主定时器,TIM2为从定时器,当使能TIM1计数器时,同时也使能了TIM2.
  在TIM2的更新中断翻转LED电平,当启动TIM1的时候,TIM2也启动了,所以LED会闪烁.

主定时器初始化:


 
 
  1. void MASTER_TIMx_Init(void)
  2. {
  3.   TIM_ClockConfigTypeDef sClockSourceConfig;
  4.   TIM_MasterConfigTypeDef  sMasterConfig;
  5.   
  6.   /* 基本定时器外设时钟使能 */
  7.   MASTER_TIM_RCC_CLK_ENABLE();
  8.   
  9.   /* 主定时器基本功能配置 */
  10.   htimx_MasterTIM.Instance = MASTER_TIMx;
  11.   htimx_MasterTIM.Init.Prescaler = MASTER_TIM_PRESCALER;
  12.   htimx_MasterTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
  13.   htimx_MasterTIM.Init.Period = MASTER_TIM_PERIOD;
  14.   htimx_MasterTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  15.   HAL_TIM_Base_Init(&htimx_MasterTIM);
  16.   /* 定时器时钟源选择 */
  17.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  18.   HAL_TIM_ConfigClockSource(&htimx_MasterTIM, &sClockSourceConfig);
  19.   
  20.   /* 主模式配置 */
  21.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  22.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; //产生更新事件时,会在TRG0产生输出。
  23.   HAL_TIMEx_MasterConfigSynchronization(&htimx_MasterTIM,&sMasterConfig);
  24.   
  25. }
从定时器初始化:


 
 
  1. void SLAVE_TIMx_Init(void)
  2. {
  3.   TIM_ClockConfigTypeDef sClockSourceConfig;
  4.   TIM_SlaveConfigTypeDef  sSlaveConfig;
  5.  
  6.   /* 基本定时器外设时钟使能 */
  7.   SLAVE_TIM_RCC_CLK_ENABLE();
  8.   
  9.   /* 从定时器基本功能配置 */
  10.   htimx_SlaveTIM.Instance = SLAVE_TIMx;
  11.   htimx_SlaveTIM.Init.Prescaler = SLAVE_TIM_PRESCALER;
  12.   htimx_SlaveTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
  13.   htimx_SlaveTIM.Init.Period = SLAVE_TIM_PERIOD;
  14.   htimx_SlaveTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  15.   HAL_TIM_Base_Init(&htimx_SlaveTIM);
  16.   /* 定时器时钟源选择 */
  17.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ITR0;
  18.   HAL_TIM_ConfigClockSource(&htimx_SlaveTIM, &sClockSourceConfig);
  19.   /* 从模式:外部触发模式1(内部定时器触发)*/
  20.   sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;            // 定时器同步:触发模式
  21.   sSlaveConfig.InputTrigger = TIM_TS_ITR0;                  // 输入触发:选择 ITR0 作为输入源
  22.   sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; // 触发极性:上升沿
  23.   sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; // 触发预分频:无
  24.   sSlaveConfig.TriggerFilter = 0x0;                          // 滤波:本例中不需要任何滤波
  25.   HAL_TIM_SlaveConfigSynchronization(&htimx_SlaveTIM,&sSlaveConfig);
  26.   
  27.   /* 外设中断配置 */
  28.   HAL_NVIC_SetPriority(SLAVE_TIM_IRQ, 0, 0);
  29.   HAL_NVIC_EnableIRQ(SLAVE_TIM_IRQ);
  30. }
主函数:

 
 
  1. while ( 1)
  2. {
  3. HAL_Delay( 5000);
  4.   /* 只开启TIM1,然后TIM2也会启动 */
  5. HAL_TIM_Base_Start(&htimx_MasterTIM);
  6. }
回调函数:


 
 
  1. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  2. {
  3. if(htim->Instance == SLAVE_TIMx)
  4. {
  5. LED1_TOGGLE;
  6. LED2_TOGGLE;
  7. LED3_TOGGLE;
  8. }
  9. }

四、定时器同步---同步出发两个定时器。

  给PA8一个上升沿,LED1和LED3同步闪烁
  使用LED1即既作为主模式也作为从模式,TIM2作为从模式,使用TIM1的CH1作为触发输入,
  检测到 上升沿就触发启动TIM1,TIM1启动的同时触发启动TIM2,
  TIM1和TIM2的时钟频率和计数周期是一致的  ,TIM1更新中断翻转LED3电平,TIM2更新中断翻转LED2电平,所以两个LED灯是同步闪烁的.



 
 
  1. void MASTER_TIMx_Init(void)
  2. {
  3.   TIM_ClockConfigTypeDef sClockSourceConfig;
  4.   TIM_MasterConfigTypeDef  sMasterConfig;
  5.   TIM_SlaveConfigTypeDef  sSlaveConfig;
  6.   
  7.   /* 基本定时器外设时钟使能 */
  8.   MASTER_TIM_RCC_CLK_ENABLE();
  9.   
  10.   /* 主定时器基本功能配置 */
  11.   htimx_MasterTIM.Instance = MASTER_TIMx;
  12.   htimx_MasterTIM.Init.Prescaler = MASTER_TIM_PRESCALER;
  13.   htimx_MasterTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
  14.   htimx_MasterTIM.Init.Period = MASTER_TIM_PERIOD;
  15.   htimx_MasterTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  16.   HAL_TIM_Base_Init(&htimx_MasterTIM);
  17.   /* 定时器时钟源选择 */
  18.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  19.   HAL_TIM_ConfigClockSource(&htimx_MasterTIM, &sClockSourceConfig);
  20.   /* 主模式配置 */
  21.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  22.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_ENABLE;      // 使能时触发输出      
  23.   HAL_TIMEx_MasterConfigSynchronization(&htimx_MasterTIM,&sMasterConfig);
  24.  
  25.   /* 从模式:外部触发 */
  26.   sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;            // 从模式:触发模式
  27.   sSlaveConfig.InputTrigger = TIM_TS_TI1F_ED;                // 输入触发:选择外部触发 TI1的边沿检测(即PA8)
  28.   sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; // 触发极性:上升沿
  29.   sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; // 触发预分频:无
  30.   sSlaveConfig.TriggerFilter = 0x0;                          // 滤波:本例中不需要任何滤波
  31.   HAL_TIM_SlaveConfigSynchronization(&htimx_MasterTIM,&sSlaveConfig);
  32.   HAL_NVIC_SetPriority(MASTER_TIM_IRQ, 0, 0);
  33.   HAL_NVIC_EnableIRQ(MASTER_TIM_IRQ);
  34. }

从定时器:

 
 
  1. void SLAVE_TIMx_Init(void)
  2. {
  3.   TIM_ClockConfigTypeDef sClockSourceConfig;
  4.   TIM_SlaveConfigTypeDef  sSlaveConfig;
  5.  
  6.   /* 基本定时器外设时钟使能 */
  7.   SLAVE_TIM_RCC_CLK_ENABLE();
  8.   
  9.   /* 从定时器基本功能配置 */
  10.   htimx_SlaveTIM.Instance = SLAVE_TIMx;
  11.   htimx_SlaveTIM.Init.Prescaler = SLAVE_TIM_PRESCALER;
  12.   htimx_SlaveTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
  13.   htimx_SlaveTIM.Init.Period = SLAVE_TIM_PERIOD;
  14.   htimx_SlaveTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  15.   HAL_TIM_Base_Init(&htimx_SlaveTIM);
  16.   /* 定时器时钟源选择 */
  17.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ITR0;
  18.   HAL_TIM_ConfigClockSource(&htimx_SlaveTIM, &sClockSourceConfig);
  19.   /* 从模式:外部触发模式1(内部定时器触发)*/
  20.   sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;          // 从模式:外部触发模式1
  21.   sSlaveConfig.InputTrigger = TIM_TS_ITR0;                  // 输入触发:选择 ITR0 作为输入源
  22.   sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; // 触发极性:上升沿
  23.   sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; // 触发预分频:无
  24.   sSlaveConfig.TriggerFilter = 0x0;                          // 滤波:本例中不需要任何滤波
  25.   HAL_TIM_SlaveConfigSynchronization(&htimx_SlaveTIM,&sSlaveConfig);
  26.   
  27.   /* 外设中断配置 */
  28.   HAL_NVIC_SetPriority(SLAVE_TIM_IRQ, 0, 0);
  29.   HAL_NVIC_EnableIRQ(SLAVE_TIM_IRQ);
  30. }






  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值