STM32 定时器同步 触发 代码 实验 验证分享

这里使用STM32F407型号,其它版本可能略有区别

定时器同步可以用来BLDC的HALL、ENCODER、内部时钟相位一致

定时器同步触发:

主定时器配置:

1、TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);

TIMx:根据数据手册决定,看表76/72,这里我们选择TIM4

STM32 定时器同步 触发 代码 实验 验证分享_第1张图片

 STM32 定时器同步 触发 代码 实验 验证分享_第2张图片

TIM_TRGOSource:输出触发源选项

TIM_TRGOSource_Reset  

TIM_TRGOSource_Enable 

TIM_TRGOSource_Update 

TIM_TRGOSource_OC1    

TIM_TRGOSource_OC1Ref 

TIM_TRGOSource_OC2Ref 

TIM_TRGOSource_OC3Ref 

TIM_TRGOSource_OC4Ref 

有8个选项,TIM_TRGOSource_OC1~TIM_TRGOSource_OC4Ref是OC输出,这里实验时采用PWM,可以的没问题;这里我们实验选择TIM_TRGOSource_OC1Ref

TIM_TRGOSource_Enable这一项也验证了,可以触发;

至于TIM_TRGOSource_Reset和TIM_TRGOSource_Update  这两项未能成功验证,反复试了很多方法,还是不行,现象:一上电,就触发了,根本不能控制

具体见手册,如下图

STM32 定时器同步 触发 代码 实验 验证分享_第3张图片

2、void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);

TIMx:和上面保持一致

TIM_MasterSlaveMode:2个选项

TIM_MasterSlaveMode_Enable 

TIM_MasterSlaveMode_Disable

这里使用TIM_MasterSlaveMode_Enable  使能主从模式

从定时器配置:

void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);

TIMx:参照表格76/72来确定,这里选择TIM5实验

TIM_InputTriggerSource:

TIM_TS_ITR0  

TIM_TS_ITR1  

TIM_TS_ITR2  

TIM_TS_ITR3  

TIM_TS_TI1F_ED

TIM_TS_TI1FP1

TIM_TS_TI2FP2

TIM_TS_ETRF  

选择输入触发源,TIM_TS_ITR0~ TIM_TS_ITR3是表格76/72来确定的,和主定时器保持一致,这里我们选择TIM_TS_ITR2(即触发源是定时器4)

TIM_TS_TI1F_ED:一般用来bldc霍尔输入来触发的

TIM_TS_TI1FP1

TIM_TS_TI2FP2:这2个检测 编码器信号输入触发的

TIM_TS_ETRF:外部触发

这些验证没有问题

具体参数意义见手册,如下图

STM32 定时器同步 触发 代码 实验 验证分享_第4张图片

void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);

TIMx:上同

TIM_SlaveMode:

TIM_SlaveMode_Reset    :复位

TIM_SlaveMode_Gated     :门控

TIM_SlaveMode_Trigger   :触发

TIM_SlaveMode_External1  :外部

从定时器模式选择,这里反复实验验证TIM_SlaveMode_Gated、 TIM_SlaveMode_External1

没有问题

至于TIM_SlaveMode_Reset只对TI1有效,即定时器输入1通道和TIM_SlaveMode_Trigger只对TI2有效,即定时器输入2通道,都是适用于外部信号触发,比如hall,编码器,按键;见下图

STM32 定时器同步 触发 代码 实验 验证分享_第5张图片

详细见手册,如下图

详细见手册,如下图

STM32 定时器同步 触发 代码 实验 验证分享_第6张图片

下面示意2种同步代码

代码1:触发输出采用TIM_TRGOSource_Enable 

触发输入采用TIM_SlaveMode_Gated

//从定时器

void       Tim5_init(void)

