【急】关于rt1052 qtimer如何将两个通道组合成32位定时器来输入捕获

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

【急】关于rt1052 qtimer如何将两个通道组合成32位定时器来输入捕获

862 Views
944706426
Contributor III

由于输入捕获的pwm脉冲只有10HZ,使用qtimer一个通道只有16位测不到,所以想组合成32位来测,官方只有定时器级联32位定时的例子,参考了最终还是没有成功,只能测到100hz以上,10hz还是有问题。

我把代码贴在下面,麻烦官方技术人员帮我看一下,万分感谢!

Since the input captured pwm pulse is only 10HZ, only 16 bits of a channel using the qtimer can not be measured, so i want to combine them into 32 bits for measurement. The official only example is that the timer cascades 32 bits for timing. After referring to the final success, i can only measure more than 100hz, but there is still a problem with 10hz.

I will post the code below, and ask the official technicians to look at it for me. Thank you very much!

 

//引脚配置
void BOARD_InitPins(void) {
  CLOCK_EnableClock(kCLOCK_Iomuxc);           
  CLOCK_EnableClock(kCLOCK_Xbar1);            

#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3)
  IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TXD, 0U); 
#else
  IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0U); 
#endif
#if FSL_IOMUXC_DRIVER_VERSION >= MAKE_VERSION(2, 0, 3)
  IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RXD, 0U); 
#else
  IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0U); 
#endif
  IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B0_00_XBAR1_INOUT04, 0U); 
  IOMUXC_GPR->GPR6 = ((IOMUXC_GPR->GPR6 &
    (~(IOMUXC_GPR_GPR6_QTIMER3_TRM1_INPUT_SEL_MASK | IOMUXC_GPR_GPR6_IOMUXC_XBAR_DIR_SEL_4_MASK))) 
      | IOMUXC_GPR_GPR6_QTIMER3_TRM1_INPUT_SEL(0x01U) 
      | IOMUXC_GPR_GPR6_IOMUXC_XBAR_DIR_SEL_4(0x00U) 
    );
  XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputIomuxXbarInout04, kXBARA1_OutputQtimer3Tmr1Input); 
}


volatile bool qtmrIsrFlag = false;
uint16_t cap_h,cap_l;

void TMR3_IRQHandler(void)
{
    QTMR_ClearStatusFlags(TMR3, kQTMR_Channel_1, kQTMR_EdgeFlag);
    qtmrIsrFlag = true;
    __DSB();
}



void qttimer_test(void)
{
    qtmr_config_t qtmrConfig;
    uint32_t timeCapt     = 0;
    uint32_t nhz;
    
    QTMR_GetDefaultConfig(&qtmrConfig);
    
    qtmrConfig.primarySource = kQTMR_ClockDivide_128;
    QTMR_Init(TMR3, kQTMR_Channel_1, &qtmrConfig);
    
    qtmrConfig.primarySource = kQTMR_ClockCounter0Output;
    QTMR_Init(TMR3, kQTMR_Channel_0, &qtmrConfig);

    QTMR_SetupInputCapture(TMR3, kQTMR_Channel_1, kQTMR_Counter1InputPin, false, true,
                           kQTMR_RisingEdge);

    EnableIRQ(TMR3_IRQn);
    QTMR_EnableInterrupts(TMR3, kQTMR_Channel_1, kQTMR_EdgeInterruptEnable);

    QTMR_StartTimer(TMR3, kQTMR_Channel_1, kQTMR_PriSrcRiseEdge);
    QTMR_StartTimer(TMR3, kQTMR_Channel_0, kQTMR_CascadeCount);
    while(1)
    {
        if(qtmrIsrFlag)
        {
            qtmrIsrFlag = false;
            cap_h = TMR3->CHANNEL[kQTMR_Channel_0].CAPT;
            cap_l = TMR3->CHANNEL[kQTMR_Channel_1].CAPT;
            timeCapt = (cap_h <<16) |cap_l;
            nhz = (CLOCK_GetFreq(kCLOCK_IpgClk) / 128U) /timeCapt;
        }
        else
        {
            nhz=0;
        }
        LOG_D("hz: %d",nhz);
        rt_thread_mdelay(200);
    }
}

 

 

 

