完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、输入捕获模式
在输入捕获模式下,当检测到ICx信号上相应的边沿后,计数器的当前值被锁存到捕获/比较寄存器(TIMx_CCRx)中。当捕获事件发生时,相应的CCxIF标志(TIMx_SR寄存器)被置’1’,如果使能了中断或者DMA操作,则将产生中断或者DMA操作。如果捕获事件发生时CCxIF标志已经为高,那么重复捕获标志CCxOF(TIMx_SR寄存器)被置’1’。写CCxIF=0可清除CCxIF,或读取存储在TIMx_CCRx寄存器中的捕获数据也可清除CCxIF。写CCxOF=0可清除CCxOF。 二、如何捕获PWM方波的频率? 将捕获的模式设置为下降沿/上升沿捕获,当第一次捕获到上升沿/下降沿,则会触发中断,在中断中,把当前的计数值记录下来Value1;第二次捕获到上升沿/下降沿,再一次触发中断,在中断中我们把当前的计数值记录下来Value1。所以第二次捕获和第一次捕获之间的时间就是PWM方波的周期了。假设定时器的时钟被设置为72MHz,那么得到的PWM方波的频率应该为72MHz/(Value2 - Value1)。 三、如何捕获PWM方波的频率和占空比? 如果我们要同时捕获方波的频率和占空比的话,那么我们需要知道一个周期中高电平的时间和一个周期中低电平的时间。 首先把捕获的模式设置为上升沿捕获(当然设置为下降沿也是可以的),发生第一次捕获到上升沿的中断,以此中断时刻作为一个起点,得到的计数值为Value1,此时将捕获模式设置为下降沿捕获,在发生第二次中断的时候,捕获到了下降沿,得到的计数值为Value2,那么Value2和Value1之间的差值,就是一个周期中,高电平的时间,然后我们在中断中又将捕获的方式设置为上升沿捕获,那么在第三次产生中断的时候,得到的计数值为Value3,那么Value3和Value2之间的差值就是一个周期中低电平的时间。所以到此为止,我们知道了一个周期中高电平和低电平的时间,那么这个PWM方波的频率和占空比就得到了。 四、实例:捕获PWM方波的频率和占空比 代码如下,根据官方固件库提供的一个Example修改而来STM32F10x_StdPeriph_Lib_V3.5.0ProjectSTM32F10x_StdPeriph_ExamplesTIMInputCapture。使用的是定时器3的通道2。 配置步骤:
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; // 选择通道2
uint32_t IC3ReadValue1 = 0, IC3ReadValue2 = 0; uint32_t CaptureNumber = 0; uint32_t Capture = 0; uint32_t TIM3Freq = 0; uint32_t TIM3Duty = 0; uint32_t TIM3_Update_Cnt = 0; /** * @brief Configures the different system clocks. * @param None * @retval None */ void InputCapture_RCC_Configuration(void) { /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* GPIOA clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); } /** * @brief Configure the GPIOA Pins. * @param None * @retval None */ void InputCapture_GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /* TIM3 channel 2 pin (PA.07) configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); } /** * @brief Configure the nested vectored interrupt controller. * @param None * @retval None */ void InputCapture_NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Enable the TIM3 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void InputCapture_Init(void) { TIM_ICInitTypeDef TIM_ICInitStructure; /* System Clocks Configuration */ InputCapture_RCC_Configuration(); /* NVIC configuration */ InputCapture_NVIC_Configuration(); /* Configure the GPIO ports */ InputCapture_GPIO_Configuration(); /* TIM3 configuration: Input Capture mode --------------------- The external signal is connected to TIM3 CH2 pin (PA.07) The Rising edge is used as active edge, The TIM3 CCR2 is used to compute the frequency value ------------------------------------------------------------ */ TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; 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(TIM3, &TIM_ICInitStructure); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); /* Enable the CC2 Interrupt Request */ TIM_ITConfig(TIM3, TIM_IT_CC2 | TIM_IT_Update, ENABLE); } /** * @brief This function handles TIM3 global interrupt request. * @param None * @retval None */ void TIM3_IRQHandler(void) { if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) { /* Clear TIM3 Update compare interrupt pending bit */ TIM_ClearITPendingBit(TIM3, TIM_IT_Update); TIM3_Update_Cnt++; } if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET) { /* Clear TIM3 Capture compare interrupt pending bit */ TIM_ClearITPendingBit(TIM3, TIM_IT_CC2); if(CaptureNumber == 0) { /* Get the Input Capture value */ TIM_SetCounter(TIM3, 0); TIM3_Update_Cnt = 0; // 需要特别注意,一定要在第一次捕获到的时候清零 CaptureNumber = 1; TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Falling); // 配置为下降沿 } else if(CaptureNumber == 1) { /* Get the Input Capture value */ IC3ReadValue1 = TIM_GetCounter(TIM3) + 65536*TIM3_Update_Cnt; CaptureNumber = 2; TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Rising); // 配置为上降沿 } else if(CaptureNumber == 2) { /* Get the Input Capture value */ IC3ReadValue2 = TIM_GetCounter(TIM3) + 65536*TIM3_Update_Cnt; /* Frequency computation */ TIM3Freq = (uint32_t) (SystemCoreClock * 1.0 / IC3ReadValue2 + 0.5); TIM3Duty = (uint32_t) (IC3ReadValue1 * 100.0 / IC3ReadValue2 + 0.5); CaptureNumber = 0; } } } 2021/02/02更新 在之前提到了TIM_GetCounter与TIM_GetCapture1之间的区别,知道了TIM_GetCapture1要准确一些,但是在之前的程序由于偷懒还是使用的是TIM_GetCounter嘿嘿,这次更新一下使用TIM_GetCapture1来检测的中断服务函数,不过下面的代码使用的时定时器2的通道2, 没有添加占空比的检测,可以自己根据需要,按照上面的方法进行检测。 需要特别注意,Tim2_Update_Cnt 一定要在第一次捕获到的时候清零,在写蓝桥杯嵌入式的代码的时候,因为把它放在了第二次捕获的时候清零,导致得到的周期是之前的一倍,找了很久才发现错误,害…都是泪啊… /** * @brief This function handles TIM2 global interrupt request. * @param None * @retval None */ void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) { /* Clear TIM2 Capture compare interrupt pending bit */ TIM_ClearITPendingBit(TIM2, TIM_IT_Update); Tim2_Update_Cnt++; } if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET) { total_meter_now++; /* Clear TIM2 Capture compare interrupt pending bit */ TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); if(Time2_CaptureNumber == 0) { /* Get the Input Capture value */ Tim2_Update_Cnt = 0; Time2_IC2ReadValue1 = TIM_GetCapture2(TIM2); Time2_CaptureNumber = 1; } else if(Time2_CaptureNumber == 1) { /* Get the Input Capture value */ Time2_IC2ReadValue2 = TIM_GetCapture2(TIM2); Time2_Capture = ( Tim2_Update_Cnt * (0xFFFF) + Time2_IC2ReadValue2 - Time2_IC2ReadValue1); /* Frequency computation */ TIM2Freq = (uint32_t) ((SystemCoreClock * 1.0 / Time2_Capture) + 0.5); Time2_CaptureNumber = 0; } } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1936浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
729浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
569浏览 3评论
594浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
552浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 21:10 , Processed in 0.868869 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号