茂xiang 发表于 2021-9-2 13:32

HC32F460 Timer6 捕获脉宽问题

本帖最后由 茂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-301.0husjfirst version for Device Driver Library of Timer6.
**
******************************************************************************/

#include "hc32_ddl.h"

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

/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* KEY0 (SW2)*/
#defineSW2_PORT         (PortD)
#defineSW2_PIN            (Pin03)
/* KEY1 (SW4)*/
#defineSW4_PORT         (PortD)
#defineSW4_PIN            (Pin04)
/* KEY2 (SW3)*/
#defineSW3_PORT         (PortD)
#defineSW3_PIN            (Pin05)
/* KEY3 (SW5)*/
#defineSW5_PORT         (PortD)
#defineSW5_PIN            (Pin06)

/* LED0 Port/Pin definition */
#defineLED0_PORT          (PortE)
#defineLED0_PIN         (Pin06)

/* LED1 Port/Pin definition */
#defineLED1_PORT          (PortD)
#defineLED1_PIN         (Pin07)

/* LED2 Port/Pin definition */
#defineLED2_PORT          (PortB)
#defineLED2_PIN         (Pin05)

/* LED3 Port/Pin definition */
#defineLED3_PORT          (PortB)
#defineLED3_PIN         (Pin09)

/* LED0~1 toggle definition */
#defineLED0_TOGGLE()      (PORT_Toggle(LED0_PORT, LED0_PIN))
#defineLED1_TOGGLE()      (PORT_Toggle(LED1_PORT, LED1_PIN))
#defineLED2_TOGGLE()      (PORT_Toggle(LED2_PORT, LED2_PIN))
#defineLED3_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;
      }
}

/**
******************************************************************************
** \briefInitialize the system clock for the sample
**
** \paramNone
**
** \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);
}


/**
*******************************************************************************
** \briefMain function of project
**
** \paramNone
**
** \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!!!

martinhu 发表于 2021-9-3 13:24

茂xiang 发表于 2021-9-3 11:51
问题解决了,TrigB必须开启Timer61时钟,谁能想到?!!!
同时要使能Start、Clear、Stop!!! ...

start和stop不需要,只要clear就行。启动的话初始化之后,软件写一次启动就行,
页: [1]
查看完整版本: HC32F460 Timer6 捕获脉宽问题