功能描述:测量方波频率和占空比。通过将TIM9配置为输入捕获模式
- main.c文件内容如下
#include "stm32f4xx.h" // Device header #include "Delay.h" #include "MyDMA.h" #include "Serial.h" #include "Timer.h"int main(void) {Serial_Init(); //初始化串口Timer_Init(); //初始化定时器Serial_SendString(USART1,"Hello, world!\n"); //串口输出字符串while(1){//IC_GetFreq()获得信号频率,通过串口显示Serial_Printf(USART1,"The frequency of the sign is %dHz\n", IC_GetFreq());//IC_GetDutyRatio()获得信号占空比,通过串口显示Serial_Printf(USART1,"The duty ratio of the sign is %.1f%% \n", 100*IC_GetDutyRatio());Delay_ms(500);} }
- Timer.c文件内容如下
#include "Timer.h" /*** @摘要 初始化TIM* @参数 无* @返回值 无* @说明 无*/ void Timer_Init(void) {//开启GPIOA时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//将PA2配置为复用模式,复用为TIM9的CH1引脚GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM9);//定义GPIO初始化结构体GPIO_InitTypeDef GPIO_InitStructure;//初始化上述结构体GPIO_StructInit(&GPIO_InitStructure);//配置GPIO模式为复用模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//配置GPIO输出类型为推挽输出GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//配置GPIO输入类型为上拉输入GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//配置GPIO的速度为高速100MHZGPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//指定GPIO引脚为Pin2GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//初始化对应的GPIOGPIO_Init(GPIOA, &GPIO_InitStructure);//开启TIM9时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE); //选择TIM9的时钟模式为内部模式,时钟源为内部时钟(84*2=168MHZ)TIM_InternalClockConfig(TIM9); //定义时基单元初始化结构体TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //初始化上述结构体TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure); //配置预分频系数为168-1TIM_TimeBaseInitStructure.TIM_Prescaler = 168-1; //配置自动重装值为0XFFFFTIM_TimeBaseInitStructure.TIM_Period = 0XFFFF; //配置计数模式为向上计数TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //配置定时器时钟频率与数字滤波器所使用的采样时钟之间的分频比TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //配置重复计数器的值为0TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //初始化时基单元TIM_TimeBaseInit(TIM9, &TIM_TimeBaseInitStructure); //定义输入捕获单元初始化结构体TIM_ICInitTypeDef TIM_ICInitStruct;//初始化上述结构体TIM_ICStructInit(&TIM_ICInitStruct);//选择通道TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//配置输入捕获通道的滤波器TIM_ICInitStruct.TIM_ICFilter = 0x6;//选择触发的边沿类型TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//配置输入捕获通道的分频器TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//输入信号选择TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;//初始化输入捕获单元TIM_ICInit(TIM9, &TIM_ICInitStruct);//配置TIM,使其可测占空比TIM_PWMIConfig(TIM9, &TIM_ICInitStruct);//上面这句等同于下面这段注释内容 // //初始化上述结构体 // TIM_ICStructInit(&TIM_ICInitStruct); // //选择通道 // TIM_ICInitStruct.TIM_Channel = TIM_Channel_2; // //配置输入捕获通道的滤波器 // TIM_ICInitStruct.TIM_ICFilter = 0x6; // //选择触发的边沿类型 // TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling; // //配置输入捕获通道的分频器 // TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; // //输入信号选择 // TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_IndirectTI; // //初始化输入捕获单元 // TIM_ICInit(TIM9, &TIM_ICInitStruct);//选择从模式触发源TIM_SelectInputTrigger(TIM9, TIM_TS_TI1FP1);//选择从模式的执行动作TIM_SelectSlaveMode(TIM9, TIM_SlaveMode_Reset);//开启TIM9,此时计数器开始工作TIM_Cmd(TIM9, ENABLE); }/*** @摘要 获得输入捕获通道信号的频率* @参数 无* @返回值 输入捕获通道信号的频率* @说明 无*/ uint32_t IC_GetFreq(void) {uint32_t cnt = TIM_GetCapture1(TIM9);if(cnt == 0)return 0;elsereturn 1000000/cnt;//周期=计数值/计数频率,频率=计数频率/计数值 }/*** @摘要 获得输入捕获通道信号的占空比* @参数 无* @返回值 输入捕获通道信号的占空比* @说明 无*/ double IC_GetDutyRatio(void) {uint32_t cnt = TIM_GetCapture1(TIM9);if(cnt != 0)return (double)TIM_GetCapture2(TIM9)/cnt;//占空比=高电平持续时间/周期return 0; }
- Timer.h文件内容如下
#ifndef __TIMER_H #define __TIMER_H#include "stm32f4xx.h" // Device headervoid Timer_Init(void); uint32_t IC_GetFreq(void); double IC_GetDutyRatio(void);#endif