{

       TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStre;

       NVIC_InitTypeDef NVIC_InitStre;

      

       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

       TIM_ITConfig(TIM5,TIM_IT_Update,DISABLE);

       TIM_Cmd(TIM5, DISABLE);

      

       //计数频率100Hz=84/(TIM_Prescaler+1)/(TIM_Period+1)

       TIM_TimeBaseInitStre.TIM_Prescaler=84-1;//定时器频率84M/(840)=1us

       TIM_TimeBaseInitStre.TIM_Period=50000-1;//周期计数值500 T=200Hz=5ms 

       TIM_TimeBaseInitStre.TIM_ClockDivision=0x00;//不分频

       TIM_TimeBaseInitStre.TIM_CounterMode=TIM_CounterMode_Up ;

       TIM_TimeBaseInitStre.TIM_RepetitionCounter=0;

       TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStre);

      

       TIM_SelectSlaveMode(TIM5,TIM_SlaveMode_Gated);

       TIM_SelectInputTrigger(TIM5,TIM_TS_ITR2);//设置输入触发源

       NVIC_InitStre.NVIC_IRQChannel=TIM5_IRQn;

       NVIC_InitStre.NVIC_IRQChannelPreemptionPriority=0x02;

       NVIC_InitStre.NVIC_IRQChannelSubPriority=0x01;

       NVIC_InitStre.NVIC_IRQChannelCmd=ENABLE;

       NVIC_Init(&NVIC_InitStre);//初始化

       TIM_ClearITPendingBit(TIM5,TIM_IT_Update);

      

       TIM_ARRPreloadConfig(TIM5, ENABLE);//使能自动装载

       TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);    

       TIM_ClearITPendingBit(TIM5,TIM_IT_Update);

      

       TIM_Cmd(TIM5, ENABLE);//使能时钟,

}

//主触发器

void       Tim4_init(void)

{

       TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStre;

       NVIC_InitTypeDef NVIC_InitStre;

      

       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

       TIM_ITConfig(TIM4,TIM_IT_Update,DISABLE);

       TIM_Cmd(TIM4, DISABLE);

      

       //计数频率100Hz=84/(TIM_Prescaler+1)/(TIM_Period+1)

       TIM_TimeBaseInitStre.TIM_Prescaler=84-1;//定时器频率84M/(840)=1us

       TIM_TimeBaseInitStre.TIM_Period=50000-1;//周期计数值500 T=200Hz=5ms 

       TIM_TimeBaseInitStre.TIM_ClockDivision=0x00;//不分频

       TIM_TimeBaseInitStre.TIM_CounterMode=TIM_CounterMode_Up ;

       TIM_TimeBaseInitStre.TIM_RepetitionCounter=0;

       TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStre);

      

       TIM_SelectOutputTrigger(TIM4, TIM_TRGOSource_Enable);//设置输入触发源

       TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable);//使能主从模式

      

       NVIC_InitStre.NVIC_IRQChannel=TIM4_IRQn;

       NVIC_InitStre.NVIC_IRQChannelPreemptionPriority=0x02;

       NVIC_InitStre.NVIC_IRQChannelSubPriority=0x03;

       NVIC_InitStre.NVIC_IRQChannelCmd=ENABLE;

       NVIC_Init(&NVIC_InitStre);//初始化

       TIM_ClearITPendingBit(TIM4,TIM_IT_Update);

      

       TIM_ARRPreloadConfig(TIM4, ENABLE);//使能自动装载

       TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);    

       TIM_ClearITPendingBit(TIM4,TIM_IT_Update);

      

       //TIM_Cmd(TIM4, ENABLE);//使能时钟,不要在这里使能

}

//我这里使用串口指令来使能定时器

Void Main_Time(vodi)

{

TIM_Cmd(TIM4 ENABLE);//在这里使能

}

//定时器5中断服务函数

void TIM5_IRQHandler(void)

{

                     if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET)

       {

GPIO_WriteBit(GPIOA,GPIO_Pin_11,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_11)));//LED

              TIM_ClearITPendingBit(TIM5,TIM_IT_Update);//清除中断

       }

}

实验现象是,上电后,定时器5不被触发,led不闪烁

串口指令使能主定时器后,定时器5被触发,led闪烁

代码2:触发输出采用TIM_TRGOSource_OC3Ref

触发输入采用TIM_SlaveMode_Gated

//从定时器

void       Tim5_init(void)

