freetech

kinetis的RTC报警中断例程

0
阅读(22422)

实时时钟是个32位秒计数器,一次溢出时间为4294967296秒=71582788分钟=1193046小时=49710天=1657月=138年>1世纪。一般我们只用其1个世纪以内,计的时年份的后2位。和其他时钟芯片一样,百年虫问题依然存在(目前笔者还未发现不存在百年虫问题的时钟芯片)。下面介绍其寄存器:

RTC_TSR - 时间秒寄存器。当时间计数器使能时,每秒钟该寄存器加1

RTC_TPR  - RTC时间预分频器寄存器。当时间计数器使能时,每隔32.768kHz个时钟周TPR增加并且是只读的。

RTC_TAR - RTC时间报警寄存器。当时间计数器开启时,每当TAR[TAR]等于TSR[TSR]并且TSR[TSR]增加时,SR[TAF]设置。写TAR清除SR[TAF]。

RTC_TCR - RTC时间补偿寄存器。

RTC_CR - RTC控制寄存器 。

RTC_SR - RTC状态寄存器。第0位是时间无效标志,第1位是时间溢出标志,第2位是时间报警标志,第3位保留,第4位是时间计数器使能,为1时,时间计数器打开;为0时,时间计数器关闭。

RTC_LR - RTC锁定寄存器。第3位是时间补偿锁定,第4位是控制寄存器锁定,第5位是状态寄存器锁定。某为0时,相应的寄存器被锁定。一明某位被清0,只能通过VBAT POR或软件复位置1。

RTC_IER - RTC中断使能寄存器。第7位是唤醒相脚打开,当该位为1时如果唤醒引脚使能,则输出唤醒信号。第6~5位保留。第4位秒中断使能。第3位保留。第2位是报警寄存器中断使能。第1位是溢出中断使能。第0位是时间无效中断使能。当某位为1时,相应的中断允许产生。当某位为0时,相应的中断禁止产生。

RTC_WAR - RTC写访问寄存。第7位控制中断使能寄存器写入,第6位控制锁定寄存器写入,第5位控制状态寄存器写入,第4位控制控制寄存器写入,第3位控制时间补偿寄存器写入,第2位控制时间报警寄存器写入,第1位控制时间预分频器寄存器写入,第0位控制时间秒寄存器写入。某为0时,相应的寄存器的写操作被忽略。

RTC_RAR - RTC读访问寄存器。各位的功能同RTC_WAR,只是控制的不是写入而是读出。某为0时,相应的寄存器的读操作被忽略。

下面用报警中断实现跑马灯。要使用RTC,首先要配置系统集成模块,打开RTC的时钟。接着设置RTC相应寄存器即可。下面是完整代码:

/*
* 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 RTC_Init()
{
    SIM_SCGC6 |= (uint32_t)0x20000000UL;
    RTC_CR = 1;        //软件复位RTC
    RTC_CR &= ~1;
    RTC_CR &= ~0x3C00;    //不使用负载电容
    RTC_CR |= 0x0100;    //使能32.768kHz
    delay();
    RTC_CR &= ~0x0200;    //32.768kHz不输出至其它外设
    RTC_SR = (uint32_t)0x00UL;
    RTC_TPR = (uint32_t)0x00UL;
    RTC_TSR = (uint32_t)0x01UL;
    RTC_TAR = (uint32_t)0x02UL;
    RTC_TCR = (uint32_t)0x00UL;
    RTC_SR = (uint32_t)0x10UL;
    RTC_IER = (uint32_t)0x04UL;//(1<<4) | 秒中断和报警中断
    NVICISER2 |= 0x04;//使能中断NVICISERn=1<<m,其中n=(82-16)/32,m=(82-16)%32
}

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

    }
    return 0;
}

void RTC_ISR(void)
{
    static int counter = 26;
    RTC_TAR = RTC_TSR + 2;       
    GPIOA_PDOR = GPIO_PDOR_PDO(GPIO_PIN(counter));
    counter++;
    if(counter > 29)
    {
        counter = 26;
    }
}

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