Labels (1)
0 Kudos
Reply
3 Replies

807 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

我看了你的代码, 你用级联模式要用两个计数器, 但你只用了一个TMR3.

比如你可以用TMR2和TMR3来级联,TMR2->TMR3,

primary count source of TMR2可以是(PCS=0x0F)

kQTMR_ClockDivide_128

primary count source of TMR3 是TMR2的输出(PCS=6)

因为你用到capture function, 你可以将被测信号连接到TMR2_TIMER0,在这种情况下, Secondary Count Source:

SCS of TMR2=0;

SCS of TMR3=0;(此信号用不到)

你可以初始化所有的compare register 到最大值0xFFFF

请参考54.7.5.11 Cascade-Count Mode,并给出代码:

// (See Processor Expert TimerInt bean.)
// This example generates an interrupt every 30 seconds,
// assuming the chip is operating at 60 MHz.
//
// To do this, counter 2 is used to count 60,000 IP_bus clocks, which means it
// will compare and reload every 0.001 seconds.
// Counter 3 is cascaded and used to count the 0.001 second ticks and
// generate the desired interrupt interval.
//
void TimerInt_Init(void)
{
// Set counter 2 to count IP_bus clocks
/* TMR2_CTRL: CM=0,PCS=8,SCS=0,ONCE=0,LENGTH=1,DIR=0,COINIT=0,OUTMODE=0 */
setReg(TMR2_CTRL,0x1020); /* Stop all functions of the timer */
// Set counter 3 as cascaded and to count counter 2 outputs
/* TMR3_CTRL: CM=7,PCS=6,SCS=0,ONCE=0,LENGTH=1,DIR=0,COINIT=0,OUTMODE=0 */
setReg(TMR3_CTRL,0xEC20); /* Set up cascade counter mode */
/* TMR3_SCTRL: TCF=0,TCFIE=0,TOF=0,TOFIE=0,IEF=0,IEFIE=0,IPS=0,INPUT=0,
Capture_Mode=0,MSTR=0,EEOF=0,VAL=0,FORCE=0,OPS=0,OEN=0 */
setReg(TMR3_SCTRL,0x00);
/* TMR2_SCTRL: TCF=0,TCFIE=0,TOF=0,TOFIE=0,IEF=0,IEFIE=0,IPS=0,INPUT=0,
Capture_Mode=0,MSTR=0,EEOF=0,VAL=0,FORCE=0,OPS=0,OEN=0 */
setReg(TMR2_SCTRL,0x00);
setReg(TMR3_CNTR,0x00); /* Reset counter register */
setReg(TMR2_CNTR,0x00);
setReg(TMR3_LOAD,0x00); /* Reset load register */
setReg(TMR2_LOAD,0x00);
setReg(TMR3_COMP1, 30000); /* milliseconds in 30 seconds */
setReg(TMR3_CMPLD1,30000);
setReg(TMR2_COMP1, 60000); // Set to cycle every milisecond
setReg(TMR2_CMPLD1,60000);
/* TMR3_CSCTRL: DBG_EN=0,FAULT=0,ALT_LOAD=0,ROC=0,TCI=0,UP=0,OFLAG=0,
TCF2EN=0,TCF1EN=1,TCF2=0,TCF1=0,CL2=0,CL1=1 */
setReg(TMR3_CSCTRL,0x41); /* Enable compare 1 interrupt and */
/* compare 1 preload */
/* TMR2_CSCTRL: DBG_EN=0,FAULT=0,ALT_LOAD=0,ROC=0,TCI=0,UP=0,OFLAG=0,
TCF2EN=0,TCF1EN=0,TCF2=0,TCF1=0,CL2=0,CL1=1 */
setReg(TMR2_CSCTRL,0x01); /* Enable Compare 1 preload */
setRegBitGroup(TMR2_CTRL,CM,0x01); /* Run counter */

 

BR

XiangJunRong

0 Kudos
Reply

786 Views
944706426
Contributor III

您好,官方的定时器级联例子也是一个定时器的两个通道来级联,对于qtimer来说一个通道的primarySource似乎不能是其他定时器。

944706426_0-1672629042844.png

 

0 Kudos
Reply

829 Views
944706426
Contributor III

顶顶顶,没有人吗

0 Kudos
Reply