//***************************************************************
//manymany-2440裸机篇之4 rtc实时时钟
//***************************************************************
//目的:掌握rtc实时时钟功能,每秒显示实时时钟
// 实现实时闹钟功能,掌握控制rtc各个寄存器
//***************************************************************
//功能:每秒显示实时时钟,能读取年,月,日,星期,时,分,秒
// 实现闹钟功能,控制蜂鸣器响灭。
//***************************************************************
//***************************************************************
//这是一个很实用的模块,现在先用串口显示,等过段时间写到液晶显示再
//改换液晶显示,那样更直观明了。
//***************************************************************
// 共两个c文件 这个为rtc.c,另一个为rtcalarm.c
//***************************************************************
#include "2440lib.h"
#include "2440addr.h"
extern void setrtctime(u8,u8,u8,u8,u8,u8,u8);
extern void setrtcalm(u8,u8,u8,u8,u8,u8);
extern void openalarm(void);
extern void openalarm(void);
extern void openrtc(void);
extern void alarm(void);
//******************************************************************
void xmain(void) //主函数 在这里主要讨论rtc寄存器的使用,其他的不深究
{
changeclockdivider(3,1);
changempllvalue(127,2,1); //405mhz
rgpbcon="0x155555";
isr_init(); //中断初始化
uart_init(0, 115200); //串口初始化
uart_select(0); //串口选择
uart_printf("the main is running\n"); //打印显示
//以下这两个函数用来设置系统开始时间和闹钟时间
//注意bcdyaer寄存器的8和9不能用08和09代替
setrtcalm(9,05,17,11,50,30); //年、月、日、时、分、秒
setrtctime(9,05,16,5,12,35,01); //年、月、日、星期、时、分、秒
openalarm(); //开闹钟功能
openrtc(); //开rtc时钟
alarm(); //判断闹钟是否到时间,蜂鸣器的响与停
while(1);
}
//**************************************************************
//以下为rtcalarm.c
//**************************************************************
#include "2440lib.h"
#include "2440addr.h"
char *week[8] = { "","sun","mon", "tues", "wed",
"thurs","fri", "sat" } ; //星期的数组
int year, month,date,weekday,hour,min,sec;
int beep = 1; //闹钟用的蜂鸣器的标志位,初始化为1,不响
extern void buzzer_pwm_run(void);
extern char *week[8];
void closealarm(void);
//********************************************************************
void get_rtc(void) //读出当前的时间函数
{
rrtccon = 0x01; //rtc读写使能,选择bcd时钟、计数器,无复位
if (rbcdyear == 0x99) //判断具体年份,因为8位寄存器只能保存0-255
year = 0x1999;
else
year = 0x2000 rbcdyear;
month="rbcdmon"; //读取年,月,日,时,分,秒各个寄存器的数据。
date="rbcddate";
weekday="rbcdday";
hour="rbcdhour";
min="rbcdmin";
sec="rbcdsec";
rrtccon = 0x0;
//rtc读写禁止,选择bcd时钟、计数器,无复位
}
//******************************************************************************
// 利用中断,进行实时时钟rtc和闹钟的进行
//***************************************************************************
void __irq tickint_handler(void) //rtc中断服务函数
{
get_rtc(); //读出当前的时间函数
//串口打印,显示当前时间,在这里我们先用串口显示,
//等做到液晶的时候,我们再用液晶代替串口,可能直观点。
uart_printf("rtc time : %4x-x-x - %s - x:x:%
02x\n",year,month,date,week[weekday],hour,min,sec);
clearpending(bit_tick); //清除tick中断函数。即分别往rsrcpnd,
// rintpnd的tick位置1即可。
}
void __irq isralarm(void) //利用中断,闹钟实时进行中断函数
{
clearpending(bit_rtc); //srcpnd,intpnd分别置1.
uart_printf("mini2440 rtcalm oucer \n");
beep = 0; // 蜂鸣器标志位清0
closealarm(); //关闹钟,即如果要开闹钟的先要把它关了,再开。
}
//******************************************************************************
//设置rtc alarm 时间
void setrtcalm(u8 almyear,u8 almmon,u8 almdate,
u8 almhour,u8 almmin,u8 almsec)//年、月、日、时、分、秒
{ rrtccon="0x0001"; //rtccon实时时钟控制寄存器,
//【0】位rtc使能信号控制位,0为禁止,1为允许
//对rtc模块进行读写操作前应对其最低位至1
ralmyear = almyear;
ralmmon = almmon;
ralmdate = almdate;
ralmhour = almhour;
ralmmin = almmin;
ralmsec = almsec;
rrtccon = 0; //读取数据完后禁止使能信号,以防误操作,
//整个文件的设置都一样,不重覆
}
//置时钟定时时间
void setrtctime(u8 wrtcyear,u8 wrtcmon,u8 wrtcdate,
u8 wrtcday,u8 wrtchour,u8 wrtcmin,u8 wrtcsec)
//年、月、日、星期、时、分、秒
{
rrtccon=0x01;
rbcdyear = wrtcyear;
rbcdmon = wrtcmon;
rbcddate = wrtcdate;
rbcdday = wrtcday;
rbcdhour = wrtchour;
rbcdmin = wrtcmon;
rbcdsec = wrtcsec;
rrtccon = 0x00;
}
//****************************************************************************
//时钟和闹钟的开关操作函数:
//openrtc(); //rtc开函数 closertc(); //rtc关函数
//openalarm():开闹钟功能函数 closealarm():关闹钟功能函数
//****************************************************************************
//rtc开
void openrtc(void)
{
pisr_tick=(unsigned)tickint_handler; //执行rtc中断服务函数
rticnt="0xff"; //ticnt该寄存器用于是否允许时间滴答中断和时间中断的计数值。
//ticnt[7]为0,禁止,为1,使能。
//ticnt[6:0]时间滴答计数值,1-127,自动递减,不能读取其实时数值。
enableirq(bit_tick); //开rtc中断服务
}
//rtc关
void closertc(void)
{
rticnt &= ~(1<<7); //禁止ticnt
disableirq(bit_tick); //关rtc中断服务
}
//开闹钟功能函数
void openalarm()
{
pisr_rtc = (unsigned)isralarm; //中断寄存器isr中的rtc中断位
clearpending(bit_rtc);
rrtcalm = (0x7f); //rtcalm闹钟控制寄存器,
//【0-7】分别对应秒到年的闹钟 使能,
//相应位0表示禁止,1表示允许
enableirq(bit_rtc); //开中断
}
//关闹钟功能函数
void closealarm(void)
{
rrtcalm = 0; //rtcalm闹钟控制寄存器所有位禁止
disableirq(bit_rtc); //关中断
}
//****************************************************************************
void alarm() //判断闹钟是否到时间,蜂鸣器的响与停
{
if(beep) //如果标志位为1,则没有到时间
{
rgpbdat &=~(1<<0); //蜂鸣器不响
delay(1000);
}
else //如果标志位为0,则到时间
{
rgpbdat |=(1<<0); //蜂鸣器响
delay(1000);
}
}
『本文转载自网络,u球体育app下载的版权归原作者所有,如有侵权请联系删除』