i want to use the LPC4357's GP_CLKIN fun--use pin-PF_4 as GP_CLKIN,the singal is Sin-Wave,the frequence is about 17MHZ. I use the Frequency monitor register,but i can not read the input singal frequence.
the code such as :
the PF_4 pin set as gp_clkin:
LPC_SCU->SFSPF_4 = (0 << 7) | (0 << 6) | (1 << 5) | (2 << 3) | 1; //GP_CLKIN
loop read some times,as follow:
for(i=0; i<FRE_NUM; i++)
{
fre[i] = freq_measure(4); //GP_CLKIN
for(j=0; j<10000; j++);
}
and then, function freq_measure(),as follow:
uint32_t freq_measure(uint32_t clk_sel)
{
volatile uint32_t fcnt, rcnt, fout;
/* Set register values */
LPC_CGU->FREQ_MON &= ~(1 << 23); /* Stop frequency counters */
LPC_CGU->FREQ_MON = (clk_sel << 24) | IRC_CNT; /* RCNT == 511 */
LPC_CGU->FREQ_MON |= (1 << 23); /* Start RCNT and FCNT */
while(LPC_CGU->FREQ_MON & (1 << 23))
{
fcnt = (LPC_CGU->FREQ_MON >> 9) & 0x3FFF;
rcnt = (LPC_CGU->FREQ_MON ) & 0x01FF;
if(fcnt == 0 && rcnt == 0)
{
return (0); /* No input clock present */
}
}
fcnt = (LPC_CGU->FREQ_MON >> 9) & 0x3FFF;
fout = fcnt * (12000000U/IRC_CNT); /* FCNT * (IRC_CLK / RCNT) */
return (fout);
}
when i debug,after the measure started,FREQ_MON's MEAS bit don't clear,and fcnt=0 always,but rcnt don't be 0.
the program is loop in the while(LPC_CGU->FREQ_MON & (1 << 23))
So,is ther some initial error?
Hi sky sky ,
/*********************************************************************//**
* @brief Compare one source clock to IRC clock
* @param[in] Clock Clock entity that will be compared to IRC, should be:
* - CGU_CLKSRC_32KHZ_OSC :32Khz crystal oscillator
* - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock
* - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock
* - CGU_CLKSRC_GP_CLKIN :General purpose input clock
* - CGU_CLKSRC_XTAL_OSC :Crystal oscillator
* - CGU_CLKSRC_PLL0 :PLL0 clock
* - CGU_CLKSRC_PLL1 :PLL1 clock
* - CGU_CLKSRC_IDIVA :Integer divider register A
* - CGU_CLKSRC_IDIVB :Integer divider register B
* - CGU_CLKSRC_IDIVC :Integer divider register C
* - CGU_CLKSRC_IDIVD :Integer divider register D
* - CGU_CLKSRC_IDIVE :Integer divider register E
* - CGU_BASE_SAFE :Base safe clock (always on)for WDT
* - CGU_BASE_USB0 :Base clock for USB0
* - CGU_BASE_USB1 :Base clock for USB1
* - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core
* and APB peripheral blocks #0 and #2
* - CGU_BASE_SPIFI :Base clock for SPIFI
* - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx
* - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx
* - CGU_BASE_APB1 :Base clock for APB peripheral block #1
* - CGU_BASE_APB3 :Base clock for APB peripheral block #3
* - CGU_BASE_LCD :Base clock for LCD
* - CGU_BASE_SDIO :Base clock for SDIO card reader
* - CGU_BASE_SSP0 :Base clock for SSP0
* - CGU_BASE_SSP1 :Base clock for SSP1
* - CGU_BASE_UART0 :Base clock for UART0
* - CGU_BASE_UART1 :Base clock for UART1
* - CGU_BASE_UART2 :Base clock for UART2
* - CGU_BASE_UART3 :Base clock for UART3
* - CGU_BASE_CLKOUT :Base clock for CLKOUT pin
* @param[in] m Multiple value pointer
* @param[in] d Divider value pointer
* @return Compare status, could be:
* - (-1): fail
* - 0: successful
* @note Formula used to compare:
* FClock = F_IRC* m / d
**********************************************************************/
int CGU_FrequencyMonitor(CGU_ENTITY_T Clock, uint32_t *m, uint32_t *d){
uint32_t n,c,temp;
int i;
/* Maximum allow RCOUNT number */
c= 511;
/* Check Source Clock Freq is larger or smaller */
LPC_CGU->FREQ_MON = (Clock<<24) | 1<<23 | c;
while(LPC_CGU->FREQ_MON & (1 <<23));
for(i=0;i<10000;i++);
temp = (LPC_CGU->FREQ_MON >>9) & 0x3FFF;
if(temp == 0) /* too low F < 12000000/511*/
return -1;
if(temp > 511){ /* larger */
c = 511 - (LPC_CGU->FREQ_MON&0x1FF);
}else{
do{
c--;
LPC_CGU->FREQ_MON = (Clock<<24) | 1<<23 | c;
while(LPC_CGU->FREQ_MON & (1 <<23));
for(i=0;i<10000;i++);
n = (LPC_CGU->FREQ_MON >>9) & 0x3FFF;
}while(n==temp);
c++;
}
*m = temp;
*d = c;
return 0;
}
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
hi jeremy:
你给的这个频率监测的代码,好像有些问题哦。
我实际测试的话,只能测出小于12M的信号频率,大于12M的信号频率都是有些错误的。
比如,16-7M的信号测出来只有6,700K.
更大一点的,32M左右的信号,测出来只有4M多一点
不知道是函数处理里面哪里有点不对
Dear Jeremy:
In view of this problem,now,i have found another issue.
i use two board have the same program that you reply,one is correct,another is error.
The error is wait always at
LPC_CGU->FREQ_MON = (Clock<<24) | 1<<23 | c;
while(LPC_CGU->FREQ_MON & (1 <<23));
According to the instructions on the document 《13.6.1 Frequency monitor register》,when the RCNT counts down towards 0,the MEAS bit will be 0,but why
while(LPC_CGU->FREQ_MON & (1 <<23));
can not complete??
the error board also works correct yesterday.
So,where is the bug? i think about the PF_4 pin or FREQ_MON register has error?
hi jeremy:
i found out the problem is at the pin PF_4. When i connect the external signal to the PF_4,the singal is pulled down a low level,and disconnect the pin,the singal recover normal.
So it isn't a software problem.
It seems too complex to used for measuring high frequence singal.
Especially the code such as for(i=0; i<10000; i++);
Is it necessary?
Hi sky sky,
Thanks for you reply.
I think the phenomenal is normal, this phenomenal is also exist in the external oscillator.
Hope this is clear.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
hi jeremy:
thank you for your reply.
i will try the code you provide.