freetech

kinetis的PIT例程——跑马灯

0
阅读(19213)

FTM虽然功能较多,但因是16位定时器,故不能做长周期定时,PIT是个32位定时器,可实现比FTM周期长很多的定时,且可工作的菊花链模式,相当于一个128位定时器,可以实现相当长时间的定时。需要注意的是PIT是个递减计数器,下面介绍相关寄存器:

PIT_MCR - 定时器模块控制寄存器。第0位是 FRZ-冻结控制位,为1时 在调试模式下定时器停止;为0时 在调试模式下定时器继续运行。

PIT_LDVALn - 定时器加载值寄存器。该寄存器设置定时器起始值。定时器将会倒计数直到为0,然后产生一个中断后再加载这个寄存器的值。向这个寄存器写入新值不会重启定时器,相反在定时器到期后才会加载新值。为了取消当前周期,以新值开始一个定时器周期,则必须先禁止定时器再使能定时器。

PIT_CVALn - 当前定时器值寄存器。如果使能了定时器,这些位就代表了当前定时器的值。如果定时器被禁止了,不要使用这些位域的值,因为这些值是不可靠的。

PIT_TCTRLn - 定时器控制寄存器。第0位是定时器使能位,为1时使能相应通道;为0时相应通道被禁止。第1位是中断使能位,为1时相应通道允许产生中断;为0时相应通道不允许产生中断。第2位是菊花链使能位,为0时不使用菊花链方式,为1时使用菊花链方式。当该位为1时,前一个通道发生1次溢出触发后一个通道的1次计数。

PIT_TFLGn - 定时器标志寄存器。TIF在定时器周期结束时置1。只有在写入1时该标志才被清除。写0无效。如果使能(TIE),TIF产生一个中断请求。

现象还是前面的现象,现在改用PIT定时器来实现。下面是完整代码:

/*
* main implementation: use this 'C' sample to create your own application
*
*/

#define GPIO_PIN_MASK            0x3C000000
#define GPIO_PIN(x)                ((1<<x)&GPIO_PIN_MASK)

#include <stdio.h>
#include "derivative.h" /* include peripheral declarations */

void delay()
{
    int i =0;
    int j=0;
    for(i=0;i<3000;i++)
      for(j=0;j<1000;j++)
          asm("nop");
}
void GPIO_Init()
{
    SIM_SCGC5 = SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;
    /* Set GPIOA pin26~29 as GPIO*/
    PORTA_PCR26=(PORT_PCR_MUX(1));
    PORTA_PCR27=(PORT_PCR_MUX(1));
    PORTA_PCR28=(PORT_PCR_MUX(1));
    PORTA_PCR29=(PORT_PCR_MUX(1));
    //set GPIOA pin26~29 to be output
    GPIOA_PDDR=GPIO_PDDR_PDD(GPIO_PIN(26))
         | GPIO_PDDR_PDD(GPIO_PIN(27))
         | GPIO_PDDR_PDD(GPIO_PIN(28))
         | GPIO_PDDR_PDD(GPIO_PIN(29));
    GPIOA_PDOR = 0;//所有LED灭
}
void PIT_Init()
{
    SIM_SCGC6 |= 0x00800000;
    PIT_MCR = 0x00;
    PIT_TCTRL0 = 0x00;
    PIT_TFLG0 = 0x01;
    PIT_LDVAL0 = 10000000;
    NVICISER2 |= 0x10;//使能中断NVICISERn=m,其中n=84/32,m=84%32
    PIT_TCTRL0 = 0x03;

    PIT_TCTRL1 = 0x00;
    PIT_TFLG1 = 0x01;
    PIT_LDVAL1 = 20000000;
    NVICISER2 |= 0x20;//使能中断NVICISERn=m,其中n=85/32,m=85%32
    PIT_TCTRL1 = 0x03;
    PIT_TCTRL2 = 0x00;
    PIT_TFLG2 = 0x01;
    PIT_LDVAL2 = 30000000;
    NVICISER2 |= 0x40;//使能中断NVICISERn=m,其中n=86/32,m=86%32
    PIT_TCTRL2 = 0x03;
    PIT_TCTRL3 = 0x00;
    PIT_TFLG3 = 0x01;
    PIT_LDVAL3 = 40000000;
    NVICISER2 |= 0x80;//使能中断NVICISERn=m,其中n=87/32,m=87%32   
    PIT_TCTRL3 = 0x03;
}

int main(void)
{
    PIT_Init();   
    GPIO_Init();   

    printf("Hello (Kinetis) World in 'C' from PK60X256 derivative! \n\r");
    for(;;)
    {

    }
    return 0;
}

void PIT_CH0_ISR(void)
{
    PIT_TFLG0 = 1;       
    GPIOA_PDOR = GPIO_PDOR_PDO(GPIO_PIN(26));
    PIT_TCTRL0 = (uint32_t)0x00UL;
}
void PIT_CH1_ISR(void)
{
    PIT_TFLG1 = 1;       
    GPIOA_PDOR = GPIO_PDOR_PDO(GPIO_PIN(27));
    PIT_TCTRL1 = (uint32_t)0x00UL;
}
void PIT_CH2_ISR(void)
{
    PIT_TFLG2 = 1;       
    GPIOA_PDOR = GPIO_PDOR_PDO(GPIO_PIN(28));
    PIT_TCTRL2 = (uint32_t)0x00UL;
}
void PIT_CH3_ISR(void)
{
    PIT_TFLG3 = 1;       
    GPIOA_PDOR = GPIO_PDOR_PDO(GPIO_PIN(29));
    //PIT_TCTRL3 = (uint32_t)0x00UL;
    PIT_TCTRL0 = (uint32_t)0x03UL;
    PIT_TCTRL1 = (uint32_t)0x03UL;
    PIT_TCTRL2 = (uint32_t)0x03UL;
}

把kinetis_sysinit.c的__vect_table{}的84~87号中断的(tIsrFunc)UNASSIGNED_ISR   换成 (tIsrFunc)PIT_CH0_ISR~(tIsrFunc)PIT_CH3_ISR。