首页 > 其他分享 >STM32学习——输出比较和输入捕获

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

时间:2024-07-06 21:58:29浏览次数:18  
标签:输出 捕获 STM32 TIM GPIO 输入 通道

目录

一、输出比较

1.什么是输出比较

2.PWM波的基本参数

3.输出比较通道框图

4.输出比较模式

5.基本结构/步骤

6.Keil5代码

二、输入捕获

1.什么是输入捕获

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

3.输入捕获结构框图

4.主从触发模式

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

6.Keil5代码


一、输出比较

1.什么是输出比较

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

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

        输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置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.什么是输入捕获

        

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

        输入捕获:IC(Input 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);
}

标签:输出,捕获,STM32,TIM,GPIO,输入,通道
From: https://blog.csdn.net/2303_76686142/article/details/140189091

相关文章

  • 【STM32】RTT-Studio中HAL库开发教程二:RS485-DMA串行通信
    文章目录一、前期准备二、实验步骤1.使用STM32CubeMX配置初始化代码2.常用函数解析3.相关程序4.实验效果三、参考文章一、前期准备开发环境:基于RT-ThreadStudio软件的开发辅助软件:STM32CubeMX初始化代码生成调试软件:串口助手使用芯片:STM32F407VET6硬件环......
  • 零基础STM32单片机编程入门(八)定时器PWM输入实战含源码视频
    文章目录一.概要二.PWM输入框架图三.CubeMX配置一个PWM输入例程1.硬件准备2.创建工程3.调试四.CubeMX工程源代码下载五.讲解视频链接地址六.小结一.概要脉冲宽度调制(PWM),是英文“PulseWidthModulation”的缩写,简称脉宽调制,是利用单片机数字输出(1或0)来对外部模拟......
  • STM32封装ESP8266一键配置函数:实现AP模式和STA模式切换、服务器与客户端创建
    鱼弦:公众号【红尘灯塔】,CSDN博客专家、内容合伙人、新星导师、全栈领域优质创作者、51CTO(Top红人+专家博主)、github开源爱好者(go-zero源码二次开发、游戏后端架构https://github.com/Peakchen)STM32封装ESP8266一键配置函数:实现AP模式和STA模式切换、服务器与客户端创建......
  • STM32F1+HAL库+FreeTOTS学习6——临界段代码保护函数&任务调度器的挂起和恢复函数
    STM32F1+HAL库+FreeTOTS学习6——临界段代码保护函数临界段临界段代码保护函数任务调度器的挂起和恢复函数上一期我们学习了FreeRTOS的内核中断管理以及中断屏蔽控制函数,下面我们来学习临界端代码保护函数的使用临界段临界段也叫临界区,指的是必须完整运行完,不能被......
  • STM32F1+HAL库+FreeTOTS学习3——任务创建(动态和静态两种)
    STM32F1+HAL库+FreeTOTS学习3——任务创建(动态和静态两种)任务创建API函数任务创建流程代码实现1.动态任务创建和删除2.静态任务创建和删除上期我们学习了STM32移植FreeRTOS搭建基准工程,现在我们来学习任务创建任务创建API函数前面我们了解到,FreeRTOS相对于裸机......
  • 基于STM32F1系列,驱动L298N电机驱动板实现直流电机的启动、停止、调速功能
    一.L298N电机驱动板电源引脚VCC外接直流电源引脚,电压范围在5~35V之间GNDGND是接地引脚,连接到电源负极5V驱动芯片内部逻辑供电引脚,如果安装了5V跳帽,则此引脚可输出5V电压,为微控板或其他电路提供电力供给,如果拔掉5V跳帽,则需要独立外接5V电源控制引脚IN1&IN2电机驱动器......
  • STM32:ADC采集光照(含完整源码)
    需求通过ADC转换实现光照亮度的数字化测量,最后将实时测量的结果打印在串口上。一、ADC概要  ADC全称是Analog-to-DigitalConverter模数转换器,一般我们把模拟信号(Analogsignal)用A来进行简写,数字信号(digitalsignal)用D来表示。  自然界中绝大部分都是模拟信......
  • 【BP时序预测】基于布谷鸟优化算法CS实现负荷数据预测单输入单输出附matlab代码
    %负荷数据预测单输入单输出(BP时序预测)%使用布谷鸟优化算法实现%假设你已经有了输入数据和对应的输出数据%输入数据应该是一个矩阵,每一行代表一个样本,每一列代表一个特征%输出数据应该是一个列向量,每个元素代表对应样本的输出%设置布谷鸟优化算法参数max_iter=......
  • 基于STM32技术的物流分拣控制系统毕业设计
    基于STM32技术的物流分拣控制系统毕业设计摘要随着物流行业的快速发展,对分拣效率和准确性的要求日益提高。本文设计了一款基于STM32技术的物流分拣控制系统,旨在通过自动化和智能化手段,提高物流分拣的效率和准确性。该系统集成了STM32微控制器、传感器技术、电机驱动模块、无......
  • 基于STM32的车速检测系统设计毕业设计
    基于STM32的车速检测系统设计毕业设计摘要:随着汽车电子技术的快速发展和智能交通系统需求的日益增长,车速检测作为车辆状态监控的重要组成部分,其准确性和实时性对于提高行车安全、优化交通管理具有重要意义。本毕业设计旨在设计并实现一个基于STM32单片机的车速检测系统,该系统......