美文网首页
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