STM32学习——输出比较和输入捕获

目录

一、输出比较

1.什么是输出比较

2.PWM波的基本参数

3.输出比较通道框图

4.输出比较模式

5.基本结构/步骤

6.Keil5代码

二、输入捕获

1.什么是输入捕获

2.输入捕获通道测量频率的方法

3.输入捕获结构框图

4.主从触发模式

5.输入捕获和PWMI模式框图

6.Keil5代码


一、输出比较

1.什么是输出比较

        •OCOutput Compare)输出比较。输出比较只在通用定时器和高级定时器中存在。以通用定时器的框图来介绍输出比较。

        看图中时基单元下方一大堆东西,也就是CNT计数器下方,是捕获/比较寄存器,这个寄存器是输出比较和输入捕获共用的,两种功能在同一时刻只能选择一种执行。先将其用作输出比较来看,输出比较最重要的一个功能就是产生PWM波。这里先有个概念。

        输出比较可以通过比较CNTCCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波。每个高级定时器和通用定时器都拥有4个输出比较通道,高级定时器的前3个通道额外拥有死区生成和互补输出的功能。互补输出好理解,就是取反,死区生成是用来解决冒险现象的,多个信号同时发生变化时,可能因为发生变化的先后顺序导致输出信号有一段不稳定的“毛刺”,死区生成就是在这种情况下,多个输入信号发生变化的时候先“中断”一会输出与输入之间的关系,等到输入信号稳定下来,再重新“建立”输出与输入的关系。

2.PWM波的基本参数

        PWM:Pulse Width Modulation,脉冲宽度调制。在51中已经学习过,不过多赘述。复习一下其基本参数:

        频率 = 1/Ts     占空比 = Ton/Ts    分辨率:占空比变化步距

        Ts:PWM波周期     Ton:PWM波一次周期中高电平持续时间     

3.输出比较通道框图

        结构比较明了,看图就行

高级定时器的输出比较通道:

通用定时器的输出比较通道:

4.输出比较模式

模式描述
冻结CNT=CRR时,REF保持为原状态
匹配时置有效电平CNT=CRR时,REF置有效状态
匹配时置无效电平CNT=CRR时,REF置无效状态
匹配时电平翻转CNT=CRR时,REF电平翻转
强制为无效电平CNT与CRR无效,REF强制为无效电平
强制为有效电平CNT与CRR无效,REF强制为有效电平
PWM模式1

向上计数:CNT<CRR时,REF置有效电平;CNT≥CRR时, REF置无效电平

向下计数:CNT>CRR时,REF置无效电平;CNT≤CRR时, REF置有效电平

PWM模式2

向上计数:CNT<CRR时,REF置无效电平;CNT≥CRR时, REF置有效电平

向下计数:CNT>CRR时,REF置有效电平;CNT≤CRR时, REF置无效电平

        具体这些模式在Keil5中一个函数即可设置。

5.基本结构/步骤

        使能时钟->配置GPIO->配置好时基单元->配置好输出比较单元->打开时基单元的运行控制

6.Keil5代码

        输出比较常用函数:

初始化输出比较(OC)
TIM_OC1Init
TIM_OC2Init
TIM_OC3Init
TIM_OC4Init
TIM_OCStructInit            给初始化函数中的结构体赋一个默认值

强制输出(为0/1)模式
TIM_ForcedOC1Config
TIM_ForcedOC2Config
TIM_ForcedOC3Config
TIM_ForcedOC4Config

配置CCR寄存器的预装功能(影子寄存器)
TIM_OC1PreloadConfig        
TIM_OC2PreloadConfig
TIM_OC3PreloadConfig
TIM_OC4PreloadConfig

配置快速使能
TIM_OC1FastConfig
TIM_OC2FastConfig
TIM_OC3FastConfig
TIM_OC4FastConfig

外部事件时清除REF信号
TIM_ClearOC1Ref
TIM_ClearOC2Ref
TIM_ClearOC3Ref
TIM_ClearOC4Ref

配置输出极性(原码输出还是取非后输出),带N的是高级定时器中互补通道的配置函数
TIM_OC1NPolarityConfig
TIM_OC2NPolarityConfig
TIM_OC3NPolarityConfig
OC4没有互补通道
TIM_OC1PolarityConfig
TIM_OC2PolarityConfig
TIM_OC3PolarityConfig
TIM_OC4PolarityConfig

单独修改输出使能
TIM_CCxCmd
TIM_CCxNCmd

选择输出比较模式
TIM_SelectOCxM

单独更改CCR寄存器的值的函数
TIM_SetCompare1
TIM_SetCompare2
TIM_SetCompare3
TIM_SetCompare4

仅高级定时器使用,使用高级定时器输出PWM时,使用此函数使能主模式,否则PWM无法正常输出
TIM_CtrlPWMOutputs

        使用输出比较产生PWM波一般初始化步骤(ARR与PSC的值根据需要调整):

void PWM_Init(void)
{
	//第一步,使能时钟
	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_TimeInitstructure;
	TIM_TimeInitstructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeInitstructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeInitstructure.TIM_Period = 100 - 1;     //ARR
	TIM_TimeInitstructure.TIM_Prescaler = 720 - 1;  //PSC
	TIM_TimeInitstructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeInitstructure);
	
	//第四步,输出比较OC
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);
	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(TIM2,&TIM_OCInitStruct);
	
	//第五步,运行控制
	TIM_Cmd(TIM2,ENABLE);
}

