嵌入式学习之通用定时器输入捕获和库函数小总结

1.按块分析输入捕获的整个过程:

输入捕获的流程图:(仅以通道1为例)
在这里插入图片描述
(1)设置滤波器:
在这里插入图片描述
浅薄的理解:这一部分跟“去抖”有些相似
其中fDTS是根据内部时钟CK_INT设置的,这两个频率是为了去设置IC1F[3:0]这四位从而改变采样频率作准备的。
(假设我们是上升沿触发),例如设置这四位为0011,则采样频率f SAMPLING =f CK_INT ,N=8 。就是说以CK_INT 这个频率采集8次,如果八次都是高电平就会触发输入捕获。
(2)设置捕获极性
在这里插入图片描述
(3)设置输入捕获映射通道
在这里插入图片描述
什么意思呢?如图所示:
在这里插入图片描述
(4)设置捕获分频器
在这里插入图片描述
这就很好理解了,比如说我们上升沿捕获,我们可以通过设置分频系数控制每几个上升沿触发一次捕获。

2.输入捕获到底干了啥?

在这里插入图片描述

3.对计时器的寄存器的小总结:

(1)TIMx_CR1、TIMx_CNT、TIMx_PSC、TIMx_ARR:设置时基单元
(2)TIMx_CCMR1、TIMx_CCMR2:与四个通道的输入输出有关的配置
几个符号说明:
①CCx:Capture/Compare,设置比较器是用于捕获(输入)还是比较(输出)
②OCx:Output compare,输出比较
③ICx:Input capture,输入捕获
④CHx、TIx:都指的是映射的引脚,前者是输出状态地下的表示,后者是输入状态下的表示。
⑤ICxPS:输入捕获后经过分频后的信号
⑥OCxREF:输出的有效信号还未经过输出极性的设置
(3)TIMx_CCER: 捕获/ 比较使能寄存器,多用于配置四个通道的极性和使能输入或输出,
(4)TIMx_CCRx:四个通道的捕获比较寄存器:
输出时用作配置比较值,从而影响占空比
输入时用于触发输入捕获存储此时计数器的值

4.库函数的用途小总结:

