RTC_ALARM 的中断id为76
他的寄存器配置这一坨和上面的BCD... 寄存器格局一模一样,往里面写值就等于设置了警报时间了
清除RTC中断挂起
rtc_alarm
pwm.h
#ifndef __PWM_H__
#define __PWM_H__
//pwm 初始化
void pwm_init();
//启动pwm
void pwm_start();
//关闭pwm
void pwm_stop();
#endif
pwm.c
#include"exynos_4412.h"
//pwm 初始化
void pwm_init(){
//配置GPD0_0 为pwm功能
GPD0.CON = (GPD0.CON & ~(0xf<<0)) | (2<<0);
//配置pwm控制器,五路固定分频 TCFG1 [3:0] = 0 这里设不固定分频
PWM.TCFG1 &= ~(0xf);
//频率 = 总线时钟 /固定分频/ (分频值+1) / 重载值 ;
//两路预分频 TCFG0 [7:0] = 99 100M/(99+1) = 1M
PWM.TCFG0 = (PWM.TCFG0 & ~(0xff<<0)) | (99<<0);
//重载值
PWM.TCNTB0 = 2000;
//比较寄存器 占空比 = 比较寄存器/重载值
PWM.TCMPB0 = 1000;
//配置总控
//不使能死区
PWM.TCON &= ~(1<<4);
//自动重装
PWM.TCON |= 1<<3;
//打开输出
PWM.TCON |= 1<<2;
//装载TCNTB0 TCMPB0
PWM.TCON |= 1<<1;
//关闭装载
PWM.TCON &= ~(1<<1);
}
//启动pwm
void pwm_start(){
//启动pwm
PWM.TCON |= 1;
}
//关闭pwm
void pwm_stop(){
//启动pwm
PWM.TCON &= ~1;
}
rtc.h
#ifndef __RTC_H__
#define __RTC_H__
/*
* 启动/停止 闹钟对应的位,年月日时分秒
*
* */
#define SEC_EABLE 0
#define SEC_DISABLE 1
#define MIN_EABLE 2
#define MIN_DISABLE 3
#define HOUR_EABLE 4
#define HOUR_DISABLE 5
#define DAY_EABLE 6
#define DAY_DISABLE 7
#define MON_EABLE 8
#define MON_DISABLE 9
#define YEAR_EABLE 10
#define YEAR_DISABLE 11
#define ALL_DISABLE 12
typedef struct
{ //均是用BCD码表示
unsigned int bcdyear; // 3位十进制数有效
unsigned char bcdmon; // 1-12
unsigned char bcdday; // 1-31
unsigned char bcdhour; // 0-23
unsigned char bcdmin; // 0-59
unsigned char bcdsec; // 0-59
unsigned char bcdweek; // 1-7
}bcd_time_struct;
//初始化RTC
void rtc_init(unsigned int bcdyear,unsigned char bcdmon,
unsigned char bcdday,unsigned char bcdhour,
unsigned char bcdmin,unsigned char bcdsec,
unsigned char bcdweek);
//读取RTC 时钟
void rtc_get_time(bcd_time_struct *bcd_struct);
//结构体元素的值初始化 即设置报警时间
void bcd_time_struct_init(bcd_time_struct *bcd_struct,
unsigned int bcdyear,unsigned char bcdmon,
unsigned char bcdday,unsigned char bcdhour,
unsigned char bcdmin,unsigned char bcdsec,
unsigned char bcdweek);
//rtc_alarm_init 警报功能初始化
void rtc_alarm_init(bcd_time_struct* bcd_struct);
//警报中断初始化
void rtc_alarm_interrupt_start(unsigned char flag);
//警报中断清除挂起
void rtc_alarm_interrupt_clear(void);
#endif
rtc.c
#include"exynos_4412.h"
#include "rtc.h"
//初始化RTC
void rtc_init(unsigned int bcdyear,unsigned char bcdmon,
unsigned char bcdday,unsigned char bcdhour,
unsigned char bcdmin,unsigned char bcdsec,
unsigned char bcdweek){
//使能RTC控制器
RTCCON |= 0x1;
//设置年月日,时分秒
RTC.BCDSEC = bcdsec;
RTC.BCDMIN = bcdmin;
RTC.BCDHOUR = bcdhour;
//注意芯片手册的星期和地址是反的,它写错了,所以我们只好反着写
RTC.BCDWEEK = bcdday; //设置日
RTC.BCDDAY = bcdweek;//设置星期
RTC.BCDMON = bcdmon;
RTC.BCDYEAR = bcdyear;
RTCCON &= ~(1);// 关闭RTC控制器使能
}
//读取RTC 时钟
void rtc_get_time(bcd_time_struct *bcd_struct)
{
if(bcd_struct != (void *)0)
{
bcd_struct->bcdyear = RTC.BCDYEAR;
bcd_struct->bcdmon = RTC.BCDMON;
bcd_struct->bcdday = RTC.BCDWEEK;//这里读出来的是日
bcd_struct->bcdhour = RTC.BCDHOUR;
bcd_struct->bcdmin = RTC.BCDMIN;
bcd_struct->bcdsec = RTC.BCDSEC;
bcd_struct->bcdweek = RTC.BCDDAY; //这里读出来的是星期
}
}
//结构体元素的值初始化 即设置报警时间
void bcd_time_struct_init(bcd_time_struct *bcd_struct,
unsigned int bcdyear,unsigned char bcdmon,
unsigned char bcdday,unsigned char bcdhour,
unsigned char bcdmin,unsigned char bcdsec,
unsigned char bcdweek){
bcd_struct->bcdyear = bcdyear;
bcd_struct->bcdmon = bcdmon;
bcd_struct->bcdday = bcdday;
bcd_struct->bcdhour = bcdhour;
bcd_struct->bcdmin = bcdmin;
bcd_struct->bcdsec = bcdsec;
bcd_struct->bcdweek = bcdweek;
}
//rtc_alarm_init 警报功能初始化 将报警时间设置经RTCALM寄存器
void rtc_alarm_init(bcd_time_struct* bcd_struct)
{
RTCALM.SEC = bcd_struct->bcdsec;
RTCALM.MIN = bcd_struct->bcdmin;
RTCALM.HOUR= bcd_struct->bcdhour;
RTCALM.DAY = bcd_struct->bcdday;
RTCALM.MON = bcd_struct->bcdmon;
RTCALM.YEAR= bcd_struct->bcdyear;
}
//警报中断初始化
void rtc_alarm_interrupt_start(unsigned char flag)
{
//设置寄存器RTCALM.ALM 第[6]位置1,闹钟使能
RTCALM.ALM = (0x1 << 6);
//GIC 面向中断源
//开启总中断
ICDDCR = ICDDCR | 0x1;
//配置端口中断使能
ICDISER.ICDISER2 = ICDISER.ICDISER2 | (0x1 << 12);
//配置端口优先级 优先级设置为5 rtc_alarm 中断id 76
ICDIPR.ICDIPR19 = (ICDIPR.ICDIPR19 & ~(0xff<<0)) | (5<<0);
//配置中断源送去哪个cpu处理 0x1表示直送cpu0
ICDIPTR.ICDIPTR19 = ICDIPTR.ICDIPTR19 & (~(0xFF << 0)) | (0x1 << 0);
//GIC 面向cpu
//cpu响应中断使能 =1 使能 =0 不使能
CPU0.ICCICR = CPU0.ICCICR | 0x1;
//配置cpu过滤优先级
CPU0.ICCPMR = CPU0.ICCPMR | 255;
//启动RTC
RTCCON = RTCCON | 0x1;
//选择哪一位使能,哪个就一到时间就报警
switch(flag)
{
case SEC_EABLE:
RTCALM.ALM |= (0x3 << 0);//使能
break;
case SEC_DISABLE:
RTCALM.ALM &= ~ (0x1 << 0);//不使能
break;
case MIN_EABLE:
RTCALM.ALM |= (0x1 << 1);
break;
case MIN_DISABLE:
RTCALM.ALM &= ~ (0x1 << 1);
break;
case HOUR_EABLE:
RTCALM.ALM |= (0x1 << 2);
break;
case HOUR_DISABLE:
RTCALM.ALM &= ~ (0x1 << 2);
break;
case DAY_EABLE:
RTCALM.ALM |= (0x1 << 3);
break;
case DAY_DISABLE:
RTCALM.ALM &= ~ (0x1 << 3);
break;
case MON_EABLE:
RTCALM.ALM |= (0x1 << 4);
break;
case MON_DISABLE:
RTCALM.ALM &= ~(0x1 << 4);
break;
case YEAR_EABLE:
RTCALM.ALM |= (0x1 << 5);
break;
case YEAR_DISABLE:
RTCALM.ALM &= ~ (0x1 << 5);
break;
case ALL_DISABLE:
RTCALM.ALM |= (0x3f << 0);//打开各个位都使能
break;
default:
RTCALM.ALM = 0 ;
}
}
//警报中断清除挂起
void rtc_alarm_interrupt_clear(void)
{
RTCINTP = RTCINTP | (0x1 << 1); //清RTC中断标志位
ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 | (0x1 << 12); //清除GIC中断标志位
}
main.c
#include"exynos_4412.h"
#include"uart.h"
#include "rtc.h"
#include "pwm.h"
//使用rtc的警报功能
//延时
void delay(unsigned int msec)
{
unsigned int i,j;
while(msec --)
{
for(i=0;i<5;i++)
for(j=0;j<512;j++);
}
}
//中断处理函数
void do_irq(void)
{
unsigned int irq_num;
irq_num = CPU0.ICCIAR & 0x3FF; //获取中断号
switch(irq_num)
{
case 76: //警报
rtc_alarm_interrupt_clear();
printf("time over!\r\n");
pwm_start();
break;
}
// CPU0.ICCEOIR = CPU0.ICCEOIR & (~(0x3FF)) | irq_num; //清cpu中断标志位
//最后清除cpu中断挂起
//写入中断id清除对应中断挂起
CPU0.ICCEOIR = irq_num;
}
int main()
{
int a = 100;
uart_init();
printf("hello!a=%d\r\n",a);
//定义个结构体类型
bcd_time_struct tm;
//初始化RTC时钟 起到校验作用
rtc_init(0x023,0x12,0x13,0x22,0x55,0x30,0x3);
//警报值初始化
bcd_time_struct tm2;
bcd_time_struct_init(&tm2,0x023,0x12,0x13,0x22,0x56,0x35,0x3);
rtc_alarm_init(&tm2);
//开启警报中断初始化
rtc_alarm_interrupt_start(12);
//蜂鸣器初始化
pwm_init();
while(1){
rtc_get_time(&tm);
//打印实时时钟
//%03x 保留3位 如果不足三位用0来补充
printf("time:2%03x/%x/%x,%x:%x:%x,week:%x \r\n",tm.bcdyear,tm.bcdmon,
tm.bcdday,tm.bcdhour,tm.bcdmin,tm.bcdsec,tm.bcdweek);
delay(1000);
}
return 0;
}