{

       TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStre;

       NVIC_InitTypeDef NVIC_InitStre;

      

       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

       TIM_ITConfig(TIM5,TIM_IT_Update,DISABLE);

       TIM_Cmd(TIM5, DISABLE);

      

       //计数频率100Hz=84/(TIM_Prescaler+1)/(TIM_Period+1)

       TIM_TimeBaseInitStre.TIM_Prescaler=84-1;//定时器频率84M/(840)=1us

       TIM_TimeBaseInitStre.TIM_Period=50000-1;//周期计数值500 T=200Hz=5ms 

       TIM_TimeBaseInitStre.TIM_ClockDivision=0x00;//不分频

       TIM_TimeBaseInitStre.TIM_CounterMode=TIM_CounterMode_Up ;

       TIM_TimeBaseInitStre.TIM_RepetitionCounter=0;

       TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStre);

      

       TIM_SelectSlaveMode(TIM5,TIM_SlaveMode_Gated);//从模式配置 

       TIM_SelectInputTrigger(TIM5,TIM_TS_ITR3);//设置输入触发源

       //TIM_SelectMasterSlaveMode(TIM5,TIM_MasterSlaveMode_Enable);//使能主从模式

      

       NVIC_InitStre.NVIC_IRQChannel=TIM5_IRQn;

       NVIC_InitStre.NVIC_IRQChannelPreemptionPriority=0x02;

       NVIC_InitStre.NVIC_IRQChannelSubPriority=0x01;

       NVIC_InitStre.NVIC_IRQChannelCmd=ENABLE;

       NVIC_Init(&NVIC_InitStre);//初始化

       TIM_ClearITPendingBit(TIM5,TIM_IT_Update);

      

       TIM_ARRPreloadConfig(TIM5, ENABLE);//使能自动装载

       TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);    

       TIM_ClearITPendingBit(TIM5,TIM_IT_Update);

      

       TIM_Cmd(TIM5, ENABLE);//使能时钟 //中断配置

}

//主定时器

void Tim8_init(void)

{

       TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStre;

       TIM_OCInitTypeDef TIM_OCInitStre;

      

       RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

       PV_PEEP_IO_Init();//IO口初始化

      

       //计数频率20kHz=168/(TIM_Prescaler+1)/(TIM_Period+1)

       TIM_TimeBaseInitStre.TIM_Prescaler=0;//定时器频率168M/(0+1)

       TIM_TimeBaseInitStre.TIM_Period=11200-1;//周期计数值 15k-11200  一个计数值 改成20kHz-8400

       TIM_TimeBaseInitStre.TIM_ClockDivision=0x00;//不分频

       TIM_TimeBaseInitStre.TIM_CounterMode=TIM_CounterMode_CenterAligned1;

       TIM_TimeBaseInitStre.TIM_RepetitionCounter=0;

       TIM_TimeBaseInit(TIM8, &TIM_TimeBaseInitStre);

      

       TIM_OCInitStre.TIM_OCMode=TIM_OCMode_PWM1;

       TIM_OCInitStre.TIM_Pulse=0;//占空比0%

       TIM_OCInitStre.TIM_OCPolarity=TIM_OCPolarity_High ;

       TIM_OCInitStre.TIM_OutputState=TIM_OutputState_Enable ;

       TIM_OCInitStre.TIM_OCIdleState=TIM_OCIdleState_Reset ;

       TIM_OC3Init(TIM8, &TIM_OCInitStre);//消音圈

      

       TIM_SelectOutputTrigger(TIM8,TIM_TRGOSource_OC3Ref);//触发输出源OC3

       TIM_SelectMasterSlaveMode(TIM8,TIM_MasterSlaveMode_Enable);//使能主从模式

      

       TIM_CtrlPWMOutputs(TIM8, ENABLE);//高级定时器要加这个使能

       TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable);

  TIM_Cmd(TIM8, ENABLE);//使能时钟

}

//串口更改占空比

Void Set_CCR(void)

{

TIM8->CCR3=1000;

}

实验现象,开始占空比等于0,定时器5不被触发,led不闪烁;

使用串口发送指令,更改占空比,定时器5被触发,led闪烁

你可能感兴趣的:(stm32,同步)