freetech

kinetis的FTM例程——定时器模计数(中断方式)

0
阅读(3279)

现象还是昨天的现象,这次改用中断方式实现,借FTM说说中断的使用。下面介绍相关寄存器:

NVICISERn - 中断使能寄存器,每个寄存器控制32个中断源的使能,使用时把NVICISERn的第m位置1,其中n=62/32,m=62%32。本示例中是NVICISER1的第30位为1(NVICISER1 |= (uint32_t)0x40000000UL;)。

NVICICERn - 中断禁止寄存器,每个寄存器控制32个中断源的禁止,使用时把NVICICERn的第m位置1,其中n=62/32,m=62%32。本示例中未用到该寄存器。

NVICISPRn - 中断挂起寄存器,每个寄存器写时控制32个中断源的挂起(写1对就的位被挂起),读时得到中断是否挂起的状态(读为1对就的位处于挂起状态)。

NVICICPRn - 中断挂起寄存器,每个寄存器写时控制32个中断源的解除挂起(写1对就的位被解除挂起),读时得到中断是否挂起的状态(读为1对就的位处于挂起状态),和NVICISPRn相同。

NVICIABRn - 中断活动寄存器,读时得到中断是否处于活动状态。

NVICIPn - 中断优先级寄存器,每个中断向量可设置0~255的优先级,数越小优先级越高。

NVICSTIR - 软件触发中断寄存器,写该寄存器触发对应的中断号。

要使用定时器溢出中断,要做3件事:

1、FTMx_SC的中断使能位IE置1。

2、NVICISERn 相应的位置1开启中断。本例中是NVICISER1 |= (uint32_t)0x40000000UL;

3、中断向量表对应的位置填中断服务程序地址。本例中是kinetis_sysinit.c的__vect_table{}的78号中断处填(tIsrFunc)FTM0_Interrupt。

下面是完整代码:

/*
* 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 FTM0_Init()
{
    SIM_SCGC6 |= (uint32_t)0x01000000UL;
    FTM0_MODE = (uint32_t)0x04UL;
    FTM0_SC = (uint32_t)0x00UL;
    FTM0_CNTIN = (uint32_t)0;//初值值0
    FTM0_CNT = (uint32_t)0;//计数值0
    FTM0_MOD = (uint32_t)50000;//模50000
    FTM0_SC = (uint32_t)0x4FUL;//系统时钟,128分频
    NVICISER1 |= (uint32_t)0x40000000UL;//使能中断NVICISERn=m,其中n=62/32,m=62%32
}
int main(void)
{
    static int counter = 26;
    FTM0_Init();
    GPIO_Init();
    printf("Hello (Kinetis) World in 'C' from PK60X256 derivative! \n\r");
    for(;;)
    {

    }
    return 0;
}
void FTM0_Interrupt(void)
{
    unsigned int tmp;
    static int counter = 26;
    tmp = FTM0_SC;
    FTM0_SC &= ~0x80;
    GPIOA_PDOR = GPIO_PDOR_PDO(GPIO_PIN(counter));
    counter++;
    if(counter > 29)
    {
        counter = 26;
    }
}

把kinetis_sysinit.c的__vect_table{}的78号中断的(tIsrFunc)UNASSIGNED_ISR   换成 (tIsrFunc)FTM0_Interrupt。