#|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获


文章目录

  • 前言
  • 1、输入捕获原理
    • 1.1、设置输入捕获滤波器
    • 1.2、设置输入捕获的极性
    • 1.3、设置输入捕获的映射通道
    • 1.4、设置输入捕获分频器
    • 1.5、捕获到有效信号可开启中断
    • 1.6、捕获实现频率和占空比的获取
  • 2、输入捕获功能配置流程
  • 3、部分源码

前言
??下载工程文件:
??https://gitee.com/Joseph_Cooper/blue-bridge-embedded
1、输入捕获原理 #|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获
文章图片

1.1、设置输入捕获滤波器 ??根据输入信号的特点,配置输入滤波器为所需的带宽(即输入为TIx时,输入滤波器控制位是TIMx_CCMRx寄存器中的ICxF位)。假设输入信号在最多5个内部时钟周期的时间内抖动,我们须配置滤波器的带宽长于5个时钟周期;因此我们可以(以fDTS频率)连续采样8次,以确认在TI1上一次真实的边沿变换,即在TIMx_CCMR1寄存器中写入IC1F=0011。
#|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获
文章图片

1.2、设置输入捕获的极性 ??改变CC1P位的值以改变上升沿触发或是下降沿触发。可通过库函数void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)来设置。
1.3、设置输入捕获的映射通道 ??通道内获得的信号是可以通过设置交给不同的IC来进行处理的,比如,我们可以将通道1捕获的信号送给IC2处理。
#|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获
文章图片

1.4、设置输入捕获分频器 ??可设置多次上升沿触发一次捕获也就是相当于分频的作用。
#|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获
文章图片

1.5、捕获到有效信号可开启中断 ??捕获到一次信号可以进入相应的中断服务函数。
#|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获
文章图片

#|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获
文章图片

1.6、捕获实现频率和占空比的获取 【#|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获】#|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获
文章图片

1、设置为上升沿捕获、定时器值清零
2、上升沿捕获成功后记录定时器中的值A再设置为下降沿捕获
3、下降沿捕获成功后记录定时器中的值B再次设置为上升沿捕获。
4、再次设置为上升沿捕获,捕获成功后记录定时器中的值C,清空定时器计数值, ( C ? A ) ? 1 f T I M (C-A)\cdot\frac1{f_{TIM}} (C?A)?fTIM?1?即为该波形的周期,其倒数即是频率, B ? A C ? A × 100 % \frac {B-A}{C-A}\times100\% C?AB?A?×100%即为占空比。
2、输入捕获功能配置流程 1、初始化定时器和通道对应IO的时钟。
2、初始化IO口,模式为输入
??GPIO_Init();
??GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入
3、初始化定时器ARR,PSC
?? TIM_TimeBaseInit();
4、初始化输入捕获通道
??TIM_ICInit();
5、使能定时器
??TIM_Cmd();
6、如果要开启捕获中断
??TIM_ITConfig();
??NVIC_Init();
7、编写中断服务函数
??TIMx_IRQHandler();
需要用到的函数:
??通道极性设置函数
??void TIM_OCxPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
??获取捕获值
??uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx);
3、部分源码 PWM输出:
#|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获
文章图片

输入捕获:
#|【蓝桥杯嵌入式】【STM32】10_InputCaputer之输入捕获
文章图片

