打印
[综合信息]

PWM输入捕获,使用TIM6

[复制链接]
4180|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aoyi|  楼主 | 2021-9-1 08:45 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、启动时钟

PWC_Fcg2PeriphClockCmd(PWC_FCG2_TMR6_x, Enable);


TMR6对应FCG2,根据PWM输入引脚来确定是TMR6_x(本例为TMR6_2)。运行以后PWC的FCG2寄存器相应位被清0。


同时TM62的这些寄存器被全部置1,GCONR的DIR位被置一。

以上步骤类似STM32的开启RCC时钟。


使用特权

评论回复
沙发
aoyi|  楼主 | 2021-9-1 08:47 | 只看该作者
二、功能初始化
设置TIM62的GCONR寄存器。





    /* Timer6 general count function configuration */
    stcTIM6BaseCntCfg.u32CntMode = TMR6_MODE_SAWTOOTH;
    stcTIM6BaseCntCfg.u32CntDir = TMR6_CNT_INCREASE;
    stcTIM6BaseCntCfg.u32CntClkDiv = TMR6_CLK_PCLK0_DIV1024;
    stcTIM6BaseCntCfg.u32CntStpAftOvf = TMR6_CNT_CONTINUOUS;
    (void)TMR6_Init(M4_TMR6_2, &stcTIM6BaseCntCfg);


设为锯齿波(TMR6_MODE_SAWTOOTH),计数增长(TMR6_CNT_INCREASE),1024分频(TMR6_CLK_PCLK0_DIV1024),计满溢出后继续计数(TMR6_CNT_CONTINUOUS)。



使用特权

评论回复
板凳
aoyi|  楼主 | 2021-9-1 08:48 | 只看该作者
三、配置GPIO为PWM输入

本例为PB07
PB07可以作为TIM62_PWM的A通道使用



#define         TMR6_2_PWMA_PORT       (GPIO_PORT_B)
#define         TMR6_2_PWMA_PIN        (GPIO_PIN_07)
GPIO_SetFunc(TMR6_2_PWMA_PORT, TMR6_2_PWMA_PIN, GPIO_FUNC_3_TIM62_PWMA, PIN_SUBFUNC_DISABLE);




使用特权

评论回复
地板
aoyi|  楼主 | 2021-9-1 08:49 | 只看该作者
四、确立TMR62定时周期

    /* Period register set */
    u32Period = 0xFFFFFFFFu;
    TMR6_SetPeriodReg(M4_TMR6_2, TMR6_PERIOD_REG_A, u32Period);


TMR62是32位计数器最大值可以设置到0xFFFFFFFF。对PERAR寄存器设置0xFFFFFFFF。PERBR和PERCR可以作为缓存,这里不用,不管它们。


使用特权

评论回复
5
aoyi|  楼主 | 2021-9-1 08:51 | 只看该作者
五、开启外部PWM信号捕获并配置滤波
设定端口控制寄存器PCNAR(PCNBR)的 CAPMDA(CAPMDB)位为1,捕获输入功能变为有效,同时设置FCNGR的对应A或B开启滤波,并配置其时钟分频。本例使用channel A。

    /* Capture input port configuration */
    stcTIM6PortInCfg.u32PortMode = TMR6_PORT_CAPTURE_INPUT;
    stcTIM6PortInCfg.u32FilterSta = TMR6_PORT_INPUT_FILTER_ON;
    stcTIM6PortInCfg.u32FltClk = TMR6_INPUT_FILTER_PCLK0_DIV16;
    (void)TMR6_PortInputConfig(M4_TMR6_2,TMR6_IO_PWMA, &stcTIM6PortInCfg);



在滤波采样基准时钟采样到端口上 3 次一致的电平时,该电平被当作有效电平传送到模块内部;小于 3 次一致的电平会被当作外部干扰滤掉,不传送到模块内部。其动作。





使用特权

评论回复
6
aoyi|  楼主 | 2021-9-1 08:52 | 只看该作者
六、配置PWM捕获(HCPAR)

这个库函数是专门配置通道A的,操作寄存器HCPAR。

    TMR6_HwCaptureChACondCmd(M4_TMR6_2, TMR6_HW_CTRL_PWMA_RISING, Enable);


请注意,如果需要使用通道B,则需要换函数。

void TMR6_HwCaptureChBCondCmd(M4_TMR6_TypeDef *TMR6x,
                            uint32_t u32CondSrc,
                            en_functional_state_t enNewState)





使用特权

评论回复
7
aoyi|  楼主 | 2021-9-1 08:54 | 只看该作者
七、捕获到跳变沿后,计数器计数硬件清零(HCLRR)

配置硬件清零事件选择寄存器(HCLRR),使得每次发生捕获事件后,计数器从0开始重新计数。

如果想测量PWM周期,则应该与捕获条件一致,本例捕获为上升沿,所以清0条件也应为上升沿。

    TMR6_HwClrCondCmd(M4_TMR6_2, TMR6_HW_CTRL_PWMA_RISING, Enable);




    TMR6_HwClrFuncCmd(M4_TMR6_2, Enable);




使用特权

评论回复
8
aoyi|  楼主 | 2021-9-1 08:55 | 只看该作者
八、配置中断(ICONR,发生捕获时触发)

启动捕获功能时,每当发生捕获事件,当前的计数值就被保存到相应的捕获寄存器(GCMAR、GCMBR)中,本例使用GCMAR。我们开启ICONR寄存器中的最低位。

    /* Enable M4_TMR6_2 GCMAR interrupt */
    TMR6_IntCmd(M4_TMR6_2, TMR6_IRQ_EN_CNT_MATCH_A, Enable);



这样就可以在发生捕获时触发中断。
到这里总结一下,当外部上升沿进来时,TMR62会直接产生:

产生捕获事件
计数器清零0
进而由于产生捕获事件间接产生:

触发中断



使用特权

评论回复
9
aoyi|  楼主 | 2021-9-1 08:56 | 只看该作者
九、配置中断向量及回调函数(NVIC)

STM32F4的中断向量通道和对应功能是固定死的,而HC32F4A0的非常灵活,可以自由配置。不过使用STM32的标准库函数来配NVIC非常方便,所以移植了STM32F4的misc.c文件,来对HC32F4A0进行NVIC配置。移植的时候需要修改以下几处:

1.misc.h



2. misc.c




然后即可使用misc文件里面的函数来配置NVIC了。


/**因为HC32F4A0的中断向量通道与中断源以及相应的中断服务函数可以灵活映射,所以需要手动配置**/

        stcIrqRegiConf.enIRQn = Int003_IRQn;                    /* Register INT_TMR6_2_GCMA Int to Vect.No.003 */

    stcIrqRegiConf.enIntSrc = INT_TMR6_2_GCMA;              /* Select Event interrupt of M4_TMR6_2 */

    stcIrqRegiConf.pfnCallback = &Tmr6_2_CapInputCallBack;  /* Callback function */

    (void)INTC_IrqSignIn(&stcIrqRegiConf);  

   

/**后面就使用移植过来的misc文件中的库函数来配置NVIC了,注意ENABLE要改为Enable,其它跟STM32一样了**/

        NVIC_InitTypeDef NVIC_InitStructure;

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

       

        NVIC_InitStructure.NVIC_IRQChannel = Int003_IRQn;      

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;               

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;                       

    NVIC_InitStructure.NVIC_IRQChannelCmd = Enable;

    NVIC_Init(&NVIC_InitStructure);



Intxxx_IRQn可选择为Int000_IRQn ~ Int031_IRQn,以及Int056_IRQn ~ Int061_IRQn。



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

99

主题

3305

帖子

3

粉丝