<p> <strong><u>MCU</u></strong><strong>微课堂</strong></p>
讯享网
讯享网<strong>CKS32F107xx <u>TI</u>M(三)</strong></p>
第四十八期 2024.11.08</p>
讯享网PWM输入捕获</p>
上节课我们介绍了高级<u>定时器</u>互补PWM输出的配置方法,这节课我们将向大家介绍高级定时器的另一个常见应用——PWM输入模式。在本节课中,我们将先围绕输入捕获模式展开,并重点描述PWM输入模式和涉及的<u>寄存器</u>,最后通过一个实验例程去介绍PWM输入模式的配置方法。</p>
讯享网<strong>输入捕获模式简介</strong></p>
<strong>1、普通输入模式</strong></p>
讯享网除基本定时器外,其余定时器的部分通道都可以对输入<u>信号</u>的上升沿、下降沿或者双边沿进行捕获,并且计数器CNT的值会被锁存到捕获/比较寄存器CCR中。当我们需要同时捕获PWM波的频率和占空比时,仅需要测出一个周期中高电平和低电平持续的时间即可。我们可尝试如下步骤:首先将定时器的某一通道初始设置为上升沿捕获,当发生第一次捕获到上升沿的中断,以此中断时刻作为一个起点,读取CCR中值为Value1,此时将捕获模式设置为下降沿捕获,在发生第二次中断的时候,捕获到了下降沿,读取CCR中值为Value2,那么Value2和Value1之间的差值,就是一个周期中高电平持续的时间,然后我们在中断中又将捕获的方式设置为上升沿捕获,那么在第三次产生中断的时候,读取CCR中值为Value3,那么Value3和Value2之间的差值就是一个周期中低电平的时间。至此,PWM波的频率可由Value3和Value1之间的差值计算出,正占空比则可通过高电平占整个周期的比值获得。如下图1所示:</p>
<img alt="ea-9dab-11ef-93f3-92fbcf53809c.png" src="https://file1.elecfans.com/web1/M00/F4/9B/wKgaoWct0TWAOJ6BAAAYLV7z0b4740.png" /></p>
讯享网图1 普通输入捕获概览图</p>
<strong>2、PWM输入模式</strong></p>
讯享网PWM输入模式是普通输入模式的一种特例,以输入通道TI1为例,PWM信号进入该通道后,信号被分成TI1FP1和TI1FP2两路,最终分别映射到了<u>IC</u>1和IC2捕获通道,其中一个捕获上升沿,另一个捕获下降沿。这样用户可以在中断中去读上升沿和下降沿对应寄存器中的计数,从而得出周期和占空比。并且用户在设计之初,需要先选定哪一路为触发信号以及触发极性,一旦选定某一路为触发信号则对应的即为周期,另一路则对应为占空比,两路捕获极性也是相反的,并且因为是PWM输入捕获的缘故,当其中一路配置完成,另一路由<u>硬件</u>自动配置,无需软件来配置。图2为PWM输入模式时序图。</p>
<img alt="30a7497c-9dab-11ef-93f3-92fbcf53809c.png" src="https://file1.elecfans.com/web1/M00/F4/98/wKgZoWct0TWAWAcWAAB8NItFfGM574.png" /></p>
讯享网图2 PWM输入模式时序图</p>
其中,IC1捕获通道计算两次都是上升沿的时间,即周期T;而IC2通道则计算一次下降沿和之前上升沿之差,这样得到高电平时长,从而可以求得周期T和占空比。需要注意的是,PWM输入模式需要占用两个捕获寄存器,且只有TI1FP1和TI2FP2连接到了从模式<u>控制器</u>(使用PWM输入捕获时,需要配置从模式控制器为复位模式),所以只能使用定时器的通道1或通道2。</p>
讯享网<strong>寄存器和输入捕获结构体概述</strong></p>
<strong>1、捕获/比较寄存器CCMR</strong></p>
讯享网关于CCMR寄存器,上节课我们介绍了输出比较模式,这节课我们来介绍下输入捕获模式,该寄存器的各位描述图如下:</p>
<img alt="30eb9f96-9dab-11ef-93f3-92fbcf53809c.png" src="https://file1.elecfans.com/web1/M00/F4/9B/wKgaoWct0TWARLbCAABPsRGzzpk981.png" /></p>
讯享网图3 CCMR1寄存器各位描述图</p>
该16位寄存器CCMR的下层对应输入捕获(上层对应输出比较),其中CCMR1用于捕获通道1和2的控制,CCMR2用于捕获通道3和4的控制。下图为低8位详细描述图,用于捕获通道1。</p>
讯享网<img alt="c6-9dab-11ef-93f3-92fbcf53809c.png" src="https://file1.elecfans.com/web1/M00/F4/98/wKgZoWct0TaAUbP8AAKj0cwXrvk416.png" /></p>
图4 CCMR1寄存器低7位描述图</p>
讯享网<u>参数</u>CC1S,用于输入捕获/输出比较通道的引脚选择,若我们设置CCIS[1:0] = 01,表明CC1通道(对应定时器的通道1)被配置为输入,IC1映射在TI1上。</p>
参数IC1PSC,配置为00时,表明每1个边沿触发1次捕获。</p>
讯享网参数IC1F,用来设置TI1输入采样频率和数字<u>滤波器</u>长度,本课中我们不做滤波处理。</p>
<strong>2、捕获/比较使能寄存器CCER</strong></p>
讯享网在本课中我们仅用到低2位CC1E和CC1P,由于我们需要在中断中处理捕获的数据,所以配置CC1E为1,CC1P配置为不反相,故设置为0。CCER低2位图如下描述。</p>
<img alt="311d6026-9dab-11ef-93f3-92fbcf53809c.png" src="https://file1.elecfans.com/web1/M00/F4/9B/wKgaoWct0TaARlTyAAIWhVGrIIA150.png" /></p>
讯享网图5 CCMR1寄存器低7位描述图</p>
<strong>3、输入捕获结构体TIM_ICInitTypeDef</strong></p>
讯享网可配合TIM_PWMIConfig函数完成定时器输入通道各参数的初始化配置。输入捕获结构体的各参数定义如下:</p>
typedef struct</p>
讯享网{</p>
uint16_t TIM_Channel;<br /> uint16_t TIM_ICPolarity;<br /> uint16_t TIM_ICSelection;<br /> uint16_t TIM_ICPrescaler;<br /> uint16_t TIM_ICFil<u>te</u>r;</p>
讯享网} TIM_ICInitTypeDef;</p>
1)参数TIM_Channel:设定CCMRx寄存器CCxS位,用于捕获通道ICx选择。</p>
讯享网2)参数TIM_ICPolarity:设定CCER寄存器CCxP位和CCxNP位,用于输入捕获边沿触发选择。</p>
3)参数TIM_ICSelection:设定CCRMx寄存器的CCxS[1:0]位,用于输入通道选择,输入通道共有三个来源,分别为:TIM_ICSelection_DirectTI、TIM_ICSelection_IndirectTI或TIM_ICSelection_TRC。若为普通输入模式,4个通道均能使用;若为PWM输入模式,只能使用通道1和2。输入通道和捕获通道的映射关系详见下图。</p>
讯享网<img alt="312ec316-9dab-11ef-93f3-92fbcf53809c.png" src="https://file1.elecfans.com/web1/M00/F4/98/wKgZoWct0TaAX-KDAACUlAa9g650.png" /></p>
图6 输入通道和捕获通道的映射关系</p>
讯享网4)参数TIM_ ICPrescaler:设定CCMRx寄存器的ICxPSC[1:0]位的值,用来设置输入捕获分频系数,有1、2、4、8分频可选。这里我们需要捕获输入信号的每个有效边沿,故设置为1分频即可。</p>
5)参数TIM_ ICFilter:设定CCMRx寄存器ICxF[3:0]位,用于设置输入捕获滤波器。</p>
讯享网本课中我们配置的示例代码如下:</p>
TIM_ICInitTypeDef TIM_ICInitStructure;</p>
讯享网TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;</p>
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;</p>
讯享网TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;</p>
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;</p>
讯享网TIM_ICInitStructure.TIM_ICFilter = 0x0;</p>
TIM_PWMIConfig(TIM1, &TIM_ICInitStructure);</p>
讯享网上述代码中,我们设置定时器的通道1为上升沿捕获,且输入通道1(TI1)与捕获通道1(IC1)为直接映射,不分频,不使用滤波器。</p>
<strong>PWM模式输入配置实验</strong></p>
讯享网本实验配置高级定时器的通道1,即PA8,用于捕获信号发生器输出PWM信号,最后通过串口调试助手打印捕获到的PWM的频率和占空比。主要的<u>编程</u>要点如下。</p>
<strong>1、高级定时器引脚初始化</strong></p>
讯享网由于TIM1_CH1是连接在PA8上,这里需要开启GPIOA<u>时钟</u>,并配置引脚为浮空输入,我们配置的代码如下:</p>
void TIM1_GPIO_Configuration(void)</p>
讯享网{</p>
GPIO_InitTypeDefGPIO_InitStructure;</p>
讯享网RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);</p>
GPIO_InitStructure.GPIO_<u>Pi</u>n = GPIO_Pin_8;</p>
讯享网GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;</p>
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;</p>
讯享网GPIO_Init(GPIOA, &GPIO_InitStructure);</p>
}</p>
讯享网<strong>2、高级定时器中断优先级设置</strong></p>
之前的课程中让我们对中断优先级已经有了深入了解,这里因为我们只有一个捕获/比较中断源,所以优先级随便设置,我们配置的代码如下:</p>
讯享网void TIM1_NVIC_Configuration(void)</p>
{</p>
讯享网NVIC_InitTypeDef NVIC_InitStructure;</p>
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); </p>
讯享网NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;</p>
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; </p>
讯享网NVIC_InitStructure.NVIC_IRQChannel<u>Sub</u>Priority = 3;</p>
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;</p>
讯享网NVIC_Init(&NVIC_InitStructure);</p>
}</p>
讯享网<strong>3、高级定时器PWM输入模式配置</strong></p>
我们主要对时基和输入捕获结构体初始化,配置代码如下:</p>
讯享网void TIM1_Input_Capture_Mode_Configuration(void)</p>
{</p>
讯享网TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;</p>
TIM_ICInitTypeDef TIM_ICInitStructure;</p>
讯享网RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);</p>
/* Time Base Configuration */</p>
讯享网TIM_TimeBaseStructure.TIM_Period = 65535-1;</p>
TIM_TimeBaseStructure.TIM_Prescaler = 72-1;</p>
讯享网TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; </p>
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; </p>
讯享网TIM_TimeBaseStructure.TIM_RepetitionCounter=0;</p>

TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);</p>
讯享网/* PWM Input Capture Configuration */</p>
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;</p>
讯享网TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;</p>
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;</p>
讯享网TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;</p>
TIM_ICInitStructure.TIM_ICFilter = 0x0;</p>
讯享网TIM_PWMIConfig(TIM1, &TIM_ICInitStructure);</p>
TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1); </p>
讯享网TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);</p>
TIM_SelectMaste<u>rS</u>laveMode(TIM1,TIM_MasterSlaveMode_Enable);</p>
讯享网TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);</p>
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);</p>
讯享网TIM_Cmd(TIM1, ENABLE);</p>
}</p>
讯享网从上述示例代码来看,我们首先将TIM1_CH1的捕获计数器设置为1us计数一次,重装载值为65535,所以可以捕获的时间精度为1us,最低可捕获的频率为15.3Hz。其次,我们选择TIM1的通道1(TI1)作为PWM信号输入,并选择TI1FP1为触发信号(输入的信号被分为TI1FP1和TI1FP2),因此IC1捕获PWM信号周期,IC2捕获PWM信号占空比。而且由于PWM输入模式下,当捕获开始时,需要将CNT复位,所以我们需要配置定时器以从模式工作在复位模式下,最后使能捕获中断和高级定时器。</p>
<strong>4、高级定时器中断服务函数配置</strong></p>
讯享网在函数TIM1_CC_IRQHandler中,如果是第一个上升沿中断,计数器CNT会被复位,锁存到CCR1寄存器的值是0,CCR2寄存器的值也是0,无法计算频率和占空比。当第二次上升沿到来的时候,CCR1和CCR2捕获到的才是有效的值。其中CCR1对应的是周期,CCR2对应的是占空比。我们配置的代码如下:</p>
void TIM1_CC_IRQHandler(void)</p>
讯享网{</p>
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);</p>
讯享网IC1Value = TIM_GetCapture1(TIM1);</p>
IC2Value = TIM_GetCapture2(TIM1);</p>
讯享网if (IC1Value != 0)</p>
{</p>
讯享网DutyCycle = (float)((IC2Value+1) * 100) / (IC1Value+1);</p>
Frequency = (/((72-1)+1))/(float)(IC1Value+1);</p>
讯享网 printf("占空比:%0.2f%% 频率:%0.2fHz ", DutyCycle, Frequency);</p>
}</p>
讯享网else</p>
{</p>
讯享网DutyCycle = 0;</p>
Frequency = 0;</p>
讯享网}</p>
}</p>
讯享网<strong>5、主函数配置</strong></p>
main函数就是对上述函数的调用,配置示例如下:</p>
讯享网int main(void)</p>
{ </p>
讯享网CKS_USART_Init();</p>
printf("CKS Timer Input Capture Demo start running... ");</p>
讯享网TIM1_GPIO_Configuration();</p>
TIM1_NVIC_Configuration();</p>
讯享网TIM1_Input_Capture_Mode_Configuration();</p>
while(1){}</p>
讯享网}</p>
至此,我们配置已完成。</p>
讯享网<strong>6、<u>下载</u>验证</strong></p>
我们将编译好的程序下载至CKS32F107xx开发板,信号发生器和PWM输入引脚PA8通过杜邦线连接,<u>USB</u>转TTL模块分别与<u>UART</u>1—PA9和<u>电脑</u>相连,然后打开串口调试助手,查看打印<u>信息</u>。</p>

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/142378.html