1.输入捕获模式测频率
(1)main.c
#include "Device/Include/stm32f10x.h" // Device header
#include "pwm.h"
#include "delay.h"
#include "OLED.h"
#include "IC.h"
uint8_t i;
int main(void)
{
//PWM模块将待测信号输出到PA0,PA0通过导线,输入到PA6(TIM3的通道1):通过输入捕获模块,测量得到频率OLED_Init();PWM_Init();IC_Init();OLED_ShowString(1,1,"Freq:00000HZ");PWM_SetPrescaler(720-1); //Freq=72M/(PSC+1)/(ARR+1)改变频率PWM_setcompare1(50); //Duty=CCR/100改变通道1占空比//PA0口输出频率为Freq=72M/(PSC+1)/(ARR+1)=1000HZ//PA0口输出一个频率1000HZ,占空比为50%的待测信号while(1){OLED_ShowNum(1,6,IC_GetFreq(),5);}
}
(2) pwm.c
#include "Device/Include/stm32f10x.h" // Device header
void PWM_Init(void)
{
//根据PWM基本结构框图,时基单元初始化、输出比较单元选择(TIM1通道初始化)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //打开时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出(输出控制权转移给片上外设)GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);TIM_InternalClockConfig(TIM2); //选择内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstructure; //初始化时基单元TIM_TimeBaseInitstructure.TIM_ClockDivision=TIM_CKD_DIV1;TIM_TimeBaseInitstructure.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInitstructure.TIM_Period=100-1;//定时器周期,实际就是ARR的值。CCR的值直接就是占空比(分辨率为1%),若ARR为1000,分辨率为0.1%TIM_TimeBaseInitstructure.TIM_Prescaler=720-1;//通过改变PSC来改变PWM频率TIM_TimeBaseInitstructure.TIM_RepetitionCounter=0;//重复计数器,高级控制寄存器专用寄存器位,这里不用设置TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitstructure);//初始化定时器TIM_OCInitTypeDef TIM_OCInitstructure;TIM_OCStructInit(&TIM_OCInitstructure); //结构体赋初始值TIM_OCInitstructure.TIM_OCMode=TIM_OCMode_PWM1;TIM_OCInitstructure.TIM_OCPolarity=TIM_OCPolarity_High;TIM_OCInitstructure.TIM_OutputState=TIM_OutputState_Enable; //输出状态TIM_OCInitstructure.TIM_Pulse=0; //CCR的值TIM_OC1Init(TIM2,&TIM_OCInitstructure); //使用PA0口,对应第一个通道,使用OC1Init函数//TIM1通道初始化TIM_Cmd(TIM2,ENABLE);//计数器使能,启动定时器
}
void PWM_setcompare1(uint16_t compare)
{TIM_SetCompare1(TIM2,compare);//CCR的值
}
void PWM_SetPrescaler(uint16_t Prescaler)
{TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Immediate);//写入PSC//立刻生效
}
(3) IC.c
#include "Device/Include/stm32f10x.h" // Device header
void IC_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //打开时钟选择PA6.TIM3_CH1RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入,定时器TIM2345引脚,输入捕获通道GPIO应使用浮空输入GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);TIM_InternalClockConfig(TIM3); //选择内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstructure; //初始化时基单元TIM_TimeBaseInitstructure.TIM_ClockDivision=TIM_CKD_DIV1;TIM_TimeBaseInitstructure.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInitstructure.TIM_Period=65536-1;//防止计数溢出//定时器周期,实际就是ARR的值。CCR的值直接就是占空比(分辨率为1%),若ARR为1000,分辨率为0.1%TIM_TimeBaseInitstructure.TIM_Prescaler=72-1;//决定了测周法的标准频率Fc//通过改变PSC来改变PWM频率TIM_TimeBaseInitstructure.TIM_RepetitionCounter=0;//重复计数器,高级控制寄存器专用寄存器位,这里不用设置TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitstructure);//初始化定时器TIM_ICInitTypeDef TIM_ICInitstructure;TIM_ICInitstructure.TIM_Channel=TIM_Channel_1;//TIM_ICInitstructure.TIM_ICFilter=0xf;//选择输入比较滤波器,在0x0-0xf之间TIM_ICInitstructure.TIM_ICPolarity=TIM_ICPolarity_Rising;TIM_ICInitstructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//??????????TIM_ICInitstructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//不分频TIM_ICInit(TIM3,&TIM_ICInitstructure);//初始化TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//触发源选择TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//选择从模式TIM_Cmd(TIM3,ENABLE);//开启定时器}
uint32_t IC_GetFreq(void)
{return 1000000/(TIM_GetCapture1(TIM3)+1);//fx=fc/N(HZ);}
2.PWMI模式测频率占空比
(1)main.c
#include "Device/Include/stm32f10x.h" // Device header
#include "pwm.h"
#include "delay.h"
#include "OLED.h"
#include "IC.h"
uint8_t i;
int main(void)
{
//PWM模块将待测信号输出到PA0,PA0通过导线,输入到PA6(TIM3的通道1):通过输入捕获模块,测量得到频率OLED_Init();PWM_Init();IC_Init();OLED_ShowString(1,1,"Freq:00000HZ");OLED_ShowString(2,1,"Duty:00%");PWM_SetPrescaler(720-1); //Freq=72M/(PSC+1)/(ARR+1)PWM_setcompare1(50); //Duty=CCR/100while(1){OLED_ShowNum(1,6,IC_GetFreq(),5);OLED_ShowNum(2,6,IC_GetDuty(),2);}
}
(2)IC.c
#include "Device/Include/stm32f10x.h" // Device header
void IC_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //打开时钟选择PA6.TIM3_CH1RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);TIM_InternalClockConfig(TIM3); //选择内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstructure; //初始化时基单元TIM_TimeBaseInitstructure.TIM_ClockDivision=TIM_CKD_DIV1;TIM_TimeBaseInitstructure.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInitstructure.TIM_Period=65536-1;//防止计数溢出//定时器周期,实际就是ARR的值。CCR的值直接就是占空比(分辨率为1%),若ARR为1000,分辨率为0.1%TIM_TimeBaseInitstructure.TIM_Prescaler=72-1;//通过改变PSC来改变PWM频率TIM_TimeBaseInitstructure.TIM_RepetitionCounter=0;//重复计数器,高级控制寄存器专用寄存器位,这里不用设置TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitstructure);//初始化定时器TIM_ICInitTypeDef TIM_ICInitstructure;TIM_ICInitstructure.TIM_Channel=TIM_Channel_1;TIM_ICInitstructure.TIM_ICFilter=0x0;TIM_ICInitstructure.TIM_ICPolarity=TIM_ICPolarity_Rising;TIM_ICInitstructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;TIM_ICInitstructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//TIM_ICInit(TIM3,&TIM_ICInitstructure);TIM_PWMIConfig(TIM3,&TIM_ICInitstructure);//PWMI基本结构TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//触发源选择TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//选择从模式TIM_Cmd(TIM3,ENABLE);}
uint32_t IC_GetFreq(void)
{return 1000000/(TIM_GetCapture1(TIM3)+1);//fx=fc/N(HZ);}
uint32_t IC_GetDuty(void)
{return (TIM_GetCapture2(TIM3)+1)*100/(TIM_GetCapture1(TIM3)+1);
}