版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
-
typedef
struct {
-
uint32_t MasterOutputTrigger;
//主模式选择。选择具体模式发送到TRG0上。
-
uint32_t MasterSlaveMode;
//主定时器的从模式使能与失能位(TIM_MASTERSLAVEMODE_ENABLE或TIM_MASTERSLAVEMODE_DISABLE)
-
}TIM_MasterConfigTypeDef;
MasterOutputTrigger:
这个位可选择主模式下将要发送到从定时器以实现同步的信息 (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电平.
主定时器初始化:
-
void MASTER_TIMx_Init(void)
-
{
-
TIM_ClockConfigTypeDef sClockSourceConfig;
-
TIM_MasterConfigTypeDef sMasterConfig;
-
-
/* 基本定时器外设时钟使能 */
-
MASTER_TIM_RCC_CLK_ENABLE();
-
-
/* 主定时器基本功能配置 */
-
htimx_MasterTIM.Instance = TIM1;
-
htimx_MasterTIM.Init.Prescaler = MASTER_TIM_PRESCALER;
-
htimx_MasterTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
-
htimx_MasterTIM.Init.Period = MASTER_TIM_PERIOD;
-
htimx_MasterTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-
HAL_TIM_Base_Init(&htimx_MasterTIM);
-
-
-
/* 定时器时钟源选择 */
-
sClockSourceConfig.ClockSource =
TIM_CLOCKSOURCE_INTERNAL;
//使用内部时钟源
-
HAL_TIM_ConfigClockSource(&htimx_MasterTIM, &sClockSourceConfig);
-
-
/* 主模式配置 */
-
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
-
sMasterConfig.MasterOutputTrigger =
TIM_TRGO_UPDATE;
-
HAL_TIMEx_MasterConfigSynchronization(&htimx_MasterTIM,&sMasterConfig);
-
-
}
-
从定时器初始化:
-
void SLAVE_TIMx_Init(void)
-
{
-
TIM_ClockConfigTypeDef sClockSourceConfig;
-
TIM_SlaveConfigTypeDef sSlaveConfig;
-
-
/* 基本定时器外设时钟使能 */
-
SLAVE_TIM_RCC_CLK_ENABLE();
-
-
/* 从定时器基本功能配置 */
-
htimx_SlaveTIM.Instance = TIM2;
-
htimx_SlaveTIM.Init.Prescaler = SLAVE_TIM_PRESCALER;
-
htimx_SlaveTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
-
htimx_SlaveTIM.Init.Period = SLAVE_TIM_PERIOD;
-
htimx_SlaveTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-
HAL_TIM_Base_Init(&htimx_SlaveTIM);
-
-
-
/* 定时器时钟源选择 */
-
sClockSourceConfig.ClockSource =
TIM_CLOCKSOURCE_ITR0;
-
HAL_TIM_ConfigClockSource(&htimx_SlaveTIM, &sClockSourceConfig);
-
-
-
/* 从模式:外部触发模式1(内部定时器触发)*/
-
sSlaveConfig.SlaveMode =
TIM_SLAVEMODE_EXTERNAL1;
// 从模式:外部触发模式1
-
sSlaveConfig.InputTrigger =
TIM_TS_ITR0;
// 输入触发:选择 ITR0 作为输入源
-
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;
// 触发极性:上升沿
-
sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
// 触发预分频:无
-
sSlaveConfig.TriggerFilter =
0x0;
// 滤波:本例中不需要任何滤波
-
HAL_TIM_SlaveConfigSynchronization(&htimx_SlaveTIM,&sSlaveConfig);
-
-
/* 外设中断配置 */
-
HAL_NVIC_SetPriority(SLAVE_TIM_IRQ,
0,
0);
-
HAL_NVIC_EnableIRQ(SLAVE_TIM_IRQ);
-
}
二、定时器门控模式使用TIM1作为主定时器,TIM2为从定时器。
当TIM1的OC1REF发生高电平时,TIM2计数器使能运行。
在主循环中将LED2灭掉,在TIM2的更新中断中点亮LED2,所以只有TIM2发生高频率的更新事件才能维持LED2点亮。
将TIM1的CH1配置为PWM1模式,这样修改比较值就可以修改OC1REF,使OC1REF占空比为50%就可以使LED2低频闪烁.
主定时器初始化:
-
void MASTER_TIMx_Init(void)
-
{
-
TIM_ClockConfigTypeDef sClockSourceConfig;
-
TIM_MasterConfigTypeDef sMasterConfig;
-
TIM_OC_InitTypeDef sOCConfig ;
-
-
/* 基本定时器外设时钟使能 */
-
MASTER_TIM_RCC_CLK_ENABLE();
-
-
/* 主定时器基本功能配置 */
-
htimx_MasterTIM.Instance = MASTER_TIMx;
-
htimx_MasterTIM.Init.Prescaler = MASTER_TIM_PRESCALER;
-
htimx_MasterTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
-
htimx_MasterTIM.Init.Period = MASTER_TIM_PERIOD;
-
htimx_MasterTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-
HAL_TIM_Base_Init(&htimx_MasterTIM);
-
-
/* 定时器时钟源选择 */
-
sClockSourceConfig.ClockSource =
TIM_CLOCKSOURCE_INTERNAL;
-
HAL_TIM_ConfigClockSource(&htimx_MasterTIM, &sClockSourceConfig);
-
-
/* 主模式配置 */
-
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
-
sMasterConfig.MasterOutputTrigger =
TIM_TRGO_OC1REF;
-
HAL_TIMEx_MasterConfigSynchronization(&htimx_MasterTIM,&sMasterConfig);
-
-
sOCConfig.OCMode =
TIM_OCMODE_PWM1;
// 使用PWM模式,通过控制比较器值就可以控制OCxREF
-
sOCConfig.Pulse = MASTER_TIM_PERIOD/
2;
// 比较值
-
sOCConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
-
sOCConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
-
sOCConfig.OCFastMode = TIM_OCFAST_DISABLE;
-
sOCConfig.OCIdleState = TIM_OCIDLESTATE_SET;
-
sOCConfig.OCNIdleState = TIM_OCNIDLESTATE_SET;
-
HAL_TIM_OC_ConfigChannel(&htimx_MasterTIM,&sOCConfig,TIM_CHANNEL_1);
-
}
从定时器初始化:
-
void SLAVE_TIMx_Init(void)
-
{
-
TIM_ClockConfigTypeDef sClockSourceConfig;
-
TIM_SlaveConfigTypeDef sSlaveConfig;
-
-
/* 基本定时器外设时钟使能 */
-
SLAVE_TIM_RCC_CLK_ENABLE();
-
-
/* 从定时器基本功能配置 */
-
htimx_SlaveTIM.Instance = SLAVE_TIMx;
-
htimx_SlaveTIM.Init.Prescaler = SLAVE_TIM_PRESCALER;
-
htimx_SlaveTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
-
htimx_SlaveTIM.Init.Period = SLAVE_TIM_PERIOD;
-
htimx_SlaveTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-
HAL_TIM_Base_Init(&htimx_SlaveTIM);
-
-
/* 定时器时钟源选择 */
-
sClockSourceConfig.ClockSource =
TIM_CLOCKSOURCE_INTERNAL;
-
HAL_TIM_ConfigClockSource(&htimx_SlaveTIM, &sClockSourceConfig);
-
-
/* 从模式:外部触发模式1(内部定时器触发)*/
-
sSlaveConfig.SlaveMode =
TIM_SLAVEMODE_GATED;
// 从模式:外部触发模式1
-
sSlaveConfig.InputTrigger =
TIM_TS_ITR0;
// 输入触发:选择 ITR0 作为输入源
-
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;
// 触发极性:上升沿
-
sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
// 触发预分频:无
-
sSlaveConfig.TriggerFilter =
0x0;
// 滤波:本例中不需要任何滤波
-
HAL_TIM_SlaveConfigSynchronization(&htimx_SlaveTIM,&sSlaveConfig);
-
-
/* 外设中断配置 */
-
HAL_NVIC_SetPriority(SLAVE_TIM_IRQ,
0,
0);
-
HAL_NVIC_EnableIRQ(SLAVE_TIM_IRQ);
-
}
主函数:
-
-
/* 主从定时器初始化 */
-
MASTER_TIMx_Init();
-
SLAVE_TIMx_Init();
-
-
-
/* 使能主从定时器,并开启从定时器的中断 */
-
HAL_TIM_Base_Start(&htimx_MasterTIM);
-
HAL_TIM_Base_Start_IT(&htimx_SlaveTIM);
-
/* 点亮LED灯,使用不同频率闪烁 */
-
LED2_TOGGLE;
-
/* 改变TIM1的比较值,修改OC1REF电平 */
-
__HAL_TIM_SET_COMPARE(&htimx_MasterTIM,TIM_CHANNEL_1,MASTER_TIM_PERIOD/
2);
-
/* 无限循环 */
-
while (
1)
-
{
-
/* 主循环中总是关闭LED2,在TIM2中断点亮LED2 */
-
/* 所以可以通过LED2的亮灭观察到TIM2是否使能启动 */
-
LED2_OFF;
-
/* TIM2作为从定时器,只有在OC1REF高电平的时候才运行,
-
这里可以修改TIM1比较值改变OC1REF的占空比% 达到改变LED2亮灭时间*/
-
}
定时器2的回调函数:
-
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
-
{
-
if(htim->Instance == SLAVE_TIMx)
-
{
-
__HAL_TIM_CLEAR_IT(&htimx_SlaveTIM, TIM_SR_TIF);
-
LED2_ON;
-
}
-
}
三、定时器同步----触发模式
使用TIM1作为主定时器,TIM2为从定时器,当使能TIM1计数器时,同时也使能了TIM2.
在TIM2的更新中断翻转LED电平,当启动TIM1的时候,TIM2也启动了,所以LED会闪烁.
主定时器初始化:
-
void MASTER_TIMx_Init(void)
-
{
-
TIM_ClockConfigTypeDef sClockSourceConfig;
-
TIM_MasterConfigTypeDef sMasterConfig;
-
-
/* 基本定时器外设时钟使能 */
-
MASTER_TIM_RCC_CLK_ENABLE();
-
-
/* 主定时器基本功能配置 */
-
htimx_MasterTIM.Instance = MASTER_TIMx;
-
htimx_MasterTIM.Init.Prescaler = MASTER_TIM_PRESCALER;
-
htimx_MasterTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
-
htimx_MasterTIM.Init.Period = MASTER_TIM_PERIOD;
-
htimx_MasterTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-
HAL_TIM_Base_Init(&htimx_MasterTIM);
-
-
-
/* 定时器时钟源选择 */
-
sClockSourceConfig.ClockSource =
TIM_CLOCKSOURCE_INTERNAL;
-
HAL_TIM_ConfigClockSource(&htimx_MasterTIM, &sClockSourceConfig);
-
-
/* 主模式配置 */
-
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
-
sMasterConfig.MasterOutputTrigger =
TIM_TRGO_UPDATE;
//产生更新事件时,会在TRG0产生输出。
-
HAL_TIMEx_MasterConfigSynchronization(&htimx_MasterTIM,&sMasterConfig);
-
-
}
从定时器初始化:
-
void SLAVE_TIMx_Init(void)
-
{
-
TIM_ClockConfigTypeDef sClockSourceConfig;
-
TIM_SlaveConfigTypeDef sSlaveConfig;
-
-
/* 基本定时器外设时钟使能 */
-
SLAVE_TIM_RCC_CLK_ENABLE();
-
-
/* 从定时器基本功能配置 */
-
htimx_SlaveTIM.Instance = SLAVE_TIMx;
-
htimx_SlaveTIM.Init.Prescaler = SLAVE_TIM_PRESCALER;
-
htimx_SlaveTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
-
htimx_SlaveTIM.Init.Period = SLAVE_TIM_PERIOD;
-
htimx_SlaveTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-
HAL_TIM_Base_Init(&htimx_SlaveTIM);
-
-
-
/* 定时器时钟源选择 */
-
sClockSourceConfig.ClockSource =
TIM_CLOCKSOURCE_ITR0;
-
HAL_TIM_ConfigClockSource(&htimx_SlaveTIM, &sClockSourceConfig);
-
-
-
/* 从模式:外部触发模式1(内部定时器触发)*/
-
sSlaveConfig.SlaveMode =
TIM_SLAVEMODE_TRIGGER;
// 定时器同步:触发模式
-
sSlaveConfig.InputTrigger =
TIM_TS_ITR0;
// 输入触发:选择 ITR0 作为输入源
-
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;
// 触发极性:上升沿
-
sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
// 触发预分频:无
-
sSlaveConfig.TriggerFilter =
0x0;
// 滤波:本例中不需要任何滤波
-
HAL_TIM_SlaveConfigSynchronization(&htimx_SlaveTIM,&sSlaveConfig);
-
-
/* 外设中断配置 */
-
HAL_NVIC_SetPriority(SLAVE_TIM_IRQ,
0,
0);
-
HAL_NVIC_EnableIRQ(SLAVE_TIM_IRQ);
-
}
-
主函数:
-
while (
1)
-
{
-
HAL_Delay(
5000);
-
/* 只开启TIM1,然后TIM2也会启动 */
-
HAL_TIM_Base_Start(&htimx_MasterTIM);
-
}
回调函数:
-
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
-
{
-
if(htim->Instance == SLAVE_TIMx)
-
{
-
LED1_TOGGLE;
-
LED2_TOGGLE;
-
LED3_TOGGLE;
-
}
-
}
四、定时器同步---同步出发两个定时器。
给PA8一个上升沿,LED1和LED3同步闪烁
使用LED1即既作为主模式也作为从模式,TIM2作为从模式,使用TIM1的CH1作为触发输入,
检测到 上升沿就触发启动TIM1,TIM1启动的同时触发启动TIM2,
TIM1和TIM2的时钟频率和计数周期是一致的 ,TIM1更新中断翻转LED3电平,TIM2更新中断翻转LED2电平,所以两个LED灯是同步闪烁的.
-
void MASTER_TIMx_Init(void)
-
{
-
TIM_ClockConfigTypeDef sClockSourceConfig;
-
TIM_MasterConfigTypeDef sMasterConfig;
-
TIM_SlaveConfigTypeDef sSlaveConfig;
-
-
/* 基本定时器外设时钟使能 */
-
MASTER_TIM_RCC_CLK_ENABLE();
-
-
/* 主定时器基本功能配置 */
-
htimx_MasterTIM.Instance = MASTER_TIMx;
-
htimx_MasterTIM.Init.Prescaler = MASTER_TIM_PRESCALER;
-
htimx_MasterTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
-
htimx_MasterTIM.Init.Period = MASTER_TIM_PERIOD;
-
htimx_MasterTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-
HAL_TIM_Base_Init(&htimx_MasterTIM);
-
-
-
/* 定时器时钟源选择 */
-
sClockSourceConfig.ClockSource =
TIM_CLOCKSOURCE_INTERNAL;
-
HAL_TIM_ConfigClockSource(&htimx_MasterTIM, &sClockSourceConfig);
-
-
-
/* 主模式配置 */
-
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
-
sMasterConfig.MasterOutputTrigger =
TIM_TRGO_ENABLE;
// 使能时触发输出
-
HAL_TIMEx_MasterConfigSynchronization(&htimx_MasterTIM,&sMasterConfig);
-
-
/* 从模式:外部触发 */
-
sSlaveConfig.SlaveMode =
TIM_SLAVEMODE_TRIGGER;
// 从模式:触发模式
-
sSlaveConfig.InputTrigger =
TIM_TS_TI1F_ED;
// 输入触发:选择外部触发
TI1的边沿检测(即PA8)
-
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;
// 触发极性:上升沿
-
sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
// 触发预分频:无
-
sSlaveConfig.TriggerFilter =
0x0;
// 滤波:本例中不需要任何滤波
-
HAL_TIM_SlaveConfigSynchronization(&htimx_MasterTIM,&sSlaveConfig);
-
-
-
HAL_NVIC_SetPriority(MASTER_TIM_IRQ,
0,
0);
-
HAL_NVIC_EnableIRQ(MASTER_TIM_IRQ);
-
-
-
}
从定时器:
-
void SLAVE_TIMx_Init(void)
-
{
-
TIM_ClockConfigTypeDef sClockSourceConfig;
-
TIM_SlaveConfigTypeDef sSlaveConfig;
-
-
/* 基本定时器外设时钟使能 */
-
SLAVE_TIM_RCC_CLK_ENABLE();
-
-
/* 从定时器基本功能配置 */
-
htimx_SlaveTIM.Instance = SLAVE_TIMx;
-
htimx_SlaveTIM.Init.Prescaler = SLAVE_TIM_PRESCALER;
-
htimx_SlaveTIM.Init.CounterMode = TIM_COUNTERMODE_UP;
-
htimx_SlaveTIM.Init.Period = SLAVE_TIM_PERIOD;
-
htimx_SlaveTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-
HAL_TIM_Base_Init(&htimx_SlaveTIM);
-
-
-
/* 定时器时钟源选择 */
-
sClockSourceConfig.ClockSource =
TIM_CLOCKSOURCE_ITR0;
-
HAL_TIM_ConfigClockSource(&htimx_SlaveTIM, &sClockSourceConfig);
-
-
-
/* 从模式:外部触发模式1(内部定时器触发)*/
-
sSlaveConfig.SlaveMode =
TIM_SLAVEMODE_TRIGGER;
// 从模式:外部触发模式1
-
sSlaveConfig.InputTrigger =
TIM_TS_ITR0;
// 输入触发:选择 ITR0 作为输入源
-
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;
// 触发极性:上升沿
-
sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
// 触发预分频:无
-
sSlaveConfig.TriggerFilter =
0x0;
// 滤波:本例中不需要任何滤波
-
HAL_TIM_SlaveConfigSynchronization(&htimx_SlaveTIM,&sSlaveConfig);
-
-
/* 外设中断配置 */
-
HAL_NVIC_SetPriority(SLAVE_TIM_IRQ,
0,
0);
-
HAL_NVIC_EnableIRQ(SLAVE_TIM_IRQ);
-
}