美文网首页
STM32定时器输入捕获

STM32定时器输入捕获

作者: andyhacker | 来源:发表于2019-06-20 22:20 被阅读0次

I、原理描述

image.png

My Code



     //double DutyCycle, Frequency, FullCycle;
    //uint32_t IC2Value;
    //uint32_t cnt;
    //uint8_t timer5_cap_sta = 0;
    //uint16_t timer5_cap_val = 0;


    PwmValType cap_val[4];
    PwmValType cap_val_cp[4];

    void drv_pwm_reader_init()
    {
        GPIO_InitTypeDef GPIO_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        TIM_ICInitTypeDef TIM_ICInitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 
        // T4CH1-4, PD12-15
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);       
    
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 ;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;    //GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOD, &GPIO_InitStructure);
 
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4);
        GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4);
        
        TIM_TimeBaseStructure.TIM_Period = 10000 - 1;
        TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / 4) / 50000 - 1;
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
        TIM_ClearFlag(TIM4, TIM_FLAG_Update | TIM_FLAG_CC1 | TIM_FLAG_CC2 | TIM_FLAG_CC3 | TIM_FLAG_CC4);
        
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
        TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
        TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
        TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
        TIM_ICInitStructure.TIM_ICFilter = 0x0;
        TIM_ICInit(TIM4, &TIM_ICInitStructure);
        
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;    
        
        TIM_ICInit(TIM4, &TIM_ICInitStructure);
        
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
        TIM_ICInit(TIM4, &TIM_ICInitStructure);
        
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;        
        TIM_ICInit(TIM4, &TIM_ICInitStructure);
 
        // TIM_PWMIConfig(TIM1, &TIM_ICInitStructure);
 
        // TIM_SelectInputTrigger(TIM1, TIM_TS_TI2FP2);
 
        // TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
 
        // TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
 
        TIM_Cmd(TIM4, ENABLE);
 
        // WARNING: TIM_IT_CC4 will inference other so that cannot work
        TIM_ITConfig(TIM4, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | /*TIM_IT_CC4  |*/ TIM_IT_Update, ENABLE); 
        
 
        NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        memset((void*)&(cap_val[0]), 0, sizeof(PwmValType) *4);
    }


    void update_val(int index, uint32_t val)
    {
        uint16_t tmpccer = 0;
        if((cap_val[index].status&0x40) == 0)       // rising, start count
        {
                cap_val[index].val = val;               
                cap_val[index].status = 0x40;
                // TIM_OC3PolarityConfig(TIM4, TIM_ICPolarity_Falling);         
                
                tmpccer = TIM4->CCER;
                /* Set or Reset the CC1P Bit */
                tmpccer &= (uint16_t)(~(0x0002 << (index *4)));
                tmpccer |= TIM_ICPolarity_Falling << (index *4);
                TIM4->CCER = tmpccer;
        }
        else if(cap_val[index].status&0x40)     // rising, end count
        {
                if(val <= cap_val[index].val)
                {
                    cap_val[index].status = 0x00;
                    return;
                }
                cap_val[index].status = 0x80;       // finish cap
                cap_val[index].val = val - cap_val[index].val; // diff
            
                cap_val_cp[index].status = 0x80;        // finish cap
                cap_val_cp[index].val = cap_val[index].val; // diff
                // TIM_OC3PolarityConfig(TIM4, TIM_ICPolarity_Rising);
            
                tmpccer = TIM4->CCER;
                /* Set or Reset the CC1P Bit */
                tmpccer &= (uint16_t)(~(0x0002 << (index *4)));
                tmpccer |= TIM_ICPolarity_Rising << (index *4);
                TIM4->CCER = tmpccer;
        }
        // TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
    }

    void TIM4_IRQHandler(void)
    {
        // if((timer5_cap_sta & 0x80) == 0)
        {
                if(TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)
                {
                        update_val(0, TIM_GetCapture1(TIM4));
                        TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
                }
                if(TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET)
                {
                        update_val(1, TIM_GetCapture2(TIM4));
                        TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);
                }
                if(TIM_GetITStatus(TIM4, TIM_IT_CC3) != RESET)
                {
                        update_val(2, TIM_GetCapture3(TIM4));
                        TIM_ClearITPendingBit(TIM4, TIM_IT_CC3);
                }
                if(TIM_GetITStatus(TIM4, TIM_IT_CC4) != RESET)
                {
                        update_val(3, TIM_GetCapture4(TIM4));
                        TIM_ClearITPendingBit(TIM4, TIM_IT_CC4);
                }
                // overflow and clean
                if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
                {
                        int i = 0;
                        for(i = 0; i < 4; i++)
                        {
                            cap_val[i].status = 0x00;
                            cap_val_cp[i].status = 0x00;
                        }
                        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
                }
                // finish and clean
                if(cap_val[0].status & 0x80 && 
                     cap_val[1].status & 0x80 &&
                     cap_val[2].status & 0x80 /*&&
                     cap_val[3].status & 0x80 */)
                {
                        int i = 0;
                        for(i = 0; i < 4; i++) cap_val[i].status = 0x00;
                        TIM_SetCounter(TIM4, 0);
                }
        }
    }

    void drv_pwm_read(PwmValType * val)
    {    
     memcpy((void *)val, (void *)&(cap_val_cp[0]), 4 * sizeof(PwmValType));
    }

参考

https://www.cnblogs.com/strongerHuang/p/5662338.html

相关文章

网友评论

      本文标题:STM32定时器输入捕获

      本文链接:https://www.haomeiwen.com/subject/sqmsqctx.html