S32K1XX_PIT定时器功能的实现

在此篇文章中,我会介绍PIT定时器的一种实现方法与原理,首先我会介绍什么是PIT,PIT的运用,以及介绍一些关键的寄存器,最后结合代码编程介绍一种常用的实现方法。

1、什么是PIT?
2、PIT的运用?
3、PIT模块关键的寄存器介绍
4、实现方法

什么是PIT?
PIT的全称是programmable interval timer (可编程间隔定时器),顾名思义即是可编程的定时器,用于实现计数,定时的效果。

PIT的运用?
定时器的运用在嵌入式当中是离不开的,通常用于任务调度的分配,定时执行某些任务功能,比如每10ms采集一次AD值,每100ms发送一次CAN信号,每1S读取一次RTC时钟的信息等等。合理的分配任务的执行周期,会更加契合CPU的限度。

此文章讲述如何实现1s的计时,每1S实现LED灯闪烁。

PIT寄存器介绍
此处介绍了一些比较重要的寄存器的使用,介绍的不是很详细,如有不对的地方,欢迎指出,仅作参考。

PARAM寄存器
EXT_TRIG: 0X04 (默认值)外部触发器的数量为4
CHANNEL : 0X04 (默认值)定时器通道数为4,即可以实现4个不同的定时器函数
提供了定时器配置的信息,作为了解,对驱动配置不影响。

MCR寄存器
DBG_EN :官方手册说的是在调试模式下,设0停止定时器通道,设1允许在调试模式下继续允许。我0 和 1都试过,在中断函数里面打断点,仍然能够进入中断。所以不理解这个到底是什么意思,欢迎补充。
DOZE_EN : 0:在休眠模式停止运行,1:在休眠模式允许允许。这个还没有试过。
SW_RST: 0:定时器通道和寄存器不复位 1:定时器通通道和寄存器复位
设1的话,定时器中断不会再进入,已尝试
M_CEN : 外围时钟使能位。在正常允许时,该位为1,置0则停止

MSR寄存器:
Bit0-3:分别对应0,1,2,3定时器通道的中断响应标志,单片机检测对应位为1时,进入中断函数后,需要往对应位写1,才能重新计时,写0无效,这样下一个中断才会响应。否则会一直进定时器中断

MIER寄存器:
Bit0-3:分别对应0,1,2,3定时器通道的中断使能标志,如果为0,则代表禁能定时器中断,但是计时功能会有,只是不会进入中断函数。

SETTEN 寄存器:
Bit0-3:分别对应0,1,2,3定时器通道,置1对应通道中断使能,置0无作用

CLRTEN寄存器:
Bit0-3:分别对应0,1,2,3定时器通道,置1启动对应通道中断不使能,置0无作用

TVAL寄存器:分别四个寄存器TVAL[0] - TVAL[3]
Bit0-31:比较模式:寄存器里面的值表示超时的值,即计时到多少,会触发中断
在捕获模式下:每当触发器断言时,计时器值寄存器存储计数器值的逆(不做介绍,没研究过怎么用,原谅我太菜)。

TCVAL分为四个寄存器TCVAL[0] - TCVAL[3],分别对应四个定时器的通道的实时的计数值。

TCTRL寄存器十分重要,同样分为TCTRL[0] - TCTRL[3],用于配置对应定时器的配置信息。

Bit23: 0:选择外部触发源 1:选择内部触发源

Bit17:0:超时(触发中断后)不停止中断定时器1:超时后停止中断定时器

Bit2-3: 00b:32位周期计数器
01b:双16位周期计数器
10b:32位触发累加器
11b-:32位触发输入捕获通道

Bit0: 0:不使能定时器 1:使能定时器

实现方法:

外设配置:
在这里插入图片描述
下面Name的lpit1_ChnConfig0在代码中会生成一样名字的结构体,包含了两个信息:是否允许调试模式下运行,是否允许休眠情况下允许,我这里Run In Debug 和 Run In Doze两个都不勾选。
read only不勾选,
Timer Mode选择32位计数器,
Period Unit选择 Count Unit

