kinetis的RTC报警中断例程
0赞实时时钟是个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。
