Hi,
Using QN9080C, I want to measure signals up to 1Mhz using Ctimer 1~3 Capture Inputs.
The APB bus clock is 16 Mhz, and the Datasheet says that the maximum frequency can be measured 1/2 APB bus clock so that I can measure Up to 8 Mhz, But the maximum frequency measured accurately is around 100 ~ 120 kHz.
I used Ctimers 1~3 with kCTIMER_TimerMode, kCTIMER_Capture_0/kCTIMER_Capture_1 and kCTIMER_Capture_FallEdge/kCTIMER_Capture_RiseEdge in Timer Configrations.
And the Code Sequence is CTIMER_Init, CTIMER_RegisterCallBack, CTIMER_SetupCapture and CTIMER_StartTimer.
Hello @EduardoZamora.
Thank you for your reply.
Yes, I used the simple_match_interrupt example. SDK 2.2.6
The callback function takes the CAP value two consecutive and calculates the Frequency.
And below there is my Code.
I tried to raise the APB clock to 32Mhz but got the same result. (CLOCK_SetClkDiv(kCLOCK_DivXtalClk, 0U); /* Set XTAL_DIV divider to value 1 */)
And below, there is all the clocks Configuration I am using.
No, I am not using any BLE or Low Power Feature.
The last results I could reach are 2MHz, but there is a significant error rate. 1MHz appears too much, which means there is an edge we could not catch.
void BOARD_BootClockRUN(void)
{
/* Power up/Power down the module. */
/* Set up clock selectors - Attach clocks to the peripheries */
CLOCK_AttachClk(k32M_to_XTAL_CLK); /* Switch XTAL_CLK to 32M */
CLOCK_AttachClk(kXTAL32K_to_32K_CLK); /* Switch 32K_CLK to XTAL32K */
CLOCK_AttachClk(kXTAL_to_SYS_CLK); /* Switch SYS_CLK to XTAL */
CLOCK_AttachClk(kAPB_to_WDT_CLK); /* Switch WDT_CLK to APB */
/* Set up dividers */
CLOCK_SetClkDiv(kCLOCK_DivOsc32mClk, 1U); /* Set OSC32M_DIV divider to value 2 */
CLOCK_SetClkDiv(kCLOCK_DivXtalClk, 0U); /* Set XTAL_DIV divider to value 2 */
CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 0U); /* Set AHB_DIV divider to value 1 */
CLOCK_SetClkDiv(kCLOCK_DivFrg1, 0U); /* Set FRG_MULT1 to value 0, Set FRG_DIV1 to value 255 */
CLOCK_SetClkDiv(kCLOCK_DivFrg0, 0U); /* Set FRG_MULT0 to value 0, Set FRG_DIV0 to value 255 */
CLOCK_SetClkDiv(kCLOCK_DivApbClk, 0U); /* Set APB_DIV divider to value 1 */
/* Enable/Disable clock out source and pins.*/
/* Enable/Disable the specified peripheral clock.*/
}
Trying measure using Callback:
int volatile Is_First_Captured = 0;
uint32_t volatile IC_Val1 = 0;
uint32_t volatile IC_Val2 = 0;
uint32_t Difference = 0;
uint32_t CTIMER_GetCAPCounter(CTIMER_Type *base, uint32_t chl)
{
uint32_t CR;
CR = base->CR[chl];
return CR;
}
void CaptureEdgeCb(uint32_t flags)
{
if (Is_First_Captured==0) // if the first rising edge is not captured
{
IC_Val1 = CTIMER_GetCAPCounter(CTIMER2, kCTIMER_Capture_0); // read the first value
Is_First_Captured = 1; // set the first captured as true
}
else // If the first rising edge is captured, now we will capture the second edge
{
IC_Val2 = CTIMER_GetCAPCounter(CTIMER2, kCTIMER_Capture_0); // read second value
Difference = IC_Val2 - IC_Val1;
frequency = CLOCK_GetFreq(kCLOCK_CoreSysClk)/Difference;
CTIMER_Reset(CTIMER2); // reset the counter
Is_First_Captured = 0; // set it back to false
PRINTF("Freq %lu\r\n",(unsigned long)frequency);
}
}
/*!
* @brief Main function
*/
int main(void)
{
ctimer_config_t config;
/* Init hardware*/
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
CTIMER_GetDefaultConfig(&config);
config.input = kCTIMER_Capture_0;
PRINTF("Inited \r\n");
CTIMER_Init(CTIMER2, &config);
CTIMER_RegisterCallBack(CTIMER2, s_CtimerCbArray, kCTIMER_SingleCallback);
CTIMER_SetupCapture(CTIMER2, kCTIMER_Capture_0, kCTIMER_Capture_RiseEdge, true);
CTIMER_StartTimer(CTIMER2);
while (1)
{
}
}
Trying to measure with pooling:
/*!
* @brief Main function
*/
int main(void)
{
ctimer_config_t config;
/* Init hardware*/
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
CTIMER_GetDefaultConfig(&config);
//config.input = kCTIMER_Capture_1;
PRINTF("Inited \r\n");
CTIMER_Init(CTIMER2, &config);
CTIMER_SetupCapture(CTIMER2, kCTIMER_Capture_1, kCTIMER_Capture_RiseEdge, false);
uint32_t Capture1 = 0;
uint32_t Capture2 = 0;
uint32_t Period = 0;
/* Clear the timer value */
CTIMER_Reset(CTIMER2);
/* Start the timer */
CTIMER_StartTimer(CTIMER2);
/* Enable the interrupts after starting the timer to void
premature capture triggering
*/
CTIMER_EnableInterrupts(CTIMER2,
(kCTIMER_Capture1InterruptEnable));
while (1)
{
/**** FIRST FALLING EDGE ****/
/* Wait for an interrupt to occur */
while(!(CTIMER2->IR & CTIMER_IR_CR1INT_MASK)){}
/* Fetch the capture value first, then clear the interrupts */
Capture1 = CTIMER2->CR[kCTIMER_Capture_1];
CTIMER2->IR = CTIMER_IR_CR1INT_MASK;
/**** SECOND FALLING EDGE ****/
/* Wait for an interrupt to occur */
while(!(CTIMER2->IR & CTIMER_IR_CR1INT_MASK)){}
/* Fetch the capture value first, then clear the interrupts */
Capture2 = CTIMER2->CR[kCTIMER_Capture_1];
CTIMER2->IR = CTIMER_IR_CR1INT_MASK;
Period = Capture2 - Capture1;
PRINTF("%ld\r\n",32000000/Period);
}
}
Hi,
Could you please help us with more details about the jumper configuration of your board?
Also, please consider removing or replacing the PRINTF() function as it may slow down the execution of your application.
Regards,
Eduardo.
Hi, @EduardoZamora.
My jumper configuration:
JP8, JP14 Connected
JP7 -> VDD SEL 3V
JP2 -> QN9080 Power Supply On Board
And the printf after capturing the two consecutive edges, so there is no problem.
The error in the second edge capture, and there is not so much code between edges capturing.
Hello,
Could you please take a look at this article?
[LPC845] Pulse-width Measurement Using CTIMER
This article mainly introduces how to use CTIMER measuring pulse-width in LPC584, but same steps and considerations should apply to QN9080 CTIMER module and you could use it as a base.
Regards,
Eduardo.
Hello Mohammed,
I apologize for my late response.
Just to confirm, are you using any of the example projects from the SDK as base for your application? Could you please help us with more details about your callback?
Also, could you please confirm if you are using a specific APB clock input divider?
By any chance, are you using any of the BLE or low power features?
Regards,
Eduardo.