i.MX 8M EVK:如何计算 1ms 计时器的频率值?
i.MX 8M EVK : how to calculate the frequency values for a 1ms timer?
我想实现一个简单的“GPT”定时器,它每 1 毫秒产生一个中断。
但是,我每 3 毫秒(而不是所需的 1 毫秒)得到一个中断。
我的错误在哪里?我应该设置什么值才能获得 1ms 计时器?
这是我对 GPT 计时器的计算:
定时器值的解释:
我们将 PLL1 DIV2 400MHz 作为源时钟
我们将根除数定义为 4 => 400MHz / 4 = 100MHz
100MHz = 每 10ns 增加一个
我们希望每 1 ms 产生一个中断
所以我们有:
Output_compare_value = delay_time x GPT_frequency
Output_compare_value = 1 x 10^-3 x (1/(10 x 10^-9)) = 100000
这是我的代码(我在每次中断时更改 GPIO 的状态以检查示波器上定时器的运行):
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_gpt.h"
#include "fsl_gpio.h"
#include "fsl_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define GPT_IRQ_ID GPT1_IRQn
#define EXAMPLE_GPT GPT1
//#define EXAMPLE_GPT_CLK_FREQ \
// (CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootGpt1)) / \
// (CLOCK_GetRootPostDivider(kCLOCK_RootGpt1)) / 2) /* SYSTEM PLL1 DIV2 */
#define EXAMPLE_GPT_CLK_FREQ 100000
#define EXAMPLE_GPT_IRQHandler GPT1_IRQHandler
#define EXAMPLE_LED_GPIO GPIO3
#define EXAMPLE_LED_GPIO_PIN 23U
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
volatile bool gptIsrFlag = false;
/* The PIN status */
volatile bool g_pinSet = false;
/*******************************************************************************
* Code
******************************************************************************/
void EXAMPLE_GPT_IRQHandler(void)
{
/* Clear interrupt flag.*/
GPT_ClearStatusFlags(EXAMPLE_GPT, kGPT_OutputCompare1Flag);
gptIsrFlag = true;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F, Cortex-M7, Cortex-M7F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U || __CORTEX_M == 7U)
__DSB();
#endif
}
/*!
* @brief Main function
*/
int main(void)
{
uint32_t gptFreq;
gpt_config_t gptConfig;
/* Define the init structure for the output LED pin*/
gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
/* Board pin, clock, debug console init */
/* Board specific RDC settings */
BOARD_RdcInit();
BOARD_InitBootPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
BOARD_InitMemory();
CLOCK_SetRootMux(kCLOCK_RootGpt1, kCLOCK_GptRootmuxSysPll1Div2); /* Set GPT1 source to SYSTEM PLL1 DIV2 400MHZ */
CLOCK_SetRootDivider(kCLOCK_RootGpt1, 1U, 4U); /* Set root clock to 400MHZ / 4 = 100MHZ */
GPT_GetDefaultConfig(&gptConfig);
/* Initialize GPT module */
GPT_Init(EXAMPLE_GPT, &gptConfig);
/* Divide GPT clock source frequency by 3 inside GPT module */
GPT_SetClockDivider(EXAMPLE_GPT, 1);
/* Get GPT clock frequency */
gptFreq = EXAMPLE_GPT_CLK_FREQ;
/* GPT frequency is divided by 3 inside module */
gptFreq /= 1;
/* Set both GPT modules to 1 second duration */
GPT_SetOutputCompareValue(EXAMPLE_GPT, kGPT_OutputCompare_Channel1, gptFreq);
/* Enable GPT Output Compare1 interrupt */
GPT_EnableInterrupts(EXAMPLE_GPT, kGPT_OutputCompare1InterruptEnable);
/* Enable at the Interrupt */
EnableIRQ(GPT_IRQ_ID);
PRINTF("\r\nPress any key to start the example");
GETCHAR();
/* Init output LED GPIO. */
GPIO_PinInit(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, &led_config);
/* Start Timer */
PRINTF("\r\nStarting GPT timer ...");
GPT_StartTimer(EXAMPLE_GPT);
while (true)
{
/* Check whether occur interupt and toggle LED */
if (true == gptIsrFlag)
{
PRINTF("\r\n GPT interrupt is occurred !");
gptIsrFlag = false;
if (g_pinSet)
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);
g_pinSet = false;
}
else
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);
g_pinSet = true;
}
}
else
{
__WFI();
}
}
}
我发现了计时器的问题。事实上,我所有的值都很好,但是日志记录的执行需要时间(第 PRINTF("GPT interrupt is occurred !");
行)所以我本可以进一步降低我的重新加载值,但我仍然会有日志记录花时间 运行.
我想实现一个简单的“GPT”定时器,它每 1 毫秒产生一个中断。 但是,我每 3 毫秒(而不是所需的 1 毫秒)得到一个中断。
我的错误在哪里?我应该设置什么值才能获得 1ms 计时器?
这是我对 GPT 计时器的计算:
定时器值的解释:
我们将 PLL1 DIV2 400MHz 作为源时钟 我们将根除数定义为 4 => 400MHz / 4 = 100MHz
100MHz = 每 10ns 增加一个 我们希望每 1 ms 产生一个中断
所以我们有: Output_compare_value = delay_time x GPT_frequency
Output_compare_value = 1 x 10^-3 x (1/(10 x 10^-9)) = 100000
这是我的代码(我在每次中断时更改 GPIO 的状态以检查示波器上定时器的运行):
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_gpt.h"
#include "fsl_gpio.h"
#include "fsl_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define GPT_IRQ_ID GPT1_IRQn
#define EXAMPLE_GPT GPT1
//#define EXAMPLE_GPT_CLK_FREQ \
// (CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootGpt1)) / \
// (CLOCK_GetRootPostDivider(kCLOCK_RootGpt1)) / 2) /* SYSTEM PLL1 DIV2 */
#define EXAMPLE_GPT_CLK_FREQ 100000
#define EXAMPLE_GPT_IRQHandler GPT1_IRQHandler
#define EXAMPLE_LED_GPIO GPIO3
#define EXAMPLE_LED_GPIO_PIN 23U
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
volatile bool gptIsrFlag = false;
/* The PIN status */
volatile bool g_pinSet = false;
/*******************************************************************************
* Code
******************************************************************************/
void EXAMPLE_GPT_IRQHandler(void)
{
/* Clear interrupt flag.*/
GPT_ClearStatusFlags(EXAMPLE_GPT, kGPT_OutputCompare1Flag);
gptIsrFlag = true;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F, Cortex-M7, Cortex-M7F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U || __CORTEX_M == 7U)
__DSB();
#endif
}
/*!
* @brief Main function
*/
int main(void)
{
uint32_t gptFreq;
gpt_config_t gptConfig;
/* Define the init structure for the output LED pin*/
gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
/* Board pin, clock, debug console init */
/* Board specific RDC settings */
BOARD_RdcInit();
BOARD_InitBootPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
BOARD_InitMemory();
CLOCK_SetRootMux(kCLOCK_RootGpt1, kCLOCK_GptRootmuxSysPll1Div2); /* Set GPT1 source to SYSTEM PLL1 DIV2 400MHZ */
CLOCK_SetRootDivider(kCLOCK_RootGpt1, 1U, 4U); /* Set root clock to 400MHZ / 4 = 100MHZ */
GPT_GetDefaultConfig(&gptConfig);
/* Initialize GPT module */
GPT_Init(EXAMPLE_GPT, &gptConfig);
/* Divide GPT clock source frequency by 3 inside GPT module */
GPT_SetClockDivider(EXAMPLE_GPT, 1);
/* Get GPT clock frequency */
gptFreq = EXAMPLE_GPT_CLK_FREQ;
/* GPT frequency is divided by 3 inside module */
gptFreq /= 1;
/* Set both GPT modules to 1 second duration */
GPT_SetOutputCompareValue(EXAMPLE_GPT, kGPT_OutputCompare_Channel1, gptFreq);
/* Enable GPT Output Compare1 interrupt */
GPT_EnableInterrupts(EXAMPLE_GPT, kGPT_OutputCompare1InterruptEnable);
/* Enable at the Interrupt */
EnableIRQ(GPT_IRQ_ID);
PRINTF("\r\nPress any key to start the example");
GETCHAR();
/* Init output LED GPIO. */
GPIO_PinInit(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, &led_config);
/* Start Timer */
PRINTF("\r\nStarting GPT timer ...");
GPT_StartTimer(EXAMPLE_GPT);
while (true)
{
/* Check whether occur interupt and toggle LED */
if (true == gptIsrFlag)
{
PRINTF("\r\n GPT interrupt is occurred !");
gptIsrFlag = false;
if (g_pinSet)
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 0U);
g_pinSet = false;
}
else
{
GPIO_PinWrite(EXAMPLE_LED_GPIO, EXAMPLE_LED_GPIO_PIN, 1U);
g_pinSet = true;
}
}
else
{
__WFI();
}
}
}
我发现了计时器的问题。事实上,我所有的值都很好,但是日志记录的执行需要时间(第 PRINTF("GPT interrupt is occurred !");
行)所以我本可以进一步降低我的重新加载值,但我仍然会有日志记录花时间 运行.