> 文档中心 > GD32F130C8T6定时器高精度PWM捕获模式

GD32F130C8T6定时器高精度PWM捕获模式


GD32F130C8T6定时器高精度PWM捕获模式

1.理论:PWM捕获有两种方法,第一种是通过定时器一个通道捕获检测到 上升沿开始捕获,下降沿结束捕获,即得到高电平时间(该方法正点原子视频有讲),第二种方法是通过定时器两个通道捕获一个通道捕获上升沿,一个通道捕获下降沿,捕获完了定时器计数值会自动复位。
第一种方法精度不高,第二种精度更高,第二种详细理论见(转载):https://blog.csdn.net/qq_29413829/article/details/52743273

第一种代码:

#include  "pwm.h"u8  TIM16CH1_CAPTURE_STA=0;//输入捕获状态float  CAPTURE_PWM_CNT=0;//进入中断次数float CAPTURE_PWM_TIME=0;//高电平时间usfloat CAPTURE_PWM_TIME_TEMP=0;void Timer16_pwm_capture(void){     TIMER_BaseInitPara    TIM_TimeBaseStructure;     NVIC_InitPara  NVIC_InitStructure;     GPIO_InitPara  GPIO_InitStructure;     TIMER_ICInitPara      TIMER_ICInitParaStruct; RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOB, ENABLE);//GPIO时钟使能 RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_CFG, ENABLE);     //映射时钟 RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_TIMER16, ENABLE);  GPIO_InitStructure.GPIO_Pin    = GPIO_PIN_8; //输入捕获 GPIO_InitStructure.GPIO_Mode   = GPIO_MODE_AF; GPIO_InitStructure.GPIO_Speed  = GPIO_SPEED_50MHZ; GPIO_InitStructure.GPIO_OType  = GPIO_OTYPE_PP; GPIO_InitStructure.GPIO_PuPd   = GPIO_PUPD_PULLDOWN; GPIO_Init(GPIOB, &GPIO_InitStructure);  GPIO_PinAFConfig( GPIOB, GPIO_PINSOURCE8, GPIO_AF_2); //TIM16_CH1    TIM_TimeBaseStructure.TIMER_Period = 7200-1;     TIM_TimeBaseStructure.TIMER_Prescaler = 1-1;     TIM_TimeBaseStructure.TIMER_ClockDivision = TIMER_CDIV_DIV1;     TIM_TimeBaseStructure.TIMER_CounterMode = TIMER_COUNTER_UP;//向上计数     TIMER_BaseInit(TIMER16, &TIM_TimeBaseStructure); //使能定时器TIMER_ICInitParaStruct.TIMER_CH   = TIMER_CH_1;//捕获通道TIMER_ICInitParaStruct.TIMER_ICPolarity  =TIMER_IC_POLARITY_RISING;//捕获极性,上升沿捕获TIMER_ICInitParaStruct.TIMER_ICSelection =TIMER_IC_SELECTION_DIRECTTI;//映射关系TIMER_ICInitParaStruct.TIMER_ICPrescaler =TIMER_IC_PSC_DIV1;//分频系数TIMER_ICInitParaStruct.TIMER_ICFilter    =0x00;//滤波器**TIMER_ICInit(TIMER16,&TIMER_ICInitParaStruct);**NVIC_InitStructure.NVIC_IRQ = TIMER16_IRQn; //中断响应优先级     NVIC_InitStructure.NVIC_IRQPreemptPriority=0; NVIC_InitStructure.NVIC_IRQSubPriority = 0;NVIC_InitStructure.NVIC_IRQEnable = ENABLE; NVIC_Init(&NVIC_InitStructure);    TIMER_ClearIntBitState(TIMER16, TIMER_INT_UPDATE);//清除定时器中断标志TIMER_ClearIntBitState(TIMER16,TIMER_INT_CH1);    TIMER_INTConfig(TIMER16, TIMER_INT_UPDATE | TIMER_INT_CH1, ENABLE);//使能定时器中断    TIMER_SetCounter(TIMER16,0x0000);//设置计数器的值    TIMER_Enable(TIMER16, ENABLE);//使能定时器  }void TIM16_IRQHandler(void){if(TIMER_GetIntBitState(TIMER16,TIMER_INT_UPDATE)!= RESET)//更新事件{if(TIM16CH1_CAPTURE_STA)//捕获到了上升沿,但还没有捕获到下降沿,定时器中断就来了{CAPTURE_PWM_CNT++;}TIMER_ClearIntBitState(TIMER16,TIMER_INT_UPDATE);}if(TIMER_GetIntBitState(TIMER16,TIMER_INT_CH1)!= RESET)//捕获事件{if(TIM16CH1_CAPTURE_STA) // 捕获到了下降沿{    TIMER_ICInitPara  TIMER_ICInitParaStruct;//配置下次上升沿捕获TIM16CH1_CAPTURE_STA=0;//完成捕获,并清除标记状态TIMER_GetCapture1(TIMER16);//获取捕获值//根据定时器配置,每进一次中断计数器就计数7200次,进了CAPTURE_PWM_CNT 次中断     CAPTURE_PWM_TIME_TEMP = (CAPTURE_PWM_CNT * 7200.0 + CAPTURE_PWM_TIME_TEMP) ;//每一个计数值=(100.0/7200.0)us, 捕获到高电平时间=CAPTURE_PWM_TIME ;CAPTURE_PWM_TIME = CAPTURE_PWM_TIME_TEMP * (100.0/7200.0);CAPTURE_PWM_CNT=0;//清空中断次数TIMER_SetCounter(TIMER16,0x0000);//设置计数器的值TIMER_ICInitParaStruct.TIMER_CH = TIMER_CH_1;TIMER_ICInitParaStruct.TIMER_ICPolarity=TIMER_IC_POLARITY_RISING;TIMER_ICInitParaStruct.TIMER_ICSelection=TIMER_IC_SELECTION_DIRECTTI;//映射关系TIMER_ICInitParaStruct.TIMER_ICPrescaler=TIMER_IC_PSC_DIV1;//分频系数TIMER_ICInitParaStruct.TIMER_ICFilter=0x00;//滤波器TIMER_PWMCaptureConfig(TIMER16,&TIMER_ICInitParaStruct);}else //成功捕获到上升沿,并将通道配置为下降沿捕获{TIMER_ICInitPara  TIMER_ICInitParaStruct;//配置下次下降沿捕获    TIMER_SetCounter(TIMER16,0x0000);//设置计数器的值为0TIM16CH1_CAPTURE_STA=0x01;//标记捕获到了上升沿TIMER_ICInitParaStruct.TIMER_CH = TIMER_CH_1;TIMER_ICInitParaStruct.TIMER_ICPolarity=TIMER_IC_POLARITY_FALLING;TIMER_ICInitParaStruct.TIMER_ICSelection=TIMER_IC_SELECTION_DIRECTTI;//映射关系TIMER_ICInitParaStruct.TIMER_ICPrescaler=TIMER_IC_PSC_DIV1;//分频系数TIMER_ICInitParaStruct.TIMER_ICFilter=0x00;//滤波器TIMER_PWMCaptureConfig(TIMER16,&TIMER_ICInitParaStruct);}TIMER_ClearIntBitState(TIMER16,TIMER_INT_CH1);}}

