標題: 2440裸機編程之六 實時時鐘 [打印本頁]
作者: aabbcc 時間: 2014-11-12 13:50
標題: 2440裸機編程之六 實時時鐘
實時日歷時鐘(RTC)單元作為S3C2440A 內部一個獨立的功能單元,能夠像鐘表和日歷一樣保存并自動計算時間。它還具有定時報警和產(chǎn)生節(jié)拍的功能。RTC 單元僅需要通過外接一個32. 768 kHz 的晶振來提供時鐘源。

RTC 可以通過備用電池供電,因此,即使系統(tǒng)電源關閉,也可以繼續(xù)工作。RTC 的寄存器保存了一些表示時間的8 位BCD 碼數(shù)據(jù),包括:秒、分、時、日期、星期、月和年。

下面分四部分分別介紹:RTC的顯示,RTC的設置,RTC的節(jié)拍中斷,RTC的報警中斷
一、RTC的顯示
RTCCON用于RTC的控制,其中RTCCON[0]用于控制使能,所以在操作RTC的任何寄存器之前,要使這一位使能,這樣才使操作有效
rBCDYEAR 存放年份值,BCD碼形式
rBCDMON 月
rBCDDATE 日(按月)
rBCDDAY 日(按星期)
rBCDHOUR 小時
rBCDMIN 分
rBCDSEC 秒
RTC的顯示實驗程序:
//********************************************************************
const char week[][10]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
void Main(void)
{
int i;
……硬件初始化……
Uart_Printf("RTC顯示\n\n");
rRTCCON = rRTCCON & ~(0xf) | 0x1; //使能RTC控制
rBCDYEAR = rBCDYEAR & ~(0xff) | 0x99; //設置年份為99年,注意是BCD碼形式,賦值不要越界
rBCDMON = rBCDMON & ~(0x1f) | 0x12; //月
rBCDDATE = rBCDDATE & ~(0x3f) | 0x31; //日(按月)
rBCDDAY = rBCDDAY & ~(0x7) | 0x1; //日(按星期)
rBCDHOUR = rBCDHOUR & ~(0x3f) | 0x23; //小時
rBCDMIN = rBCDMIN & ~(0x7f) | 0x59; //分
rBCDSEC = rBCDSEC & ~(0x7f) | 0x45; //秒
rRTCCON = 0x0; //取消RTC控制使能
temp = rBCDSEC;
while(1)
{
while(rBCDSEC==temp); //等待一秒
temp = rBCDSEC;
Uart_Printf("%2x年%2x月%2x日 %s %2x:%2x:%2x\n",rBCDYEAR,rBCDMON,rBCDDATE,week[rBCDDAY-1],rBCDHOUR,rBCDMIN,rBCDSEC);
}
}
//*******************************************************************
運行結構如圖:

二、RTC的設置
其實就是寫年月日這些寄存器,沒什么復雜的地方
//********************************************************************
const char week[][10]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
void Main(void)
{
int i;
……硬件初始化……
Uart_Printf("RTC設置時間\n\n");
Uart_Printf("按S鍵設定時間 按D鍵顯示時間\n");
do
{
key = Uart_Getch();
if(key=='s' || key=='S') RTC_set();
else if(key=='d' || key=='D') Uart_Printf("%2x年%2x月%2x日 %s %2x:%2x:%2x\n",rBCDYEAR,rBCDMON,rBCDDATE,week[rBCDDAY-1],rBCDHOUR,rBCDMIN,rBCDSEC);
else Uart_Printf("無效的輸入! 按S鍵設定時間 按D鍵顯示時間\n\n");
}
while(1);
}
void RTC_set(void)
{
do
{
Uart_Printf("輸入年份:");
year = Uart_GetIntNum(); //輸入年份
}
while(year>99);
Uart_Printf("年份:%d\n",year);
do
{
Uart_Printf("輸入月份:");
month = Uart_GetIntNum();
}
while(month<1 || month>12);
Uart_Printf("月份:%d\n",month);
do
{
Uart_Printf("輸入日:");
date = Uart_GetIntNum();
}
while(date<1 || date>31);
Uart_Printf("日:%d\n",day);
do
{
Uart_Printf("輸入星期幾(1:星期日、2:星期一......7:星期六):");
day = Uart_GetIntNum();
}
while(day<1 || day>7);
Uart_Printf("%s\n",week[day-1]);
do
{
Uart_Printf("輸入小時:");
hour = Uart_GetIntNum();
}
while(hour>23);
Uart_Printf("小時:%d\n",hour);
do
{
Uart_Printf("輸入分:");
minute = Uart_GetIntNum();
}
while(minute>59);
Uart_Printf("分:%d\n",minute);
do
{
Uart_Printf("輸入秒:");
second = Uart_GetIntNum();
}
while(second>59);
Uart_Printf("秒:%d\n",second);
rRTCCON = rRTCCON & ~(0xf) | 0x1; //使能RTC控制
rBCDYEAR = rBCDYEAR & ~(0xff) | (year/10<<4)+year%10; //設置年份為99年,注意是BCD碼形式,賦值不要越界
rBCDMON = rBCDMON & ~(0x1f) | (month/10<<4)+month%10; //月
rBCDDATE = rBCDDATE & ~(0x3f) | (date/10<<4)+date%10; //日(按月)
rBCDDAY = rBCDDAY & ~(0x7) | 0x1; //日(按星期)
rBCDHOUR = rBCDHOUR & ~(0x3f) | (hour/10<<4)+hour%10; //小時
rBCDMIN = rBCDMIN & ~(0x7f) | (minute/10<<4)+minute%10; //分
rBCDSEC = rBCDSEC & ~(0x7f) | (second/10<<4)+second%10; //秒
rRTCCON = 0x0; //取消RTC控制使能
Uart_Printf("輸入完畢\n");
Uart_Printf("按S鍵設定時間 按D鍵顯示時間 \n");
}
//*******************************************************************

