6 计时器(五)

6-6 TMI输入捕获演示

PWM分辨率技巧:如果是要1%,那就定ARR + 1 = 100;如果是要0.1%,那就定ARR + 1 = 1000。

1.输入捕获模拟测频率程序

主函数:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

int main(void)
{
	OLED_Init();
	PWM_Init();
	IC_Init();

	OLED_ShowString(1,1,"Freq:00000Hz");
	PWM_SetPrescaler(720 - 1);		//Freq = 72M / (PSC + 1) / 100
	PWM_SetCompare1(50);			//Duty = CCR / 100
	
	while (1)
	{
		OLED_ShowNum(1,6,IC_GetFreq(),5);
	}
}

pwm.c

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	//1.把TIM外设与GPIO外设的时钟打开
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	TIM_InternalClockConfig(TIM2);  //选择内部时钟源TIM2
	
	//4.配置GPIO,PWM对应的GPIO配置位复位推挽输出
	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;  		 //修改了引脚复用,这里也得进行对应修改(0-15)	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
		
	
	//2.配置时基单元
	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自动重装值(总数)
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 -1;					//PSC预分频的值(一周期计多少次)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;				//重复计数器的值(高级TIM才有)
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	//3.配置输出比较单元(输出比较模式,极性选择,输出使能,设置CRR的值)
	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口对应OC1口(参考引脚定义表)
	
	TIM_Cmd(TIM2, ENABLE);
}

//调节CCR1寄存器的值,从而控制PWM的占空比
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);
}

//单独修改PSC
void PWM_SetPrescaler(uint16_t Prescaler)
{
	TIM_PrescalerConfig(TIM2, Prescaler, TIM_PSCReloadMode_Immediate);
}

ic函数:

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	 //1.把TIM外设与GPIO外设的时钟打开
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	//配置GPIO,PWM对应的GPIO配置位复位推挽输出
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	//2.GPIO初始化
	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);
	
	//3.配置时基单元
	TIM_InternalClockConfig(TIM3);  //选择内部时钟源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自动重装值(设大值,防止溢出)
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 -1;					//PSC预分频的值(一周期计多少次)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;				//重复计数器的值(高级TIM才有)
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	//4.配置输入捕获单元(包括滤波器,极性,直连通道)
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel= TIM_Channel_1; 				 //选择通道
	TIM_ICInitStructure.TIM_ICFilter = 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);
	
	//5.选择触发源,选择TI1FP1
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);
	
	//6.配置从模式为Reset
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
	
	//7.调用TIM_Cmd,启动定时器
	TIM_Cmd(TIM3, ENABLE);
}

uint32_t IC_GetFreq(void)
{
	return 1000000 / TIM_GetCapture1(TIM3);
}

显示测试结果为1001Hz

2.PWMI测量频率和占空比

主函数:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

int main(void)
{
	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) / 100
	PWM_SetCompare1(50);			//Duty = CCR / 100
	
	while (1)
	{
		OLED_ShowNum(1,6,IC_GetFreq(),5);
		OLED_ShowNum(2,6,IC_GetDuty(),2);
	}
}

IC主函数:

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	 //1.把TIM外设与GPIO外设的时钟打开
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	//配置GPIO,PWM对应的GPIO配置位复位推挽输出
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	//2.GPIO初始化
	GPIO_InitTypeDef GPIO_InitStructure;
	//对于普通的开漏推挽输出,引脚的控制权来自输出数据库,如果用定时器来控制引脚,需使用复用开漏,来自片上外设控制引脚,断开输出数据寄存器
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  		//TIM3 CH3		 	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//3.配置时基单元
	TIM_InternalClockConfig(TIM3);  //选择内部时钟源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自动重装值(设大值,防止溢出)
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 -1;					//PSC预分频的值(一周期计多少次)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;				//重复计数器的值(高级TIM才有)
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	//4.配置输入捕获单元(包括滤波器,极性,直连通道)
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel= TIM_Channel_1; 				 //选择通道
	TIM_ICInitStructure.TIM_ICFilter = 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_PWMIConfig(TIM3, &TIM_ICInitStructure);		//快捷地把电路配置为PWMI模式地标准结构(只适合通道1和通道2)
	
	//5.选择触发源,选择TI1FP1
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);
	
	//6.配置从模式为Reset
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
	
	//7.调用TIM_Cmd,启动定时器
	TIM_Cmd(TIM3, ENABLE);
}

uint32_t IC_GetFreq(void)
{
	return 1000000 / TIM_GetCapture1(TIM3);  //TIM_GetCapture1读取ccr
}

uint32_t IC_GetDuty(void)
{
	return TIM_GetCapture2(TIM3)*100 / TIM_GetCapture1(TIM3);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值