由于输入捕获的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);
}
}
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
您好,官方的定时器级联例子也是一个定时器的两个通道来级联,对于qtimer来说一个通道的primarySource似乎不能是其他定时器。
顶顶顶,没有人吗