三、RTC的節(jié)拍中斷
節(jié)拍中斷即每個RTC節(jié)拍產(chǎn)生一個中斷
這里用到TICNT寄存器,TICNT[7]用于使能,TICNT[6:0]取值為1~127,其對應的節(jié)拍中斷時間間隔為(TICNT+1)/128
這是RTC的節(jié)拍中斷的實驗程序,間隔時間設為1秒
//********************************************************************
const char week[][10]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
void Main(void)
{
int i;
……硬件初始化……
Uart_Printf("RTC TICK中斷\n\n");
tick_init();
tick_INT_init();
while(1);
}
void tick_init(void) //RTC TICK初始化
{
rRTCCON = 1; //允許設置
rTICNT = 1<<7 | 127 ; //允許TICK中斷,每次中斷時間為: (n+1)/128 * 1秒 ,其中 n = TICNT[6:0]
rRTCCON = 0; //禁止設置
}
void tick_INT_init(void) //RTC報警中斷初始化
{
ClearPending(1<<8); //清除報警中斷標志
pISR_TICK = (U32)tick_ISR; //填入中斷例程 于中斷向量表的 報警中斷向量處
rINTMSK &= ~(1<<8); //禁止屏蔽報警中斷
}
void tick_ISR(void) __irq //RTC報警中斷例程
{
Uart_Printf("當前時間: %2x年%2x月%2x日 %s %2x:%2x:%2x\n",rBCDYEAR,rBCDMON,rBCDDATE,week[rBCDDAY-1],rBCDHOUR,rBCDMIN,rBCDSEC);
ClearPending(1<<8); //清除報警中斷標志
}
//*******************************************************************
結果如圖

