- /**************************************************************************//**
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- * [url=home.php?mod=space&uid=895143]@version[/url] V3.00
- * [url=home.php?mod=space&uid=247401]@brief[/url] Show how to use ECAP interface to get input frequency
- *
- * [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2016 Nuvoton Technology Corp. All rights reserved.
- *
- ******************************************************************************/
- #include <stdio.h>
- #include "NuMicro.h"
- #define PLL_CLOCK 192000000
- /*---------------------------------------------------------------------------------------------------------*/
- /* Global variables */
- /*---------------------------------------------------------------------------------------------------------*/
- uint32_t u32Status;
- uint32_t u32IC0Hold;
- void TMR0_IRQHandler(void)
- {
- if(TIMER_GetIntFlag(TIMER0) == 1)
- {
- /* Clear Timer0 time-out interrupt flag */
- TIMER_ClearIntFlag(TIMER0);
- /*PA.0 gpio toggle */
- PA0 ^= 1;
- }
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* ECAP0 IRQ Handler */
- /*---------------------------------------------------------------------------------------------------------*/
- void ECAP0_IRQHandler(void)
- {
- /* Get input Capture status */
- u32Status = ECAP_GET_INT_STATUS(ECAP0);
- /* Check input capture channel 0 flag */
- if((u32Status & ECAP_STATUS_CAPTF0_Msk) == ECAP_STATUS_CAPTF0_Msk)
- {
- /* Clear input capture channel 0 flag */
- ECAP_CLR_CAPTURE_FLAG(ECAP0, ECAP_STATUS_CAPTF0_Msk);
- /* Get input capture counter hold value */
- u32IC0Hold = ECAP0->HLD0;
- }
- /* Check input capture channel 1 flag */
- if((u32Status & ECAP_STATUS_CAPTF1_Msk) == ECAP_STATUS_CAPTF1_Msk)
- {
- /* Clear input capture channel 1 flag */
- ECAP_CLR_CAPTURE_FLAG(ECAP0, ECAP_STATUS_CAPTF1_Msk);
- }
- /* Check input capture channel 2 flag */
- if((u32Status & ECAP_STATUS_CAPTF2_Msk) == ECAP_STATUS_CAPTF2_Msk)
- {
- /* Clear input capture channel 2 flag */
- ECAP_CLR_CAPTURE_FLAG(ECAP0, ECAP_STATUS_CAPTF2_Msk);
- }
- /* Check input capture compare-match flag */
- if((u32Status & ECAP_STATUS_CAPCMPF_Msk) == ECAP_STATUS_CAPCMPF_Msk)
- {
- /* Clear input capture compare-match flag */
- ECAP_CLR_CAPTURE_FLAG(ECAP0,ECAP_STATUS_CAPCMPF_Msk);
- }
- /* Check input capture overflow flag */
- if((u32Status & ECAP_STATUS_CAPOVF_Msk) == ECAP_STATUS_CAPOVF_Msk)
- {
- /* Clear input capture overflow flag */
- ECAP_CLR_CAPTURE_FLAG(ECAP0,ECAP_STATUS_CAPOVF_Msk);
- }
- }
- void SYS_Init(void)
- {
- /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
- PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);
- /* Enable external XTAL 12MHz clock */
- CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
- /* Waiting for external XTAL clock ready */
- CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
- CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HXT, CLK_CLKDIV0_HCLK(1));
- /* Set core clock as PLL_CLOCK from PLL */
- CLK_SetCoreClock(PLL_CLOCK);
- /* Set PCLK0/PCLK1 to HCLK/2 */
- CLK->PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);
- /* Enable UART module clock */
- CLK_EnableModuleClock(UART0_MODULE);
- /* Enable ECAP0 module clock */
- CLK_EnableModuleClock(ECAP0_MODULE);
- /* Enable TIMER0 module clock */
- CLK_EnableModuleClock(TMR0_MODULE);
- /* Select UART module clock source */
- CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));
- /* Select TIMER0 module clock source */
- CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0);
- /* Set GPB multi-function pins for UART0 RXD and TXD */
- SYS->GPB_MFPH &= ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk);
- SYS->GPB_MFPH |= (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);
- /* Set PA.10 for ECAP0_IC0*/
- SYS->GPA_MFPH = (SYS->GPA_MFPH & ~SYS_GPA_MFPH_PA10MFP_Msk) |SYS_GPA_MFPH_PA10MFP_ECAP0_IC0;
- }
- void UART0_Init(void)
- {
- /* Configure UART0 and set UART0 Baudrate */
- UART_Open(UART0, 115200);
- }
- void ECAP0_Init(void)
- {
- /* Enable ECAP0*/
- ECAP_Open(ECAP0, ECAP_DISABLE_COMPARE);
- /* Select Reload function */
- ECAP_SET_CNT_CLEAR_EVENT(ECAP0, (ECAP_CTL1_CAP0RLDEN_Msk|ECAP_CTL1_CAP1RLDEN_Msk));
- /* Enable ECAP0 Input Channel 0*/
- ECAP_ENABLE_INPUT_CHANNEL(ECAP0, ECAP_CTL0_IC0EN_Msk);
- /* Enable ECAP0 source from IC0 */
- ECAP_SEL_INPUT_SRC(ECAP0, ECAP_IC0, ECAP_CAP_INPUT_SRC_FROM_IC);
- /* Select IC0 detect rising edge */
- ECAP_SEL_CAPTURE_EDGE(ECAP0, ECAP_IC0, ECAP_RISING_EDGE);
- /* Input Channel 0 interrupt enabled */
- ECAP_EnableINT(ECAP0, ECAP_CTL0_CAPIEN0_Msk);
- }
- void Timer0_Init(void)
- {
- /* Open Timer0 in periodic mode, enable interrupt and 1 interrupt tick per second */
- TIMER_Open(TIMER0,TIMER_PERIODIC_MODE,10000);
- TIMER_EnableInt(TIMER0);
- /* Enable Timer0 NVIC */
- NVIC_EnableIRQ(TMR0_IRQn);
- }
- int32_t main(void)
- {
- uint32_t u32Hz=0, u32Hz_DET=0;
- /* Unlock protected registers */
- SYS_UnlockReg();
- /* Init System, IP clock and multi-function I/O */
- SYS_Init();
- /* Lock protected registers */
- SYS_LockReg();
- /* Init UART0 for printf */
- UART0_Init();
- printf("\n");
- printf("+----------------------------------------------------------+\n");
- printf("| M480 Enhanced Input Capture Timer Driver Sample Code |\n");
- printf("+----------------------------------------------------------+\n");
- printf("\n");
- printf(" !! GPIO PA.0 toggle periodically !!\n");
- printf(" !! Connect PA.0 --> PA.10(ECAP0_IC0) !!\n\n");
- printf(" Press any key to start test\n\n");
- getchar();
- /* Initial ECAP0 function */
- ECAP0_Init();
- /* Initial Timer0 function */
- Timer0_Init();
- /* Configure PA.0 as output mode */
- GPIO_SetMode(PA, BIT0, GPIO_MODE_OUTPUT);
- /* Start Timer0 counting */
- TIMER_Start(TIMER0);
- /* Delay 200ms */
- CLK_SysTickDelay(200000);
- /* Init & clear ECAP interrupt status flags */
- u32Status = ECAP_GET_INT_STATUS(ECAP0);
- ECAP0->STATUS = u32Status;
- /* ECAP_CNT starts up-counting */
- ECAP_CNT_START(ECAP0);
- while(1)
- {
- if(u32Status != 0)
- {
- /* Input Capture status is changed, and get a new hold value of input capture counter */
- u32Status = 0;
- /* Calculate the IC0 input frequency */
- u32Hz_DET = (SystemCoreClock/2) / (u32IC0Hold + 1);
- if(u32Hz != u32Hz_DET)
- {
- /* If IC0 input frequency is changed, Update frequency */
- u32Hz = u32Hz_DET;
- }
- else
- {
- printf("\nECAP0_IC0 input frequency is %d (Hz),u32IC0Hold=0x%08x\n", u32Hz,u32IC0Hold);
- TIMER_Stop(TIMER0); //Disable timer Counting.
- break;
- }
- }
- }
- /* Disable External Interrupt */
- NVIC_DisableIRQ(ECAP0_IRQn);
- NVIC_DisableIRQ(TMR0_IRQn);
- /* Disable ECAP function */
- ECAP_Close(ECAP0);
- /* Disable Timer0 IP clock */
- CLK_DisableModuleClock(TMR0_MODULE);
- /* Disable ECAP IP clock */
- CLK_DisableModuleClock(ECAP0_MODULE);
- printf("\nExit ECAP sample code\n");
- while(1);
- }
这段程序演示了如何使用NuMicro系列微控制器的ECAP(Enhanced Capture)接口来获取输入信号的频率。下面是主要功能和流程解析:
初始化和系统设置:
设置系统时钟和UART接口,配置用于调试输出的UART0。
启用和配置ECAP0模块的时钟和输入捕获功能。
启用和配置TIMER0模块作为定时器,用于周期性的任务执行。
ECAP模块初始化:
打开ECAP0模块并禁用比较功能。
配置ECAP0的输入捕获通道(IC0),选择从IC0输入源获取输入信号。
设置IC0检测上升沿触发,并启用IC0的输入捕获功能。
启用ECAP0的中断,用于处理捕获事件。
TIMER0定时器初始化:
配置TIMER0为周期模式,并启用定时器中断,每秒钟产生一次中断。
中断处理函数:
TMR0_IRQHandler():处理TIMER0定时器的中断事件,实现定时器中PA0引脚的周期性翻转。
ECAP0_IRQHandler():处理ECAP0模块的捕获事件,获取并处理输入捕获的状态和数据。
|