之前的博文中介绍了移植官方例程捕获频率的方法,今天在其基础上再来看看如何捕获对应的占空比.
工程可见Github<传送门>
大部分内容和输入捕获(一)类似,这里只贴出不一样的
main.c
/******************************************************************************* * 文件名:main.c * 描 述: * 作 者:CLAY * 版本号:v1.0.0 * 日 期: 2019年2月19日 * 备 注:修改后的LCD例程 * PA7 (TIM3_CH2) 输入捕获外来信号频率(两次上升沿) ******************************************************************************* */ #include "stm32f10x.h" #include "lcd.h" #include "e2prom.h" #include "stdio.h" #include "i2c.h" #include "adc.h" #include "rtc.h" #include "usart2.h" #include "pwm.h" #include "pwm_oc.h" #include "pwm_ic.h" #include "timer.h" u32 TimingDelay = 0; //全局变量 u8 flag200ms = 0; u8 str[20]; //串口相关 u8 RxdCnt = 0; u8 RxdOver = 0; u8 RxdBuf[20]; //RTC相关 u8 RTC_Flag = 0; //捕获相关 extern u8 TIM3_CH2_CAPTURE_MODE; extern u32 TIM3_CH2_CAPTURE_H; extern u32 TIM3_CH2_CAPTURE_HL; void Delay_Ms(u32 nTime); //Main Body int main(void) { u8 str[20]; STM3210B_LCD_Init(); LCD_Clear(Blue); LCD_SetBackColor(Blue); LCD_SetTextColor(White); SysTick_Config(SystemCoreClock/1000); TIM4_Init(2000 ,72);//定时2ms PWM_OC_Init(500, 60);//500Hz 60%方波 PWM_IC_Init(); while(1) { if(flag200ms) { flag200ms = 0; if(TIM3_CH2_CAPTURE_MODE == 3) { sprintf((char*)str, " Freq = %d Hz ", 1000000 / TIM3_CH2_CAPTURE_HL); LCD_DisplayStringLine(Line3, str); sprintf((char*)str, " Duty = %d %% ", TIM3_CH2_CAPTURE_H * 100 / TIM3_CH2_CAPTURE_HL); LCD_DisplayStringLine(Line5, str); TIM3_CH2_CAPTURE_MODE = 0; } } } } // void Delay_Ms(u32 nTime) { TimingDelay = nTime; while(TimingDelay != 0); }
stm32f10x_it.c
u8 TIM3_CH2_CAPTURE_MODE = 0;//捕获所在位置 u32 TIM3_CH2_CAPTURE_H = 0;//第一次上升沿 u32 TIM3_CH2_CAPTURE_HL = 0;//第一个下降沿 void TIM3_IRQHandler(void) { if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET) { TIM_ClearITPendingBit(TIM3, TIM_IT_CC2); switch(TIM3_CH2_CAPTURE_MODE) { case 0: TIM3_CH2_CAPTURE_MODE = 1; TIM3_CH2_CAPTURE_H = 0; TIM3_CH2_CAPTURE_HL = 0; TIM_SetCounter(TIM3, 0);//清零第一次上升沿计数器 TIM_OC2PolarityConfig(TIM3, TIM_ICPolarity_Falling);//改为下降沿触发 break; case 1: TIM3_CH2_CAPTURE_MODE = 2; TIM3_CH2_CAPTURE_H = TIM_GetCounter(TIM3);//获取第一次下降沿的计数值 TIM_OC2PolarityConfig(TIM3, TIM_ICPolarity_Rising); break; case 2: TIM3_CH2_CAPTURE_MODE = 3; TIM3_CH2_CAPTURE_HL = TIM_GetCounter(TIM3); break; default: break; } } }
紫色部分为我们输入的方波信号。
首先我们刚开始时要把捕获通道设置为上升沿触发假如我们捕获到了一个上升沿,也就是到达了A点,那么我们的定时器就开始计数,随后我们还要把捕获通道设置成为下降沿触发。
当我们捕获了一个下降沿时,也就是到达了B点,那么我们获取一个计数值,定时器还得继续计数,同时重新把捕获通道设置为上升沿触发。
直到再次捕获到了一个上升沿,那么就代表已经到达C点了,我们再获取一次计数值,然后再把捕获通道设置为上升沿触发,以备下次使用。
占空比 = 第一次捕获值 / 第二次捕获值
周期 = 1000000 / 第二次捕获值
TIM_OC2PolarityConfig(TIM3, TIM_ICPolarity_Falling);//改为下降沿触发