第二种方法:

float CAPTURE_PWM_TIME_UP=0;float CAPTURE_PWM_TIME_ALL=0;float CAPTURE_PWM_TIME_LAST=0;/*----------------------------- TIMER14 500hz  -----------------------------------*/void Timer15_pwm_capture(void){     TIMER_BaseInitPara   TIM_TimeBaseStructure; NVIC_InitPara NVIC_InitStructure; GPIO_InitPara GPIO_InitStructure; TIMER_ICInitPara     TIMER_ICInitParaStruct; RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOA , ENABLE);//GPIO时钟使能 RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_CFG, ENABLE); //映射时钟 RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_TIMER15, ENABLE);     GPIO_InitStructure.GPIO_Pin    = GPIO_PIN_3; //输入捕获 GPIO_InitStructure.GPIO_Mode   = GPIO_MODE_AF; GPIO_InitStructure.GPIO_Speed  = GPIO_SPEED_50MHZ;     GPIO_InitStructure.GPIO_OType  = GPIO_OTYPE_PP; GPIO_InitStructure.GPIO_PuPd   = GPIO_PUPD_PULLDOWN; GPIO_Init(GPIOA, &GPIO_InitStructure);  GPIO_PinAFConfig(GPIOA,GPIO_PINSOURCE3,GPIO_AF_0);//配置映射为 TIM15_CH2     TIMER_DeInit(TIMER15);     TIM_TimeBaseStructure.TIMER_Period = 30000-1;   //720-10k  2.5k     TIM_TimeBaseStructure.TIMER_Prescaler = 1-1;      TIM_TimeBaseStructure.TIMER_ClockDivision = TIMER_CDIV_DIV1;      TIM_TimeBaseStructure.TIMER_CounterMode = TIMER_COUNTER_UP;//向上计数      TIMER_BaseInit(TIMER15, &TIM_TimeBaseStructure); //使能定时器     NVIC_InitStructure.NVIC_IRQ = TIMER15_IRQn; //中断响应优先级      NVIC_InitStructure.NVIC_IRQPreemptPriority=0;  NVIC_InitStructure.NVIC_IRQSubPriority = 0; NVIC_InitStructure.NVIC_IRQEnable = ENABLE;  NVIC_Init(&NVIC_InitStructure); //这里配置了一个通道,另一个通道会自动配置 TIMER_ICInitParaStruct.TIMER_CH   = TIMER_CH_2;//捕获通道  TIMER_CH_2 TIMER_ICInitParaStruct.TIMER_ICPolarity  =TIMER_IC_POLARITY_RISING;//捕获极性上升沿捕获 TIMER_ICInitParaStruct.TIMER_ICSelection =TIMER_IC_SELECTION_DIRECTTI;//映射关系 TIMER_ICInitParaStruct.TIMER_ICPrescaler =TIMER_IC_PSC_DIV1;//分频系数 TIMER_ICInitParaStruct.TIMER_ICFilter    =0x00;//滤波器 **TIMER_PWMCaptureConfig(TIMER15,&TIMER_ICInitParaStruct);**//第一种是配置   TIMER_ICInit(),现在这里配置的是TIMER_PWMCaptureConfig(); TIMER_SelectInputTrigger(TIMER15,TIMER_TS_TI2FP2); TIMER_SelectSlaveMode(TIMER15,TIMER_SLAVE_MODE_RESET); TIMER_SelectMasterSlaveMode(TIMER15,TIMER_MASTER_SLAVE_MODE_ENABLE); TIMER_ClearIntBitState(TIMER15, TIMER_INT_UPDATE);//清除定时器中断标志 TIMER_ClearIntBitState(TIMER15, TIMER_INT_CH2); TIMER_INTConfig(TIMER15,TIMER_INT_CH2, ENABLE);//使能定时器中断 TIMER_SetCounter(TIMER15,0x0000);//设置计数器的值 TIMER_Enable(TIMER15, ENABLE);//使能定时器  }void TIM15_IRQHandler(void){  CAPTURE_PWM_TIME_UP = (float)(TIMER15->CHCC1);//上升沿计数值,读取捕获值会自动清空中断标志  CAPTURE_PWM_TIME_ALL   =(float)(TIMER15->CHCC2);//总pwm计数值,读取捕获值会自动清空中断标志}

情感课堂