STM32学习笔记(十四)输入捕获实验

STM32F103ZET6之输入捕获实验



前言

对于STM32的学习可分为3个版本。
1.寄存器版本
2.库函数版本
3.HAL库版本
由于个人原因,选择库函数版本来进行STM32的学习。


提示:软件安装等问题,不进行讲解!!!

一、输入捕获基本原理

1.简介

输入捕获模式可以用来测量脉冲宽度或者测量频率。通过检测TIMx_CHx 上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。

2.工作过程

在这里插入图片描述
在这里插入图片描述

二、相关寄存器

1.捕获/比较模式寄存器 (TIMx_CCMR1)

在这里插入图片描述
TIMx_CCMR1 明显是针对 2 个通道的配置,低八位[7: 0]用于捕获/比较通道 1 的控制,而高八位[15: 8]则用于捕获/比较通道 2 的控制,因为 TIMx 还有 CCMR2 这个寄存器,所以可以知道CCMR2 是用来控制通道 3 和通道 4

2.TIMx_CMMR1 的[7:0]位

在这里插入图片描述

3.捕获/比较使能寄存器 (TIMx_CCER)

在这里插入图片描述

4.捕获/比较寄存器(TIMx_CCR1~4)

在这里插入图片描述

三、操作步骤

1.相应引脚

在这里插入图片描述

2.操作步骤

在这里插入图片描述
在这里插入图片描述

四、程序源码

1.timer.h

代码如下:

#ifndef __TIMER_H
#define __TIMER_H

#include "sys.h"

void TIM3_Int_Init(u16 arr,u16 psc);
void TIM3_PWM(u16 arr,u16 psc);
void TIM5_Cap_Init(u16 arr,u16 psc);
#endif

2.timer.c

代码如下:

#include "timer.h"
#include "led.h"

void TIM3_Int_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef IM_TimeBaseInitstr;
	NVIC_InitTypeDef NVIC_Initstr;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//定时器时钟使能
	
	IM_TimeBaseInitstr.TIM_Period=arr;
	IM_TimeBaseInitstr.TIM_Prescaler=psc;
	IM_TimeBaseInitstr.TIM_CounterMode=TIM_CounterMode_Up;
	IM_TimeBaseInitstr.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM3, &IM_TimeBaseInitstr);//初始化时钟
	
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//开启定时器中断
	
	NVIC_Initstr.NVIC_IRQChannel=TIM3_IRQn;
	NVIC_Initstr.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Initstr.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_Initstr.NVIC_IRQChannelSubPriority=2;
	NVIC_Init(&NVIC_Initstr);//配置NVIC
	
	TIM_Cmd(TIM3, ENABLE);//使能定时器
}
void TIM3_IRQHandler(void)//中断服务函数
{
	if(TIM_GetITStatus(TIM3, TIM_IT_Update)==SET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);//清除更新中断标志
		LED1=!LED1;
	}
}
void TIM3_PWM(u16 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_Initstr;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstr;
	TIM_OCInitTypeDef TIM_OCInitstr;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//定时器时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//GPIOB和复用时钟
	
	GPIO_Initstr.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_Initstr.GPIO_Pin=GPIO_Pin_5;
	GPIO_Initstr.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_Initstr);//初始化IO口为复用功能输出
	
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3 , ENABLE);//重映射,定时器3通道2映射PB5
	
	TIM_TimeBaseInitstr.TIM_Period=arr;
	TIM_TimeBaseInitstr.TIM_Prescaler=psc;
	TIM_TimeBaseInitstr.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitstr.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitstr);//初始化定时器3
	
	TIM_OCInitstr.TIM_OCMode=TIM_OCMode_PWM2;
	TIM_OCInitstr.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitstr.TIM_OCPolarity=TIM_OCPolarity_High ;
	TIM_OC2Init(TIM3, &TIM_OCInitstr);//设置定时器3通道2PWM的模式
	
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能预装载寄存器
	TIM_Cmd(TIM3, ENABLE);//使能定时器
}

TIM_ICInitTypeDef TIM5_ICInitstr;