void TIM_DeInit(TIM_TypeDef* TIMx);
用于复位,不用管。
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
只要使用计时器,时基单元肯定必须配置:选择时钟源,加载值和分频系数
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
上面这四个用于设置输出PWM时用到的参数,包括选择PWM输出模式,选择输出极性,设置比较值。注意:设置输出时是按输出通道分的库函数
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
这一个用于设置输入捕获的参数,就是最开始我们说的那几个。可以看出,配置输入时不是按输入通道分的库函数
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
pwm输入模式?还没用过,http://www.manongjc.com/detail/16-wcqebecwsvnhuxo.html
void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef TIM_BDTRInitStruct);
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef
TIM_TimeBaseInitStruct);
这个函数将定时器时基单元初始化为默认值
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
同理,这个函数将定时器输出初始化为默认值
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);
同理,这个函数将定时器输入初始化为默认值
void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct);
同理,这个函数将定时器互补输出(我猜的还没用)初始化为默认值
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
必用,定时器的使能
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
还是跟高级定时器有关
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
使能各种中断包括更新中断,输入捕获中断等等
void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource);
用于软件产生事件
void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength);
没用,用到再补充
void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState);
没用,用到再补充
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
没用,用到再补充
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
没用,用到再补充
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, uint16_t TIM_ICPolarity, uint16_t ICFilter);
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
uint16_t ExtTRGFilter);
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
uint16_t ExtTRGFilter);
以上全根SMCR寄存器有关,没用,用到再补充
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
单独设置定时器的预分频系数,软件置UG位将其写入
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
单独设置定时器的计数模式:向上、向下或向上向下
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
没用,用到再补充
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
没用,用到再补充
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
以上四个单独用于设置输出参考信号OC1REF的动作,现在主要是选择PWM输出模式
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
设置自动装载的预加载
void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState);
没用,用到再补充
void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState);
没用,用到再补充
void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
用于设置PWM输出比较值的预加载
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
输出比较快速使能
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
清除OC1REF=0
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
单独配置输入输出的极性,注意不光可以是输出的极性,也可以是输入的极性改变配置
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
禁止更新事件
void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource);
软件通过该位选择UEV事件的源
void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode);
设置单脉冲模式
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
单独设置计数器
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
单独设置装载值ARR
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
以上四个用于设置捕获比较寄存器的比较值,不只输出用奥,随便你想什么时候用都行
void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
单独设置输入捕获的分频系数
void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD);
用于设置输入捕获时的滤波器部分的fDTS频率
uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);
用于获得捕获比较寄存器里面的值,不只输入用奥,随便你想什么时候用都行
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
获得此时计数器的值
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);
获得此时分频系数的值
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
获得状态标志位
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
清除状态标志位
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
获得中断标志位
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
获得中断标志位

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是一个基本的 STM32F4 输入捕获代码,使用库函数版: ``` #include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_tim.h" int main(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; // 使能 GPIO 和 TIM 时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 配置 PA 为输入模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); // 将 PA 映射到 TIM2 的通道 1 GPIO_PinAFConfig(GPIOA, GPIO_PinSource, GPIO_AF_TIM2); // 配置 TIM2 的基本定时器 TIM_TimeBaseStructure.TIM_Period = xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = ; TIM_TimeBaseStructure.TIM_ClockDivision = ; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 配置 TIM2 的输入捕获通道 1 TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = ; TIM_ICInit(TIM2, &TIM_ICInitStructure); // 启动 TIM2 TIM_Cmd(TIM2, ENABLE); while (1) { // 在这里添加你的代码 } } ``` 这个代码可以让 STM32F4 的 TIM2 模块捕获 PA 引脚上的输入信号,并在捕获到信号时触发一个中断。你可以在中断处理函数中读取捕获到的计数器值,从而得到输入信号的频率或占空比等信息。 ### 回答2: STM32F4的输入捕获代码使用库函数版本时,可以使用HAL库函数来实现。下面是一个简单的示例: 首先,你需要在CubeMX中配置你的定时器和GPIO引脚来实现输入捕获功能。配置完成后,CubeMX将生成相应的HAL库函数代码。 以下是一个示例代码,假设你配置的定时器为TIM2,GPIO引脚为GPIOA_PIN1: ```c #include "stm32f4xx_hal.h" TIM_HandleTypeDef htim2; void TIM2_IRQHandler(void) { HAL_TIM_IRQHandler(&htim2); //处理定时器中断 } void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM2) //判断是TIM2触发的中断 { if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) //判断是通道1触发的中断 { uint32_t capturedValue = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); //获取捕获的值 // 进行你的处理 // ... } } } int main(void) { HAL_Init(); // 配置定时器和GPIO引脚 // ... HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); //启动输入捕获并使能中断 while (1) { // 主循环任务 // ... } } ``` 在这个示例中,我们首先定义了TIM_HandleTypeDef结构体实例htim2,用于操作定时器TIM2。然后,在定时器中断处理函数`TIM2_IRQHandler`中调用`HAL_TIM_IRQHandler`来处理定时器中断。在输入捕获回调函数`HAL_TIM_IC_CaptureCallback`中,我们检查定时器和通道号,获取捕获的值,并进行后续处理。 注意,在`main`函数中,我们使用`HAL_TIM_IC_Start_IT`函数来启动输入捕获并使能中断。 这只是一个简单的示例,实际应用中可能需要根据需要进行一些配置和优化。希望以上代码能对你有所帮助。 ### 回答3: STM32F4系列微控制器是一种嵌入式系统的芯片,在控制系统中具有广泛的应用。输入捕获是一种用于测量信号的时间参数的技术。 输入捕获库函数版本的代码如下: ```c #include "stm32f4xx.h" void TIM4_IRQHandler(void) { if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET) { // 在此处编写捕获到信号后的处理代码 TIM_ClearITPendingBit(TIM4, TIM_IT_CC1); } } void TIM4_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // 捕获上升沿 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 捕获前不分频 TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM4, &TIM_ICInitStructure); TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE); TIM_Cmd(TIM4, ENABLE); } int main(void) { TIM4_Configuration(); while (1) { // 在此处编写主循环处理代码 } } ``` 以上代码将初始化`TIM4`定时器输入捕获功能。在`TIM4_IRQHandler`中可以编写捕获到信号后的处理代码。在主循环中可以编写其他需要处理的代码。 以上就是关于STM32F4输入捕获代码库函数版的简单介绍。希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值