[DemoCode下载] ECAP抓取信号频率的方法

[复制链接]
 楼主| gejigeji521 发表于 2024-7-13 18:58 | 显示全部楼层 |阅读模式
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
  4. * [url=home.php?mod=space&uid=247401]@brief[/url]    Show how to use ECAP interface to get input frequency
  5. *
  6. * [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2016 Nuvoton Technology Corp. All rights reserved.
  7. *
  8. ******************************************************************************/
  9. #include <stdio.h>
  10. #include "NuMicro.h"

  11. #define PLL_CLOCK       192000000


  12. /*---------------------------------------------------------------------------------------------------------*/
  13. /* Global variables                                                                                        */
  14. /*---------------------------------------------------------------------------------------------------------*/
  15. uint32_t u32Status;
  16. uint32_t u32IC0Hold;

  17. void TMR0_IRQHandler(void)
  18. {
  19.     if(TIMER_GetIntFlag(TIMER0) == 1)
  20.     {
  21.         /* Clear Timer0 time-out interrupt flag */
  22.         TIMER_ClearIntFlag(TIMER0);

  23.         /*PA.0 gpio toggle */
  24.         PA0 ^= 1;
  25.     }
  26. }
  27. /*---------------------------------------------------------------------------------------------------------*/
  28. /*  ECAP0 IRQ Handler                                                                                      */
  29. /*---------------------------------------------------------------------------------------------------------*/
  30. void ECAP0_IRQHandler(void)
  31. {
  32.     /* Get input Capture status */
  33.     u32Status = ECAP_GET_INT_STATUS(ECAP0);

  34.     /* Check input capture channel 0 flag */
  35.     if((u32Status & ECAP_STATUS_CAPTF0_Msk) == ECAP_STATUS_CAPTF0_Msk)
  36.     {
  37.         /* Clear input capture channel 0 flag */
  38.         ECAP_CLR_CAPTURE_FLAG(ECAP0, ECAP_STATUS_CAPTF0_Msk);

  39.         /* Get input capture counter hold value */
  40.         u32IC0Hold = ECAP0->HLD0;
  41.     }

  42.     /* Check input capture channel 1 flag */
  43.     if((u32Status & ECAP_STATUS_CAPTF1_Msk) == ECAP_STATUS_CAPTF1_Msk)
  44.     {
  45.         /* Clear input capture channel 1 flag */
  46.         ECAP_CLR_CAPTURE_FLAG(ECAP0, ECAP_STATUS_CAPTF1_Msk);
  47.     }

  48.     /* Check input capture channel 2 flag */
  49.     if((u32Status & ECAP_STATUS_CAPTF2_Msk) == ECAP_STATUS_CAPTF2_Msk)
  50.     {
  51.         /* Clear input capture channel 2 flag */
  52.         ECAP_CLR_CAPTURE_FLAG(ECAP0, ECAP_STATUS_CAPTF2_Msk);
  53.     }

  54.     /* Check input capture compare-match flag */
  55.     if((u32Status & ECAP_STATUS_CAPCMPF_Msk) == ECAP_STATUS_CAPCMPF_Msk)
  56.     {
  57.         /* Clear input capture compare-match flag */
  58.         ECAP_CLR_CAPTURE_FLAG(ECAP0,ECAP_STATUS_CAPCMPF_Msk);
  59.     }

  60.     /* Check input capture overflow flag */
  61.     if((u32Status & ECAP_STATUS_CAPOVF_Msk) == ECAP_STATUS_CAPOVF_Msk)
  62.     {
  63.         /* Clear input capture overflow flag */
  64.         ECAP_CLR_CAPTURE_FLAG(ECAP0,ECAP_STATUS_CAPOVF_Msk);
  65.     }
  66. }


  67. void SYS_Init(void)
  68. {
  69.     /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
  70.     PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);

  71.     /* Enable external XTAL 12MHz clock */
  72.     CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

  73.     /* Waiting for external XTAL clock ready */
  74.     CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

  75.     CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HXT, CLK_CLKDIV0_HCLK(1));

  76.     /* Set core clock as PLL_CLOCK from PLL */
  77.     CLK_SetCoreClock(PLL_CLOCK);

  78.     /* Set PCLK0/PCLK1 to HCLK/2 */
  79.     CLK->PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);

  80.     /* Enable UART module clock */
  81.     CLK_EnableModuleClock(UART0_MODULE);

  82.     /* Enable ECAP0 module clock */
  83.     CLK_EnableModuleClock(ECAP0_MODULE);

  84.     /* Enable TIMER0 module clock */
  85.     CLK_EnableModuleClock(TMR0_MODULE);

  86.     /* Select UART module clock source */
  87.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));

  88.     /* Select TIMER0 module clock source */
  89.     CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_HXT, 0);

  90.     /* Set GPB multi-function pins for UART0 RXD and TXD */
  91.     SYS->GPB_MFPH &= ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk);
  92.     SYS->GPB_MFPH |= (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);

  93.     /* Set PA.10 for ECAP0_IC0*/
  94.     SYS->GPA_MFPH = (SYS->GPA_MFPH & ~SYS_GPA_MFPH_PA10MFP_Msk) |SYS_GPA_MFPH_PA10MFP_ECAP0_IC0;

  95. }

  96. void UART0_Init(void)
  97. {
  98.     /* Configure UART0 and set UART0 Baudrate */
  99.     UART_Open(UART0, 115200);
  100. }

  101. void ECAP0_Init(void)
  102. {
  103.     /* Enable ECAP0*/
  104.     ECAP_Open(ECAP0, ECAP_DISABLE_COMPARE);

  105.     /* Select Reload function */
  106.     ECAP_SET_CNT_CLEAR_EVENT(ECAP0, (ECAP_CTL1_CAP0RLDEN_Msk|ECAP_CTL1_CAP1RLDEN_Msk));

  107.     /* Enable ECAP0 Input Channel 0*/
  108.     ECAP_ENABLE_INPUT_CHANNEL(ECAP0, ECAP_CTL0_IC0EN_Msk);

  109.     /* Enable ECAP0 source from IC0 */
  110.     ECAP_SEL_INPUT_SRC(ECAP0, ECAP_IC0, ECAP_CAP_INPUT_SRC_FROM_IC);

  111.     /* Select IC0 detect rising edge */
  112.     ECAP_SEL_CAPTURE_EDGE(ECAP0, ECAP_IC0, ECAP_RISING_EDGE);

  113.     /* Input Channel 0 interrupt enabled */
  114.     ECAP_EnableINT(ECAP0, ECAP_CTL0_CAPIEN0_Msk);
  115. }

  116. void Timer0_Init(void)
  117. {

  118.     /* Open Timer0 in periodic mode, enable interrupt and 1 interrupt tick per second */
  119.     TIMER_Open(TIMER0,TIMER_PERIODIC_MODE,10000);
  120.     TIMER_EnableInt(TIMER0);

  121.     /* Enable Timer0 NVIC */
  122.     NVIC_EnableIRQ(TMR0_IRQn);

  123. }


  124. int32_t main(void)
  125. {
  126.     uint32_t u32Hz=0, u32Hz_DET=0;

  127.     /* Unlock protected registers */
  128.     SYS_UnlockReg();

  129.     /* Init System, IP clock and multi-function I/O */
  130.     SYS_Init();

  131.     /* Lock protected registers */
  132.     SYS_LockReg();

  133.     /* Init UART0 for printf */
  134.     UART0_Init();

  135.     printf("\n");
  136.     printf("+----------------------------------------------------------+\n");
  137.     printf("|   M480 Enhanced Input Capture Timer Driver Sample Code   |\n");
  138.     printf("+----------------------------------------------------------+\n");
  139.     printf("\n");
  140.     printf("  !! GPIO PA.0 toggle periodically    !!\n");
  141.     printf("  !! Connect PA.0 --> PA.10(ECAP0_IC0) !!\n\n");
  142.     printf("     Press any key to start test\n\n");
  143.     getchar();

  144.     /* Initial ECAP0 function */
  145.     ECAP0_Init();

  146.     /* Initial Timer0 function */
  147.     Timer0_Init();

  148.     /* Configure PA.0 as output mode */
  149.     GPIO_SetMode(PA, BIT0, GPIO_MODE_OUTPUT);

  150.     /* Start Timer0 counting */
  151.     TIMER_Start(TIMER0);

  152.     /* Delay 200ms */
  153.     CLK_SysTickDelay(200000);

  154.     /* Init & clear ECAP interrupt status flags */
  155.     u32Status = ECAP_GET_INT_STATUS(ECAP0);
  156.     ECAP0->STATUS = u32Status;

  157.     /* ECAP_CNT starts up-counting */
  158.     ECAP_CNT_START(ECAP0);

  159.     while(1)
  160.     {
  161.         if(u32Status != 0)
  162.         {
  163.             /* Input Capture status is changed, and get a new hold value of input capture counter */
  164.             u32Status = 0;

  165.             /* Calculate the IC0 input frequency */
  166.             u32Hz_DET = (SystemCoreClock/2) / (u32IC0Hold + 1);


  167.             if(u32Hz != u32Hz_DET)
  168.             {
  169.                 /* If IC0 input frequency is changed, Update frequency */
  170.                 u32Hz = u32Hz_DET;
  171.             }
  172.             else
  173.             {
  174.                 printf("\nECAP0_IC0 input frequency is %d (Hz),u32IC0Hold=0x%08x\n", u32Hz,u32IC0Hold);
  175.                 TIMER_Stop(TIMER0); //Disable timer Counting.
  176.                 break;
  177.             }
  178.         }

  179.     }
  180.     /* Disable External Interrupt */
  181.     NVIC_DisableIRQ(ECAP0_IRQn);
  182.     NVIC_DisableIRQ(TMR0_IRQn);

  183.     /* Disable ECAP function */
  184.     ECAP_Close(ECAP0);

  185.     /* Disable Timer0 IP clock */
  186.     CLK_DisableModuleClock(TMR0_MODULE);

  187.     /* Disable ECAP IP clock */
  188.     CLK_DisableModuleClock(ECAP0_MODULE);

  189.     printf("\nExit ECAP sample code\n");

  190.     while(1);
  191. }



这段程序演示了如何使用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模块的捕获事件,获取并处理输入捕获的状态和数据。

 楼主| gejigeji521 发表于 2024-7-13 18:59 | 显示全部楼层
主函数循环:

等待用户按下任意键开始测试。
开始ECAP0和TIMER0的计数。
在循环中,通过检测ECAP0的捕获状态,获取输入信号的频率。计算公式为:
9253666925dfe7427e.png
一旦检测到输入频率变化,更新并打印新的频率值。
最终,通过禁用中断和关闭模块的方式结束测试。
这段程序允许您连接一个信号源到PA.0引脚,并使用ECAP0模块获取该信号的输入频率,并通过UART输出显示。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

195

主题

2460

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部

195

主题

2460

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部