void TIM5_Cap_Init(u16 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_Initstr;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstr;
	NVIC_InitTypeDef NVIC_Initstr;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_Initstr.GPIO_Mode=GPIO_Mode_IPD;
	GPIO_Initstr.GPIO_Pin=GPIO_Pin_0;
	GPIO_Initstr.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_Initstr);
	
	TIM_TimeBaseInitstr.TIM_Period=arr;
	TIM_TimeBaseInitstr.TIM_Prescaler=psc;
	TIM_TimeBaseInitstr.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitstr.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitstr);
	
	TIM5_ICInitstr.TIM_Channel=TIM_Channel_1;
	TIM5_ICInitstr.TIM_ICPolarity=TIM_ICPolarity_Rising;
	TIM5_ICInitstr.TIM_ICSelection=TIM_ICSelection_DirectTI;
	TIM5_ICInitstr.TIM_ICPrescaler=TIM_ICPSC_DIV1;
	TIM5_ICInitstr.TIM_ICFilter=0x00;
	TIM_ICInit(TIM5, &TIM5_ICInitstr);
	
	NVIC_Initstr.NVIC_IRQChannel=TIM5_IRQn;
	NVIC_Initstr.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Initstr.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_Initstr.NVIC_IRQChannelSubPriority=0;
	NVIC_Init(&NVIC_Initstr);
	
	TIM_ITConfig(TIM5,TIM_IT_CC1, ENABLE);
	TIM_Cmd(TIM5, ENABLE);
}
u8 TIM5CH1_CAPTURE_STA=0;//输入捕获状态
u16 TIM5CH1_CAPTURE_VAL;
void TIM5_IRQHandler(void)
{
	if((TIM5CH1_CAPTURE_STA&0x80)==0)//未成功捕获
	{
		if(TIM_GetITStatus(TIM5, TIM_IT_Update)!=RESET)//发生更新中断
		{
			if(TIM5CH1_CAPTURE_STA&0x40)//捕获到高电平
			{
				if((TIM5CH1_CAPTURE_STA&0x3F)==0x3F)//高电平时间太长
				{
					TIM5CH1_CAPTURE_STA|=0x80;//捕获一次
					TIM5CH1_CAPTURE_VAL=0xFFFF;
				}
				else
					TIM5CH1_CAPTURE_STA++;
			}
		}
	  if(TIM_GetITStatus(TIM5, TIM_IT_CC1)!=RESET)//发生捕获中断
		{
			if(TIM5CH1_CAPTURE_STA&0x40)
			{
				TIM5CH1_CAPTURE_STA|=0x80;
				TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);
				TIM_OC1PolarityConfig(TIM5, TIM_ICPolarity_Rising);
			}
			else
			{
				TIM5CH1_CAPTURE_STA=0;
				TIM5CH1_CAPTURE_VAL=0;
				TIM_SetCounter(TIM5, 0);
				TIM5CH1_CAPTURE_STA|=0x40;
				TIM_OC1PolarityConfig(TIM5, TIM_ICPolarity_Falling);
			}
		}
  }
			TIM_ClearITPendingBit(TIM5,TIM_IT_Update|TIM_IT_CC1);
}


3.main.c

代码如下:

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "beep.h"
#include "key.h"
#include "timer.h"
#include "usart.h"

extern u8 TIM5CH1_CAPTURE_STA;//输入捕获状态
extern u16 TIM5CH1_CAPTURE_VAL;

int main(void)
{
	u32 temp=0;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	uart_init(115200);
	delay_init();
    LED_Init();
	Beep_Init();
	KEY_Init();
	TIM5_Cap_Init(0xFFFF,72-1);//72M/72=1M
	while(1)
	{
		if(TIM5CH1_CAPTURE_STA&0x80)
		{
		temp=TIM5CH1_CAPTURE_STA&0x3F;
		temp*=65536;
		temp+=TIM5CH1_CAPTURE_VAL;
		printf("HIGH:%d us\r\n",temp);
		TIM5CH1_CAPTURE_STA=0;
		}
	 }
}

五、实验结果

在这里插入图片描述
在这里插入图片描述


总结

1.看完视频,一定自己写一遍程序。
2.烧写程序前,对程序进行分析,推理实验现象。
3.若实验现象与推理不一致,一定要认真分析程序。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白正在努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值