四、RTC的報警中斷
報警,其實就像個鬧鐘,一旦當前時間(BCDYEAR……)與報警時間(ALMYEAR ……)匹配,就會引發(fā)中斷
這里用到的寄存器有:
ALMYEAR 報警年份寄存器
ALMMON 月
ALMDATE 日(按月)
ALMHOUR 小時
ALMMIN 分
ALMSEC 秒
RTCALM 決定年月日時分秒這六個寄存器哪些需要使能,比如:如果ALMMON未使能,則在匹配的時候忽略ALMMON的值。
下面是測試報警中斷的程序:
//********************************************************************
const char week[][10]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
void Main(void)
{
int i;
……硬件初始化……
Uart_Printf("RTC報警中斷實驗\n");
alarm_init();
Uart_Printf(" 按S鍵設定時間 按A鍵設定報警時間 按D鍵顯示時間\n");
do
{
key = Uart_Getch();
if(key=='s' || key=='S') RTC_set();
else if(key=='d' || key=='D')
{
Uart_Printf("當前時間: %2x年%2x月%2x日 %s %2x:%2x:%2x\n",rBCDYEAR,rBCDMON,rBCDDATE,week[rBCDDAY-1],rBCDHOUR,rBCDMIN,rBCDSEC);
Uart_Printf("報警時間: %2x年%2x月%2x日 %2x:%2x:%2x\n",rALMYEAR,rALMMON,rALMDATE,rALMHOUR,rALMMIN,rALMSEC);
}
else if(key=='a' || key=='A') RTC_alarm_set();
else Uart_Printf("無效的輸入! 按S鍵設定時間 按A鍵設定報警時間 按D鍵顯示時間\n");
}
while(1);
}
void alarm_init(void) //RTC報警中斷初始化
{
ClearPending(1<<30); //清除報警中斷標志
pISR_RTC = (U32)alarm_ISR; //填入中斷例程 于中斷向量表的 報警中斷向量處
rINTMSK &= ~(1<<30); //禁止屏蔽報警中斷
}
void alarm_ISR(void) __irq //RTC報警中斷例程
{
Uart_Printf("報警時間到!!!\n");
Uart_Printf("報警時間到!!!\n");
Uart_Printf("報警時間到!!!\n");
ClearPending(1<<30); //清除報警中斷標志
}
void RTC_set(void) //RTC當前時間設置
{
Uart_Printf("設置當前時間:\n");
do
{
Uart_Printf("輸入星期幾 (1:星期日、2:星期一......7:星期六):");
day = Uart_GetIntNum(); //輸入星期幾
}
while(day<1 || day>7);
Uart_Printf("%s\n",week[day-1]);
time_input(); //輸入時間:年月日時分秒
rRTCCON = rRTCCON & ~(0xf) | 0x1; //使能RTC控制
rBCDYEAR = rBCDYEAR & ~(0xff) | (year/10<<4)+year%10; //設置年份為99年,注意是BCD碼形式,賦值不要越界
rBCDMON = rBCDMON & ~(0x1f) | (month/10<<4)+month%10; //月
rBCDDATE = rBCDDATE & ~(0x3f) | (date/10<<4)+date%10; //日(按月)
rBCDDAY = rBCDDAY & ~(0x7) | 0x1; //日(按星期)
rBCDHOUR = rBCDHOUR & ~(0x3f) | (hour/10<<4)+hour%10; //小時
rBCDMIN = rBCDMIN & ~(0x7f) | (minute/10<<4)+minute%10; //分
rBCDSEC = rBCDSEC & ~(0x7f) | (second/10<<4)+second%10; //秒
rRTCCON = 0x0; //取消RTC控制使能
Uart_Printf("輸入完畢\n");
Uart_Printf(" 按S鍵設定時間 按A鍵設定報警時間 按D鍵顯示時間\n");
}
void RTC_alarm_set(void) //RTC報警時間設置
{
Uart_Printf("設置報警時間:\n");
time_input(); //輸入時間:年月日時分秒
rRTCCON = rRTCCON & ~(0xf) | 0x1; //使能RTC控制
rALMYEAR = rALMYEAR & ~(0xff) | (year/10<<4)+year%10; //設置年份為99年,注意是BCD碼形式,賦值不要越界
rALMMON = rALMMON & ~(0x1f) | (month/10<<4)+month%10; //月
rALMDATE = rALMDATE & ~(0x3f) | (date/10<<4)+date%10; //日(按月)
// rALMDAY = rALMDAY & ~(0x7) | 0x1; //日(按星期) 報警無此寄存器
rALMHOUR = rALMHOUR & ~(0x3f) | (hour/10<<4)+hour%10; //小時
rALMMIN = rALMMIN & ~(0x7f) | (minute/10<<4)+minute%10; //分
rALMSEC = rALMSEC & ~(0x7f) | (second/10<<4)+second%10; //秒
rRTCCON = 0x0; //取消RTC控制使能
rRTCALM = 0x7F; //開啟全局報警
Uart_Printf("輸入完畢\n");
Uart_Printf(" 按S鍵設定時間 按A鍵設定報警時間 按D鍵顯示時間\n");
}
void time_input(void) //輸入時間:年月日時分秒
{
do
{
Uart_Printf("輸入年份:");
year = Uart_GetIntNum(); //輸入年份
}
while(year>99);
Uart_Printf("年份:%d\n",year);
do
{
Uart_Printf("輸入月份:");
month = Uart_GetIntNum();
}
while(month<1 || month>12);
Uart_Printf("月份:%d\n",month);
do
{
Uart_Printf("輸入日:");
date = Uart_GetIntNum();
}
while(date<1 || date>31);
Uart_Printf("日:%d\n",day);
do
{
Uart_Printf("輸入小時:");
hour = Uart_GetIntNum();
}
while(hour>23);
Uart_Printf("小時:%d\n",hour);
do
{
Uart_Printf("輸入分:");
minute = Uart_GetIntNum();
}
while(minute>59);
Uart_Printf("分:%d\n",minute);
do
{
Uart_Printf("輸入秒:");
second = Uart_GetIntNum();
}
while(second>59);
Uart_Printf("秒:%d\n",second);
}
//*******************************************************************
結果如圖

作者: ahljj 時間: 2015-9-11 19:08
2440裸機編程之六 實時時鐘
歡迎光臨 (http://m.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
牛牛热在线视频
|
亚洲毛片在线观看
|
一区二区福利视频
|
91国内精品久久
|
一级黄色夫妻生活
|
国产精久久久久久久妇剪断
|
久久激情视频
|
69堂永久69tangcom
|
天天玩天天操天天干
|
成人二区
|
中文字幕乱码一区二区三区
|
自拍亚洲|
日韩在线精品
|
精品久久久久久久久久久久久久久久久
|
欧美日韩在线一区二区三区
|
日韩中文一区二区三区
|
亚洲精品一区二区三区在线
|
九九久久久
|
成人做爰9片免费看网站
|
av色噜噜
|
四虎永久影院
|
国产精品高清在线
|
国产亚洲精品久久午夜玫瑰园
|
国产成人久久av免费高清密臂
|
欧美一区不卡
|
手机日韩
|
中文字幕视频在线观看
|
中文字幕一区二区三区不卡
|
国产精品一码二码三码在线
|
91免费福利在线
|
欧美成人综合
|
久久久国产精品视频
|
毛片综合
|
伊人网伊人
|
欧美一区二区三区在线看
|
午夜精品久久久久久久久久久久
|
久久久久久久91
|
一区精品国产欧美在线
|
成人av播放
|
日韩中文一区二区三区
|
国产在线播
|