二、输入捕获

1.什么是输入捕获

        

        还是通用定时器的框图,在时基单元下方,捕获/比较寄存器左边,就是输入捕获部分的框图。

        输入捕获:ICInput Capture)输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值(计数器的值)将被锁存到CCR(捕获/比较寄存器,下同)中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数。每个高级定时器和通用定时器都有四个输入捕获通道。输入捕获通道可以设置为PWMI模式,可以同时测量PWM波的频率和占空比。此外,配合主从触发模式可以实现硬件电路自动测量,就省去了软件代码反复调用函数和中断所需要的时间。

2.输入捕获通道测量频率的方法

        1.测频法:在一段时间T内,对上升沿次数进行计数,得到N,则频率f=N/T;适用于高频信号,因为如果信号频率比较低,在T时间内可能一次上升沿都记不到,得到的频率为0,这显然误差比较大。不过即便是对高频信号用测频法,也可能存在一次上升沿的误差,比如在信号为低电平时,时间T结束了,那时间T结束时,信号低电平之后的那一个上升沿就没有计上。

        2.测周法:在两个上升沿之间,以一个自己定的,标准频率F计次,计了几次,N就是多大,那么此时频率f=F/N。这种方法适用于低频信号,信号频率低,两个上升沿之间间隔时间大,N就大,得到的结果误差相对会小一些。如果用于高频,那么试想一下极端情况,两个上升沿之间时间间隔非常短,短到N为0,那么得到频率就是0,误差非常大。同样的测周法也和测频法一样,N有一次计数上的误差。

        中界频率:上述两种方法的使用场景是不同的,针对信号频率的高低,使用不同的方法,误差也是不一样的,那高频低频的界限是什么呢?这就引入了中界频率的概念,中界频率处,两种方法的误差是一样的,信号频率高于中界频率,就认为是高频,用测频法,信号频率低于中界频率,就认为是低频,用测周法。

3.输入捕获结构框图

        

        输入捕获通道,个人认为应该看成两个通道一组,四个通道构成两组,每组两个。如框图所示。信号从通道1进入后,经过滤波器去除毛刺,然后检测边沿,可以选择捕获上升沿还是下降沿,然后选择是原码输出,还是取非再输出,到TI1FP1为止,通道1和2的流程一样。两个通道的信号都可以从通道1的输出通道输出(IC1),同样的,通道1也可以从IC2输出(框图中没画),这样。通道1和2的输出部分是交叉着的。这一点可以用来同时测频率和占空比。一个IO口输入,然后通过两个通道分别输出频率,占空比。

4.主从触发模式

        

        将定时器内部的引脚,或者说信号,映射到TRGO引脚,再通过TRGO引脚发送给其他外设,用于触发其他外设。

        从模式:接受其他/自身外设的信号,被别的信号控制去执行一些功能。

        触发源选择:选择控制从模式的信号源。映射到TRGI。

5.输入捕获和PWMI模式框图

        输入捕获:使能时钟->配置GPIO->配置输入捕获单元->配置时基单元->触发源,从模式->打开运行控制

        基本流程不变,在输入捕获配置步骤中,不再使用初始化函数,而是直接用TIM_PWMIConfig()函数自动配置。

6.Keil5代码

        常用函数:


/*
TIM_ICInit              //初始化,四个输入通道公用一个函数,在输出中是四个函数分开的
TIM_PWMIConfig					//可以快速配置两个输入通道
TIM_ICStructInit				//给结构体赋一个默认初始值

//三兄弟
TIM_SelectInputTrigger  //选择输入触发源TRGI(从模式触发源的选择)
TIM_SelectOutputTrigger	//选择输出触发源TRGO(主模式输出的触发源)
TIM_SelectSlaveMode 		//选择从模式

TIM_SetIC1Prescaler			//单独配置1/2/3/4通道的预分频器
TIM_SetIC2Prescaler
TIM_SetIC3Prescaler
TIM_SetIC4Prescaler

TIM_GetCapture1					//读取通道1/2/3/4的CCR
TIM_GetCapture2					//输出比较模式下,CCR寄存器只写,输入捕获模式下,CCR寄存器只读
TIM_GetCapture3
TIM_GetCapture4
*/

        初始化函数:


void IC_Init(void)
{
	//第一步,使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	
	//配置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);
	
	//配置时基单元
	TIM_InternalClockConfig(TIM3); //使用内部时钟源
	
	TIM_TimeBaseInitTypeDef TIM_Initstructure;
	TIM_Initstructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_Initstructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_Initstructure.TIM_Period = 65536 - 1;					//ARR
	TIM_Initstructure.TIM_Prescaler = 72 - 1;				//PSC
	TIM_Initstructure.TIM_RepetitionCounter = 0;  //高级定时器的重复计数器
	TIM_TimeBaseInit(TIM3,&TIM_Initstructure);
	
	//配置输入捕获单元
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; //选通道
	TIM_ICInitStruct.TIM_ICFilter = 0xF;					//滤波
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;						//
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;  //直接通道
	TIM_PWMIConfig(TIM3,&TIM_ICInitStruct);
	
	//从模式
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);
	
	//使能中断控制
	TIM_Cmd(TIM3,ENABLE);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值