浅谈通用定时器的输入捕获输出比较与PWM实现

1.通用定时器(TIM2-TIM5)主要特性

(1)==16 位(TIM3 和 TIM4)==或 32 位(TIM2 和 TIM5) 递增、递减和递增/递减自动重载计数器。

(2)16 位可编程预分频器,用于对计数器时钟频率进行分频 (即运行时修改),分频系数介于 1 到 65536 之间。

(3)多达 4 个独立通道,可用于:
输入捕获
输出比较
PWM 生成(边沿和中心对齐模式)
— 单脉冲模式输出

(4)使用外部信号控制定时器且可实现多个定时器互连的同步电路。

(5)发生如下事件时生成中断/DMA 请求
更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)
触发事件(计数器启动、停止、初始化或通过内部/外部触发计数)
输入捕获
输出比较

(6)支持定位用增量(正交)编码器和霍尔传感器电路

(7)外部时钟触发输入或逐周期电流管理

2.功能实现

0

2.1输入捕获/输出比较

1

2
3
输入捕获的实现代码(获取key2的按下时间并打印)

//TIM5输入捕获初始化函数
void TIM5_ICInit(u8 PreemptionPriority, u8 SubPriority)
{
	//开启GPIOA时钟线
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	//开启TIM5时钟线
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
	
	
	GPIO_InitTypeDef GPIO_InitStructure;
	//引脚配置为复用模式
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	//初始化GPIO
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//将PA0引脚重映射到TIM5上
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5);
	
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 10000-1;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 8400-1;
	//仅限于TIM1/TIM8配置PWM需要
	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter = ;
	
	//时基单元初始化
	TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStruct);
	
	//软件产生更新事件
	TIM_GenerateEvent(TIM5, TIM_EventSource_Update);
	
	//清除标志位
	TIM_ClearFlag(TIM5, TIM_FLAG_Update);
	
	//清空计数器
	TIM_SetCounter(TIM5, 0);
	
	//输入捕获配置
	TIM_ICInitTypeDef TIM_ICInitStruct;
	//使用通道1
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
	//设置滤波模式为2
	TIM_ICInitStruct.TIM_ICFilter = 2;
	//边沿触发模式选择双边沿触发
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
	//选择不分频
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	//选择输入源为TI1FP1
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
	//初始化输入捕获
	TIM_ICInit(TIM5, &TIM_ICInitStruct);
	//开启通道1
	TIM_CCxCmd(TIM5, TIM_Channel_1, TIM_CCx_Enable);
	
	//开启更新中断和通道1中断
	TIM_ITConfig(TIM5, TIM_IT_Update|TIM_IT_CC1, ENABLE);
	
	//配置优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM5_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = PreemptionPriority;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = SubPriority;
	NVIC_Init(&NVIC_InitStruct);
}

//TIM5中断处理函数
void TIM5_IRQHandler(void)
{
	static u32 time5 = 0;
	//判断是否是因更新中断进的中断
	if(TIM_GetITStatus(TIM5, TIM_IT_Update) == SET)
	{
		
		time5++;
		
		//清除标志位
		TIM_ClearITPendingBit(TIM5, TIM_IT_Update);
	}
	
	//判断是否是因通道1中断进的中断
	if(TIM_GetITStatus(TIM5, TIM_IT_CC1) == SET)
	{
		if(key1)
		{
			TIM6_DelayMs(40);		
			//清空计数器
			TIM_SetCounter(TIM5, 0);
			//开启TIM5
			TIM_Cmd(TIM5, ENABLE);
		}
		else
		{
			TIM6_DelayMs(40);
			double miao = (double)(TIM_GetCounter(TIM5)+1)/10000 + time5;
			printf("key1按键时长 = %.2lf\r\n",miao);
			time5 = 0;
			
			//关闭TIM5
			TIM_Cmd(TIM5, DISABLE);
		}
		
		

		//清除标志位
		TIM_ClearITPendingBit(TIM5, TIM_IT_CC1);
	}	
}

2.2PWM实现

void PWM_Init(u16 x)
{
	//开启GPIOC时钟线
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
	//开启TIM3时钟线
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM3);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 10*x-1;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 8400-1;
	//仅限于TIM1/TIM8配置PWM需要
	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter = ;
	
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
	
	//软件产生更新事件
	TIM_GenerateEvent(TIM3, TIM_EventSource_Update);
	
	//清除标志位
	TIM_ClearFlag(TIM3, TIM_FLAG_Update);
	
	//清空计数器
	TIM_SetCounter(TIM3, 0);
	
	//使能定时器
	TIM_Cmd(TIM3, ENABLE);
	
	//PWM配置
	TIM_OCInitTypeDef TIM_OCInitStruct;
	//输出比较模式设置为PWM1
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	//有效电平设为低电平
	TIM_OCInitStruct.TIM_OCPolarity =TIM_OCPolarity_Low;
	//使能输出状态
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	//设置比较值
	TIM_OCInitStruct.TIM_Pulse = 0;
	TIM_OC1Init(TIM3, &TIM_OCInitStruct);
	
	//打开通道1
	TIM_CCxCmd(TIM3, TIM_Channel_1, TIM_CCx_Enable);
	
	
}

//在其他地方可通过调用
TIM_SetCompare1(TIM3,x);
//实现修改比较值x

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值