功能描述:测量方波频率和占空比。通过将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的速度为高速100MHZ GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed; //指定GPIO引脚为Pin2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //初始化对应的GPIO GPIO_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-1 TIM_TimeBaseInitStructure.TIM_Prescaler = 168-1; //配置自动重装值为0XFFFF TIM_TimeBaseInitStructure.TIM_Period = 0XFFFF; //配置计数模式为向上计数 TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //配置定时器时钟频率与数字滤波器所使用的采样时钟之间的分频比 TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //配置重复计数器的值为0 TIM_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; else return 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 header void Timer_Init(void); uint32_t IC_GetFreq(void); double IC_GetDutyRatio(void); #endif