打印
[技术问答]

HC32F460 Timer6 捕获脉宽问题

[复制链接]
3219|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
茂xiang|  楼主 | 2021-9-2 13:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 茂xiang 于 2021-9-2 13:37 编辑

按照规格书说明和大家建议,现在无法进入捕获中断了,华大也没有脉冲测量的完整示例,ε=(´ο`*)))唉

#include "hc32_ddl.h"
#include "hal_CLK.h"
#include "hc32f46x_timer6.h"
#include "sysGeneralFunc.h"

/******************************************************************************/
/** \file main.c
**
** \brief This sample demonstrates how to use Timer6.
**
**   - 2018-11-30  1.0  husj  first version for Device Driver Library of Timer6.
**
******************************************************************************/

#include "hc32_ddl.h"

/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/

/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* KEY0 (SW2)*/
#define  SW2_PORT           (PortD)
#define  SW2_PIN            (Pin03)
/* KEY1 (SW4)*/
#define  SW4_PORT           (PortD)
#define  SW4_PIN            (Pin04)
/* KEY2 (SW3)*/
#define  SW3_PORT           (PortD)
#define  SW3_PIN            (Pin05)
/* KEY3 (SW5)*/
#define  SW5_PORT           (PortD)
#define  SW5_PIN            (Pin06)

/* LED0 Port/Pin definition */
#define  LED0_PORT          (PortE)
#define  LED0_PIN           (Pin06)

/* LED1 Port/Pin definition */
#define  LED1_PORT          (PortD)
#define  LED1_PIN           (Pin07)

/* LED2 Port/Pin definition */
#define  LED2_PORT          (PortB)
#define  LED2_PIN           (Pin05)

/* LED3 Port/Pin definition */
#define  LED3_PORT          (PortB)
#define  LED3_PIN           (Pin09)

/* LED0~1 toggle definition */
#define  LED0_TOGGLE()      (PORT_Toggle(LED0_PORT, LED0_PIN))
#define  LED1_TOGGLE()      (PORT_Toggle(LED1_PORT, LED1_PIN))
#define  LED2_TOGGLE()      (PORT_Toggle(LED2_PORT, LED2_PIN))
#define  LED3_TOGGLE()      (PORT_Toggle(LED3_PORT, LED3_PIN))

/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
uint16_t u16CaptureA;
uint16_t u16CaptureC;
float ftCapDuty;

//问题,溢出怎么办?-->溢出直接进入中断了
//捕获中断但是下降沿怎么获取?
uint8_t capFlag=0;
uint16_t overFlowCnt=0;
void Timer62_CapInputCallBack(void)
{
        if(!capFlag){
                capFlag=1;
                u16CaptureA = Timer6_GetGeneralCmpValue(M4_TMR62, Timer6GenCompareB);
                __NOP();
        }else{
                capFlag=0;
                u16CaptureC = Timer6_GetGeneralCmpValue(M4_TMR62, Timer6GenCompareB);
                __NOP();
                //计算 u16CaptureC - u16CaptureA
        }
}

void Timer62_OverflowCallBack(void)
{
        overFlowCnt++;
        if(overFlowCnt>=10){
                overFlowCnt=0;
        }
}

/**
******************************************************************************
** \brief  Initialize the system clock for the sample
**
** \param  None
**
** \return None
******************************************************************************/
static void SysClkIni(void)
{
    en_clk_sys_source_t       enSysClkSrc;
    stc_clk_sysclk_cfg_t      stcSysClkCfg;
    stc_clk_mpll_cfg_t        stcMpllCfg;

    MEM_ZERO_STRUCT(enSysClkSrc);
    MEM_ZERO_STRUCT(stcSysClkCfg);
    MEM_ZERO_STRUCT(stcMpllCfg);

    /* Set bus clk div. */
    stcSysClkCfg.enHclkDiv = ClkSysclkDiv1;   // 168MHz
    stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;  // 84MHz

    stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;  // 168MHz
    stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;  // 84MHz
    stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;  // 42MHz
    stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;  // 42MHz
    stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;  // 84MHz
    CLK_SysClkConfig(&stcSysClkCfg);

    CLK_HrcCmd(Enable);       //Enable HRC

    /* MPLL config. */
    stcMpllCfg.pllmDiv = 2ul;   //HRC 16M / 2
    stcMpllCfg.plln    = 42ul;  //8M*42 = 336M
    stcMpllCfg.PllpDiv = 2ul;   //MLLP = 168M
    stcMpllCfg.PllqDiv = 2ul;   //MLLQ = 168M
    stcMpllCfg.PllrDiv = 2ul;   //MLLR = 168M
    CLK_SetPllSource(ClkPllSrcHRC);
    CLK_MpllConfig(&stcMpllCfg);

    /* flash read wait cycle setting */
    EFM_Unlock();
    EFM_SetLatency(EFM_LATENCY_4);
    EFM_Lock();

    /* Enable MPLL. */
    CLK_MpllCmd(Enable);

    /* Wait MPLL ready. */
    while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
    {
        ;
    }

    /* Switch system clock source to MPLL. */
    CLK_SetSysClkSource(CLKSysSrcMPLL);
}


#define IO_TEST_PORT        (PortB)
#define IO_TEST_PIN                (Pin10)
#define IO_TEST_OUT_H        PORT_SetBits(IO_TEST_PORT, IO_TEST_PIN)
#define IO_TEST_OUT_L        PORT_ResetBits(IO_TEST_PORT, IO_TEST_PIN)


/*******************************************************************************
*名    称:IIC_IO_Init(void)
*功    能:软件IIC,IO口输出初始化
*说    明:
*修    改:
*******************************************************************************/
void IO_OUT_Init(){
        stc_port_init_t stcPortInit;
        MEM_ZERO_STRUCT(stcPortInit);                                                //必须初始化结构体,否则IO口设置异常 21-06-08(IO翻转对比测试)
        stcPortInit.enPinMode = Pin_Mode_Out;
    stcPortInit.enExInt = Disable;
    stcPortInit.enPullUp = Disable;

        IO_TEST_OUT_H;                                                                                //IO输出高低必须写在前面,初始化默认是低电平,否则会有一个脉冲
        PORT_Init(IO_TEST_PORT, IO_TEST_PIN, &stcPortInit);
}


/**
*******************************************************************************
** \brief  Main function of project
**
** \param  None
**
** \retval int32_t return value, if needed
**
******************************************************************************/
int32_t main(void)
{
    uint16_t                         u16Period;
    uint16_t                         u16Compare;
    stc_timer6_basecnt_cfg_t         stcTIM6BaseCntCfg;
    stc_timer6_port_output_cfg_t     stcTIM6PWMxCfg;
    stc_timer6_port_input_cfg_t      stcTIM6CapxCfg;
    stc_timer6_gcmp_buf_cfg_t        stcGCMPBufCfg;
    stc_port_init_t                  stcPortInit;
    stc_irq_regi_conf_t              stcIrqRegiConf;
    stc_timer6_sw_sync_t             stcSwSyncStart;

    MEM_ZERO_STRUCT(stcTIM6BaseCntCfg);
    MEM_ZERO_STRUCT(stcTIM6PWMxCfg);
    MEM_ZERO_STRUCT(stcTIM6CapxCfg);
    MEM_ZERO_STRUCT(stcGCMPBufCfg);
    MEM_ZERO_STRUCT(stcPortInit);
    MEM_ZERO_STRUCT(stcIrqRegiConf);
    MEM_ZERO_STRUCT(stcSwSyncStart);

    SysClkIni();                                                                                        //系统时钟,PCLK0 168MHz
    PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM62, Enable);        //TIM62时钟使能

        //设置1:PB2设置捕获输入口
    PORT_SetFunc(PortB, Pin02, Func_Tim6, Disable);                  //Timer62 TrigB

    /******************Config Timer62 count mode*************************/
    stcTIM6BaseCntCfg.enCntMode   = Timer6CntSawtoothMode;        //Sawtooth wave mode
    stcTIM6BaseCntCfg.enCntDir    = Timer6CntDirUp;                        //Counter counting up
    stcTIM6BaseCntCfg.enCntClkDiv = Timer6PclkDiv1024;                //Count clock: pclk0/1024
    Timer6_Init(M4_TMR62, &stcTIM6BaseCntCfg);                                //timer6 PWM frequency, count mode and clk config
    u16Period = 0xFFFFu;                                                                        //168MHz/1024/0xffff=2.5Hz   164K频率,计满400mS
    Timer6_SetPeriod(M4_TMR62, Timer6PeriodA, u16Period);        //Period set
      
        /*捕获输入源设置*/
        stcTIM6CapxCfg.enPortSel  = Timer6TrigB;                           //Capture Input Port: TIME6_TRIGB
        stcTIM6CapxCfg.enPortMode = Timer6ModeCaptureInput;                //Capture input function
        stcTIM6CapxCfg.bFltEn     = false;                                 //Input filter disable
        stcTIM6CapxCfg.enFltClk   = Timer6FltClkPclk0Div16;                //Filter clock,不影响,不使能filter
        Timer6_PortInputConfig(M4_TMR62, &stcTIM6CapxCfg);                 //Input config TMR6x->FCONR_f.NOFIENTB
      
        /*脉宽测量,下降沿捕获,上升沿启动,上升沿清0,下降沿停止*/
        M4_TMR62->PCONR_f.CAPMDB = 1;                                                                                //CAPMDB设置1为捕获功能
        Timer6_ConfigHwCaptureB(M4_TMR62, Timer6HwTrigTimTriBFall);               //HW Capture: timer6TrigB port fall trig TMR6x->HCPBR
        Timer6_ConfigHwStart(M4_TMR62, Timer6HwTrigTimTriBRise);                        //HW Start: 根据文档说明增加
        Timer6_ConfigHwClear(M4_TMR62, Timer6HwTrigTimTriBRise);                  //HW Clear: 配置硬件清零事件选择寄存器(HCLRR),使得每次发生捕获事件后,计数器从0开始重新计数。
        Timer6_ConfigHwStop(M4_TMR62, Timer6HwTrigTimTriBFall);                                //HW Stop: imer6TrigB port fall trig
        Timer6_EnableHwClear(M4_TMR62);
        Timer6_ConfigHwCntUp(M4_TMR62, Timer6HwCntTRIGBRise);                                //硬件同步计数(HCUPR)
//        Timer6_EnableHwStart(M4_TMR6_TypeDef *TMR6x)
      
    /*config interrupt*/
    /* Enable timer62 GCMAR interrupt */
    Timer6_ConfigIrq(M4_TMR62, Timer6INTENB, true);                                                //捕获中断

    stcIrqRegiConf.enIRQn = Int003_IRQn;                                            //Register INT_TMR61_GUDF Int to Vect.No.002
    stcIrqRegiConf.enIntSrc = INT_TMR62_GCMB;                                       //Select Event interrupt function
    stcIrqRegiConf.pfnCallback = &Timer62_CapInputCallBack;                          //Callback function
    enIrqRegistration(&stcIrqRegiConf);                                             //Registration IRQ

        stcIrqRegiConf.enIRQn = Int003_IRQn;                                            //Register INT_TMR61_GUDF Int to Vect.No.002
    stcIrqRegiConf.enIntSrc = INT_TMR62_GOVF;                                       //溢出中断函数
    stcIrqRegiConf.pfnCallback = &Timer62_OverflowCallBack;                          //Callback function
    enIrqRegistration(&stcIrqRegiConf);                                             //Registration IRQ
      
    NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);                                    //Clear Pending
    NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_04);                //Set priority
    NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);                                           //Enable NVIC

    /*start timer6*/
//    stcSwSyncStart.bTimer62 = true;
//    Timer6_SwSyncStart(&stcSwSyncStart);
        Timer6_StartCount(M4_TMR62);
      
        IO_OUT_Init();
        while(1){
                IO_TEST_OUT_H;                //高电平20uS捕获测试
                Delay_us(20);
                IO_TEST_OUT_L;                //低电平1S
                Delay_ms(1000);
                __NOP();
        }
}










使用特权

评论回复
沙发
茂xiang|  楼主 | 2021-9-2 13:33 | 只看该作者
本帖最后由 茂xiang 于 2021-9-2 13:36 编辑

按照规格书说明和大家建议,现在无法进入捕获中断了

使用特权

评论回复
板凳
sadicy| | 2021-9-3 10:50 | 只看该作者
感觉,有点复杂了

使用特权

评论回复
地板
茂xiang|  楼主 | 2021-9-3 11:51 | 只看该作者
问题解决了,TrigB必须开启Timer61时钟,谁能想到?!!!
同时要使能Start、Clear、Stop!!!

使用特权

评论回复
5
martinhu| | 2021-9-3 13:24 | 只看该作者
茂xiang 发表于 2021-9-3 11:51
问题解决了,TrigB必须开启Timer61时钟,谁能想到?!!!
同时要使能Start、Clear、Stop!!! ...

start和stop不需要,只要clear就行。启动的话初始化之后,软件写一次启动就行,

使用特权

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

本版积分规则

6

主题

13

帖子

1

粉丝