久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4215|回復: 1
打印 上一主題 下一主題
收起左側

2440裸機編程之六 實時時鐘

[復制鏈接]
跳轉到指定樓層
樓主
ID:68618 發表于 2014-11-12 13:50 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
實時日歷時鐘(RTC)單元作為S3C2440A 內部一個獨立的功能單元,能夠像鐘表和日歷一樣保存并自動計算時間。它還具有定時報警和產生節拍的功能。RTC 單元僅需要通過外接一個32. 768 kHz 的晶振來提供時鐘源。


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


下面分四部分分別介紹:RTC的顯示,RTC的設置,RTC的節拍中斷,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的節拍中斷

節拍中斷即每個RTC節拍產生一個中斷
這里用到TICNT寄存器,TICNT[7]用于使能,TICNT[6:0]取值為1~127,其對應的節拍中斷時間間隔為(TICNT+1)/128
這是RTC的節拍中斷的實驗程序,間隔時間設為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 ……)匹配,就會引發中斷
這里用到的寄存器有:
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);
}
//*******************************************************************
結果如圖

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:45457 發表于 2015-9-11 19:08 | 只看該作者
2440裸機編程之六 實時時鐘
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕乱码一区二区三区 | 91看片视频 | 国产美女h视频 | 国产欧美一区二区在线观看 | 全部免费毛片在线播放网站 | 美国黄色一级片 | 日韩中文一区 | 中文字幕二区 | 第一色在线 | 99精品一级欧美片免费播放 | 日韩免费视频一区二区 | 精品在线观看入口 | 国产一区在线免费 | 日韩欧美国产精品 | 国产日韩欧美另类 | 国产精品地址 | 精品欧美一区二区三区久久久 | 国产精品久久久久久久久久久久 | 黄在线免费观看 | 亚洲欧美一区二区三区在线 | 国产999精品久久久久久绿帽 | 欧美日韩国产免费 | 欧美一级片在线观看 | 亚洲 欧美 在线 一区 | 久久精品黄色 | 在线资源视频 | 精品国产乱码久久久久久丨区2区 | 久久亚洲精品国产精品紫薇 | 中文字字幕在线中文乱码范文 | 51ⅴ精品国产91久久久久久 | 日中文字幕在线 | 在线观看电影av | 激情国产在线 | 夜夜草av | 亚洲一区二区三区在线免费 | 天堂久久网 | 亚洲一区亚洲二区 | 在线欧美亚洲 | 日韩在线播放第一页 | 人人干在线 | 久草免费视 |