关于stm32的同步定时器和单脉冲模式的一些小问题

2019-10-15 19:26发布

本帖最后由 含笑stm32 于 2017-1-5 15:19 编辑

最近在尝试stm32的主从定时器和单脉冲模式出现了一些现问题,也参考了一些代码,但是还是没有解决,希望用过这一块的朋友可以提供一些帮助,谢谢了~
主要的想法是用TIM2作为主定时器,采用编码器模式,对脉冲信号进行计数,然后将他的溢出产生的更新事件作为从定时器TIM3的触发信号,然后TIM3采用单脉冲模式,从而达到TIM2每溢出一次,TIM3即产生一个脉冲信号,TIM2的编码器配置是没问题的,但是TIM3没有脉冲信号,应该是同步定时器或者是单脉冲模式的问题,希望可以帮忙看一下,下面是代码。中断优先级没有配置感觉不是那一块的问题。
void RCC_Init()
{               
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM3,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_TIM1|RCC_APB2Periph_AFIO,ENABLE);
}
void EncoderAB_Init() //编码器模式 AB相 TIM2 pa0 pa1   Z相TIM4 pb6 pb7暂时不用
{
        
        TIM_TimeBaseInitTypeDef ENCODER_TimeBaseStructure;
        TIM_ICInitTypeDef ENCODER_ICStructure;
        GPIO_InitTypeDef GPIO_Structure;
        
        GPIO_Structure.GPIO_Mode=GPIO_Mode_IPU;
        GPIO_Structure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
        GPIO_Structure.GPIO_Speed=GPIO_Speed_10MHz;
        GPIO_Init(GPIOA,&GPIO_Structure);
        [size=17.1429px]TIM_DeInit(TIM2);
        TIM_TimeBaseStructInit(&ENCODER_TimeBaseStructure);
        ENCODER_TimeBaseStructure.TIM_Period=4000;
        ENCODER_TimeBaseStructure.TIM_Prescaler=ENCODER_Pre;
        TIM_TimeBaseInit(TIM2,&ENCODER_TimeBaseStructure);
        
        TIM_ICStructInit(&ENCODER_ICStructure);
        ENCODER_ICStructure.TIM_Channel = TIM_Channel_1;
        ENCODER_ICStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
        ENCODER_ICStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
        ENCODER_ICStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
        ENCODER_ICStructure.TIM_ICFilter = 0;        

        TIM_EncoderInterfaceConfig(TIM2,TIM_EncoderMode_TI12,TIM_ICPolarity_BothEdge,TIM_ICPolarity_BothEdge);
        TIM_ICInit(TIM2,&ENCODER_ICStructure);
        
        //tim2 主模式
        //TIM2->CR2=0x0020;  //MMS=010;
        TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);
        TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);//tim2的更新事件作为触发;
        
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
        TIM_ClearFlag(TIM2,TIM_FLAG_Update);
        TIM2->CNT=0;
        TIM2->CR1&=0xfffd; //UDIS=0 允许更新事件;
        TIM_Cmd(TIM2,ENABLE);        
}
//tim3 单脉冲模式ch1 pa6 ch2 pa7 脉宽:10us   两寄存器差值:10us*72mhz=720;
void TIM3_Init()
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_OCInitTypeDef TIM_OCStructure;
        GPIO_InitTypeDef GPIO_Structure;        
        
        TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
        TIM_TimeBaseStructure.TIM_Period=3720;
        TIM_TimeBaseStructure.TIM_Prescaler=2-1;
        TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
        
        TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable);//tim3从模式
        TIM_SelectOnePulseMode(TIM3,TIM_OPMode_Single);  //单脉冲模式
        TIM_SelectInputTrigger(TIM3,TIM_TS_ITR1);  //触发通过tim2 根据手册上通道为TIR1
        TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Trigger);//上升沿触发
        //输出;
        GPIO_Structure.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_6;
        GPIO_Structure.GPIO_Mode=GPIO_Mode_AF_PP;
        GPIO_Structure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_Structure);
        //输出pwm波设置
        TIM_OCStructure.TIM_OCMode=TIM_OCMode_PWM2;
        TIM_OCStructure.TIM_OutputState=TIM_OutputState_Enable;
        TIM_OCStructure.TIM_OCPolarity=TIM_OCPolarity_High;
        TIM_OCStructure.TIM_Pulse=3000;

        TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
        TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
        //TIM_ARRPreloadConfig(TIM3,ENABLE);
        TIM_OC1Init(TIM3,&TIM_OCStructure);//ch1
        TIM_OC2Init(TIM3,&TIM_OCStructure); //ch2

        TIM3->CCMR1|=0x0404;  //OC1FE=OC2FE=1;是单脉冲模式无需比较,检测到触发可直接输出脉冲
        //TIM_Cmd(TIM3,DISABLE);
        
        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
        TIM_ClearFlag(TIM3,TIM_FLAG_Update);
}

int main()
{
        RCC_Init();
        EncoderAB_Init();
        TIM3_Init();
        while(1);
}

void TIM2_IRQHandler()
{
        if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
        {
                TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
        }
}

void TIM3_IRQHandler()
{
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
        {
                TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
                TIM_Cmd(TIM3,DISABLE);
        }
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。