GPT定时器定时

今天要说的是这个GPT定时器,由于比较特殊,先简单介绍一下。
首先,它是个32位计数器,递增计数。可以对时钟源进行分频,范围是1~4096。支持2路输入捕获,支持3路比较输出。运行有两种模式。重启模式和自由运行模式(关键)。重启模式就是普通的到达匹配值时,计数器重置。自由运行模式在达到匹配值后不会重置,会一直计数到最大(0XFFFF FFFF)
而且,只有通道1支持重启模式!!!(切记)

<ignore_js_op>

这次打算用GPT1的通道1做一个1S的定时器,先上代码
  1. #include "fsl_device_registers.h"
  2. #include "fsl_debug_console.h"
  3. #include "board.h"
  4. #include "pin_mux.h"
  5. #include "clock_config.h"
  6. #include "fsl_lpuart.h"
  7. #include "fsl_gpt.h"
  8. #include "delay.h"
  9. #define DISPLAY_CLK(name) (PRINTF("%s:%d\r\n",#name,CLOCK_GetFreq(name)))    //打印对应时钟
  10. volatile bool gptIsrFlag = false;
  11. int main(void)
  12. {
  13.     gpt_config_t gptConfig;
  14.         
  15.     BOARD_ConfigMPU();
  16.     BOARD_InitPins();
  17.     BOARD_BootClockRUN();
  18.     BOARD_InitDebugConsole();
  19.     DISPLAY_CLK(kCLOCK_IpgClk);
  20.     DISPLAY_CLK(kCLOCK_OscClk);        
  21.         
  22.     gptConfig.clockSource = kGPT_ClockSource_Osc;     //选择时钟源为 OSC
  23.     gptConfig.divider = 1U;                           //设置时钟分频
  24.     GPT_Init(GPT1, &gptConfig);                       //初始化
  25.     GPT_SetOutputCompareValue(GPT1, kGPT_OutputCompare_Channel1, CLOCK_GetFreq(kCLOCK_OscClk));  //设置输出比较通道的比较值
  26.     GPT_EnableInterrupts(GPT1, kGPT_OutputCompare1InterruptEnable);   //使能对应中断
  27.     EnableIRQ(GPT1_IRQn);       //使能中断
  28.     GPT_StartTimer(GPT1);       //开始计时
  29.     while (1)
  30.     {
  31.     }
  32.         
  33. }
  34. void GPT1_IRQHandler(void)
  35. {
  36.     GPT_ClearStatusFlags(GPT1, kGPT_OutputCompare1Flag);   //清除中断标志位
  37.     LPUART_WriteBlocking(LPUART1, "\n\r",2);//阻塞方式发送一串字符
  38.     __DSB();
  39. }
复制代码


首先还是配置的特色这次是 gpt_config_t,(当然也提供了快速配置的函数GPT_GetDefaultConfig)

typedef struct _gpt_init_config
{
    gpt_clock_source_t clockSource; /*!< clock source for GPT module. */
    uint32_t divider;               /*!< clock divider (prescaler+1) from clock source to counter. */
    bool enableFreeRun;             /*!< true: FreeRun mode, false: Restart mode. */
    bool enableRunInWait;           /*!< GPT enabled in wait mode. */
    bool enableRunInStop;           /*!< GPT enabled in stop mode. */
    bool enableRunInDoze;           /*!< GPT enabled in doze mode. */
    bool enableRunInDbg;            /*!< GPT enabled in debug mode. */
    bool enableMode;                /*!< true:  counter reset to 0 when enabled;
                                    false: counter retain its value when enabled. */
} gpt_config_t;


里面关键的量有两个 clockSource 和 divider 一个是用来配置时钟源的,另一个是用来配置分频的,其他的都是用来配置模式的(什么低功耗运行,DEBUG运行等等)
我们知道,在RT1052设置时钟源和分频主要靠CLOCK_SetMux和CLOCK_SetDiv这两个函数(使用方式可见飞凌RT1052——6.PIT中断与外设时钟配置https://www.nxpic.org.cn/module/foru ... 189&fromuid=3469866(出处: 恩智浦技术社区))
这次我测试了一下,配置这两项对它会有影响(不过这样设置后一些时钟算不清了,感觉有点乱,有时候变有时候不变(有时间再研究一下))有兴趣的可以尝试一下,以下给出时钟图、寄存器位和默认配置(见clock_config.c文件)

<ignore_js_op>
吐一个槽PRECLK_CLK_SEL有俩字母反了(我还很闲的去看了一下勘误表,并没有改,可能确实不重要吧(但对这个3563页的pdf,找东西全靠查找的手册来说,确实有点无语。。。。。))
<ignore_js_op>
<ignore_js_op>

稍微提一下DISPLAY_CLK这个宏,是用来输出时钟频率的,主要是调用了CLOCK_GetFreq(使用方式可见飞凌RT1052——6.PIT中断与外设时钟配置https://www.nxpic.org.cn/module/foru ... 189&fromuid=3469866(出处: 恩智浦技术社区)),用几次就明白了。

gptConfig.clockSource = kGPT_ClockSource_Osc;     //选择时钟源为 OSC
gptConfig.divider = 1U;                           //设置时钟分频

时钟源可以为以下这些
typedef enum _gpt_clock_source
{
    kGPT_ClockSource_Off = 0U,      /*!< GPT Clock Source Off.*/
    kGPT_ClockSource_Periph = 1U,   /*!< GPT Clock Source from Peripheral Clock.*/
    kGPT_ClockSource_HighFreq = 2U, /*!< GPT Clock Source from High Frequency Reference Clock.*/
    kGPT_ClockSource_Ext = 3U,      /*!< GPT Clock Source from external pin.*/
    kGPT_ClockSource_LowFreq = 4U,  /*!< GPT Clock Source from Low Frequency Reference Clock.*/
    kGPT_ClockSource_Osc = 5U,      /*!< GPT Clock Source from Crystal oscillator.*/
} gpt_clock_source_t;

其中kGPT_ClockSource_Periph就是ipg_clk,kGPT_ClockSource_Ext 是外部输入时钟,kGPT_ClockSource_Osc 就是这次要用的OSC时钟了(24MHz)

分频可以设置为1~4096,这里设置为1分频(也就是不分频)

然后GPT_Init(GPT1, &gptConfig);初始化配置

GPT_SetOutputCompareValue(GPT1, kGPT_OutputCompare_Channel1, CLOCK_GetFreq(kCLOCK_OscClk));  //设置输出比较通道的比较值

这个函数一共三个传入值,第一个是选择的模块,第二个是选择的通道,第三个就是要设置的比较值,这里使用CLOCK_GetFreq(kCLOCK_OscClk)得到OSCCLK的主频,把这个作为传入的话,就能定时1S(分频为1)

然后下面三句就没啥好说的了,常见配置。

然后中断回调函数(因为只有通道0才能重启模式运行,我觉得我也不会用那个自由运行模式,就没判断中断来源)
清除对应标志位,打印换行。

最后是运行结果(打开了时间戳)

<ignore_js_op>

posted on 2022-06-15 21:24  张凌001  阅读(328)  评论(0编辑  收藏  举报

导航