main.c:
#include "Headfile.h"/** * @filemain.c * @brief实现PA1捕获PA9、PA10端的输出,显示频率和占空比 * @version1.0 * @authorJosephCooper * @date2020.10.09 *//** 滴答定时器实现延时中间变量 */ u32 TimingDelay = 0; extern __IO uint32_t TIM2Freq; extern u8 TIM2FreqReady; extern __IO uint32_t TIM2Duty; void Delay_Ms(u32 nTime); //Main Body int main(void) { uint32_t i = 0; u8 Str[200]; uint32_t TIM2Freq_BP = 0; uint32_t TIM2Duty_BP = 0; memset(Str,0x00,sizeof(Str)); //清空数组 SysTick_Config(SystemCoreClock/1000); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Delay_Ms(200); LEDInit(); //LED初始化 //关闭所有LED LEDCmd(Bit_SET); GPIO_Write(GPIOC,GPIO_ReadOutputData(GPIOC) | 0xFF00); LEDCmd(Bit_RESET); STM3210B_LCD_Init(); LCD_Clear(Blue); LCD_SetBackColor(Blue); LCD_SetTextColor(White); BuzzerInit(); //蜂鸣器初始化 TIM2_ICInit(); TIM1_PWMInit(); //TIM1_PWM初始化 while(1) { if(TIM2FreqReady) { TIM2FreqReady = 0; if( (TIM2Freq!=TIM2Freq_BP) || (TIM2Duty!=TIM2Duty_BP) ) { TIM2Freq_BP = TIM2Duty; TIM2Duty_BP = TIM2Freq; sprintf((char*)Str,"TIM2Freq:%dHz", TIM2Freq); LCD_DisplayStringLine(Line2,Str); sprintf((char*)Str,"TIM2Duty:%d%%", TIM2Duty); LCD_DisplayStringLine(Line3,Str); for(i=0; i<500000; i++); //刷新延迟 } } } }// void Delay_Ms(u32 nTime) { TimingDelay = nTime; while(TimingDelay != 0); }

stm32f10x_it.c:
#include "stm32f10x_tim.h" #include "stm32f10x.h" extern u32 TimingDelay; ... //7、编写中断服务函数 __IO uint16_t IC2ReadValue1 = 0, IC2ReadValue2 = 0,IC2ReadValue_LOW = 0; __IO uint16_t CaptureNumber = 0; __IO uint32_t Capture = 0; __IO uint32_t TIM2Freq = 0; __IO uint32_t TIM2Duty = 0; u8 TIM2FreqReady = 0; void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET) { /* Clear TIM3 Capture compare interrupt pending bit */ TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); if(CaptureNumber == 0) { /* Get the Input Capture value */ IC2ReadValue1 = TIM_GetCapture2(TIM2); CaptureNumber = 1; //设置下降沿捕获 TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_Low); } else if(CaptureNumber == 1) { IC2ReadValue_LOW = TIM_GetCapture2(TIM2); CaptureNumber = 2; //设置上升沿捕获 TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_High); } else if(CaptureNumber == 2) { /* Get the Input Capture value */ IC2ReadValue2 = TIM_GetCapture2(TIM2); /* Capture computation */ if (IC2ReadValue2 > IC2ReadValue1) { Capture = (IC2ReadValue2 - IC2ReadValue1); } else { Capture = ((0xFFFF - IC2ReadValue1) + IC2ReadValue2); } /* Frequency computation */ TIM2Duty = ( (IC2ReadValue_LOW-IC2ReadValue1)*100 ) / Capture; TIM2Freq = 1000000 / Capture; //定时器经过72分频后的频率 CaptureNumber = 0; TIM2FreqReady = 1; TIM_SetCounter(TIM2,0); }} }

InputCaputer.c
#include "Headfile.h"void TIM2_ICInit() { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM2_ICInitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //1、初始化定时器和通道对应IO的时钟。 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //2、初始化PA1,模式为输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //3、初始化定时器(时基设置) TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1 ; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); //4、初始化输入捕获通道 TIM2_ICInitStructure.TIM_Channel = TIM_Channel_2; //定时器2的通道2 TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获 TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //使用通道默认IC即IC2 TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //不分频 TIM2_ICInitStructure.TIM_ICFilter = 0x00; //不滤波 //5、使能定时器 TIM_ICInit(TIM2, &TIM2_ICInitStructure); //IC初始化 TIM_Cmd(TIM2, ENABLE); //打开定时器 //6、如果要开启捕获中断 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); }

??关于LCD刷新的问题:LCD在刷新时可能因为中断打断出现乱码的问题,将要显示的字符串添加(用空格补全)至总长度超过20位即可sprintf((char*)Str,"TIM2Freq:%dHz ", TIM2Freq);

    推荐阅读