敲黑板!!!重中之重的重点来了!!!
同时下面会有提示信息,包含定时器时钟的频率8MHZ,和每一个周期的运行时间125ns,表示定时器中断的计数器每加1一次,需要125ns,一秒钟可以加8000000次,如果我们要实现1S的定时器中断,首先1S = 1 000 000 000 ns ,则Timer Period里面填入的数为1000000000/125 = 8000000,表示计数器从0加到8000000就触发中断,加8000000次的时间就是1s 这样就实现了 1S的中断。
同理,如果要实现1ms的中断,首先转换一下1ms = 1000000ns ,用1000000/125 = 8000,即填入8000就可以实现1ms的计时,这里根据实际需求选择。
Trigger Source表示中断源,这里外部触发源,可以节省一定内部资源。
最后一定要勾选 Interrupt Enable ,使能中断。

代码部分相对比较固定,用的基本都是库函数和官方Demo的部分函数
1、首先是时钟初始化和GPIO的初始化。
2、然后对PIT进行初始化,使用的函数和结构体名,都可以在库函数中找到,LPIT_DRV_Init就是配置是否调试模式下运行(这个我也没搞懂实际作用),和休眠模式下是否运行(未测试)。
3、PIT内部有四个定时器通道,LPIT_DRV_InitChannel函数则是对配置的其中一个通道进行初始化,配置计数的模式和定时的时长。
4、LPIT_DRV_EnableTimerChannelInterrupt则是运行定时器产生中断
5、LPIT_DRV_StartTimerChannels开启计数的功能
6、INT_SYS_SetPriority启动中断,和设定中断的优先级
7、最后要声明LPIT0_Ch0_IRQHandler函数,在里面写入需要执行的任务,我实现的是LED的反转,这个函数名是固定的,系统会自动进入该中断函数。在进入中断函数之后,需要清除中断标志位LPIT0->MSR = 1对MSR寄存器的BIT0置1即可,这里表示的是0通道的定时器,如果是另外的通道的,就要对应通道置1,才能清除中断,也可以使用函数LPIT_DRV_ClearInterruptFlagTimerChannels,如果不清0,系统检测到中断标志为1,会一直进入中断,影响程序的正常运行。

关于函数里面的传参也很简单,用的结构体都是系统生成好的。还有其他的,第一个参数0表示PIT的通道,第二个参数需要做位移运算,表示内部的定时器通道,基本都是bit0-bit3,对应一个内部通道

代码实现:

#include "sdk_project_config.h"

#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include"CLOCK_S32K1xx.h"
#include "interrupt_manager.h"
#include"lpit_driver.h"

extern void LPIT0_Ch0_IRQHandler(void);

int main(void)
{
    CLOCK_SYS_Init(g_clockManConfigsArr,   CLOCK_MANAGER_CONFIG_CNT, g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
    CLOCK_SYS_UpdateConfiguration(0U, 1);    // 时钟初始化

    PINS_DRV_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);      //GPIO初始化

    LPIT_DRV_Init(0,&lpit1_InitConfig);                         //LPIT初始化
    LPIT_DRV_InitChannel(0,0,&lpit1_ChnConfig0);    //配置计数模式,定时时间
    LPIT_DRV_EnableTimerChannelInterrupt(0,1<<0);   //允许定时器生成中断
    LPIT_DRV_StartTimerChannels(0, (1 << 0));         //启动计数
    INT_SYS_SetPriority(LPIT0_Ch0_IRQn,9);          //设置中断优先级
    while(1)
    {

    }
}

void LPIT0_Ch0_IRQHandler(void)
{
	LPIT0->MSR  = 1 ;       /* 也可以用 LPIT_DRV_ClearInterruptFlagTimerChannels(0, (1 << 0)); */       /*  清除中断响应标志位  */
    PTD->PTOR =   1 << 16; /* LED灯反转 */
}
  • 47
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值