当前位置: 首页 > article >正文

江科大STM32入门——输入捕获笔记总结

wx:嵌入式工程师成长日记

ddd39e6b19e14e33897aa6213919c759.png

输入捕获原理

输入捕获是指 STM32 的定时器可以对外部输入信号的边沿进行检测,并记录下相应的时刻。其基本原理基于定时器的计数器和相关寄存器。

当外部信号连接到定时器的输入捕获引脚时,定时器会根据设定的捕获条件,如上升沿或下降沿,对信号进行监测。当满足捕获条件时,定时器会将当前计数器的值复制到捕获 / 比较寄存器中。通过读取捕获 / 比较寄存器的值,就可以获取到信号边沿出现的时刻。

波形图

1.如果两个上跳沿的捕获发生在同一个计数周期内,两个计数值分别为CCR1和CCR2,则方波的周期为CCR2-CCR1个计数周期,根据定时器的周期就可以计算出方波周期和频率。

如果方波周期超过定时器的计数周期,或两次输入捕获发生在相邻的两个定时周期内,如图CCR2和CCR3,则只需将计数器的计数周期和事件发生次数考虑进去即可,根据CCR2和CCR3计算的脉冲周期应该是 ARR - CCR1 + CCR2。 

 输入捕获代码配置:

1.定时器初始化配置

    htim2.Instance = TIM2;
      //将定时器设置为TIM2。
    htim2.Init.Prescaler = 84-1; 
       //设置预分频器的值为83(实际值减去1)。预分频器用于将输入时钟频率分频,从而得到更低的计数频率。在这里,输入时钟频率将被除以84,获得的计数频率为84Mhz /(84-1 +1) = 1MHz。
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP; 
       //将计数模式设置为向上计数模式。在向上计数模式下,计数器从0递增到自动重载值。
    htim2.Init.Period = 0xFFFFFFFF;  
      //设置自动重载寄存器的值为0xFFFFFFFF(32位最大值)。这意味着计数器将从0递增到0xFFFFFFFF,然后重新从0开始循环。
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      //设置时钟分频系数为不分频(TIM_CLOCKDIVISION_DIV1)。时钟分频用于进一步分频计数器的时钟频率。
    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
       //启用自动重载预装载功能。当该功能启用时,新的自动重载值在下一个更新事件时生效,以避免在计数器工作时意外更改自动重载值。

2.启动定时器TIM2的中断模式,并开始输入捕获功能

HAL_TIM_Base_Start_IT(&htim2);														
/* 启动TIM2定时器的中断模式  */
	HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);												
/* 以中断方式开启TIM2的输入捕获模式  */

3.定时器回调函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim == &htim2){								    /* 判断是否为定时器TIM2 */
		 if(ic_state == runing){					    /* 判断是否为是 正在运行状态 */
				tim_over ++;					        /* 定时器溢出值计数 */
		 }
	}
}
	
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim == &htim2){							         /* 判断是否为定时器TIM2 */
		 if(ic_state == idle){							 /* 判断状态是不是 空闲 */
				ic_state = runing;						 /* 将状态设置为 正在运行 */
				tim_value = 0;							 /* 计数值清零 */
				__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING); /* 将TIM2的通道1捕获极性设置为下降沿捕获 */
			 __HAL_TIM_SET_COUNTER(&htim2,0);		     /* 将TIM2的计数值设置为0 */
		 }else{								             /* 此时不是空闲状态 */
				HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1);/* 停止定时器2输入捕获功能 */
				ic_state = end;						     /* 将状态设置为 结束 */
			  tim_value = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);	 /* 获取此时计数值 */
		 	 __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);/* 将TIM2的通道1捕获极性设置为上升沿捕获 */
		 }
	}
}

PWM波(输出捕获)

PWM初始化:

//TIM3 PWM初始化
//arr   重装载值
//psc   预分频系数
void TIM3_PWM_Init(u16 arr,u16 psc)
{
    GPIO_InitTypeDef     GPIO_InitStrue;
    TIM_OCInitTypeDef     TIM_OCInitStrue;
    TIM_TimeBaseInitTypeDef     TIM_TimeBaseInitStrue;
    
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);        //使能TIM3和相关GPIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);// 使能GPIOB时钟(LED在BP5引脚),使能AFIO时钟(定时器3通道2需要重映射到BP5引脚)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    
    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_5;     // TIM_CH2
    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;    // 复用推挽
    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;    //设置最大输出速度
    GPIO_Init(GPIOB,&GPIO_InitStrue);                //GPIO端口初始化设置
    
    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);
    
    TIM_TimeBaseInitStrue.TIM_Period=arr;    //设置自动重装载值
    TIM_TimeBaseInitStrue.TIM_Prescaler=psc;        //预分频系数
    TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up;    //计数器向上溢出
    TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1;        //时钟的分频因子,起到了一点点的延时作用,一般设为TIM_CKD_DIV1
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue);        //TIM3初始化设置(设置PWM的周期)
    
    TIM_OCInitStrue.TIM_OCMode=TIM_OCMode_PWM2;        // PWM模式2:CNT>CCR时输出有效
    TIM_OCInitStrue.TIM_OCPolarity=TIM_OCPolarity_High;// 设置极性-有效为高电平
    TIM_OCInitStrue.TIM_OutputState=TIM_OutputState_Enable;// 输出使能
    TIM_OC2Init(TIM3,&TIM_OCInitStrue);        //TIM3的通道2PWM 模式设置
 
    TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);        //使能预装载寄存器
    
    TIM_Cmd(TIM3,ENABLE);        //使能TIM3
}

PWM模式:

PWM模式1:在向上计数时,一旦TIMX_CNT<TIMX_CCR1时通道1为有效电平,否则为无效电平:在向下计数时,一旦TIMX_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。
PWM模式2:在向上计数时,一旦TIMX_CNT<TIMX_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMX_CNT>TIMX_CCR1时通道1为有效电平,否则为无效电平。


http://www.kler.cn/a/487766.html

相关文章:

  • Makefile文件/其他文件中出现的“变量/符合”,如何查看定义?
  • verilogHDL仿真详解
  • JavaFx 21 项目Markdown 预览、编辑、新建、文件树、删除、重命名
  • huggingface上下载数据
  • Python自学 - 类进阶(可调用对象)
  • 《上古重生》V20241127111039官方中文学习版
  • 将光源视角的深度贴图应用于摄像机视角的渲染
  • 系统架构设计师考点—计算机网络
  • 命令模式详解与应用
  • TensorFlow Quantum快速编程(基本篇)
  • CES 2025|美格智能高算力AI模组助力“通天晓”人形机器人震撼发布
  • 【计算机网络】什么是网关(Gateway)?
  • 国产游戏崛起,燕云十六移动端1.9上线,ToDesk云电脑先开玩
  • 安捷伦等程控电源压测工具支持所有NationalInstruments.Visa协议的电源。
  • 初学stm32 --- ADC单通道采集
  • 【数据结构】 树的遍历:先序、中序、后序和层序
  • Ubuntu | 系统软件安装系列指导说明
  • Java一个简单的反弹动画练习
  • 统一门户单点登入(C#-OOS机制)
  • 物联网:七天构建一个闭环的物联网DEMO-MQTT的配置