程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> S3C2440 裸機時鐘RTC

S3C2440 裸機時鐘RTC

編輯:C++入門知識

實時時鐘(RTC)單元可以在當系統電源關閉後通過備用電池工作。RTC可以通過使用STRB/LDRB ARM操
作發送8位二-十進制交換碼(BCD)值數據給CPU。這些數據包括年、月、日、星期、時、分和秒的時間信息。
RTC 單元工作在外部32.768kHz晶振並且可以執行鬧鐘功能。

 

RTC操作比較簡

\

單,寄存器的設置在數據手冊上寫的很詳細,就不寫了,貼一個RTC代碼,該程序參考了天翔的RTC程序代碼,主要是他寫的比較好,都模塊化了,我修改了他的代碼,有鬧鐘(利用蜂鳴器),在TQ2440 板子上能運行,程序功能:串口每秒顯示一次時間並且LED1閃一次,在鬧鐘設置中,秒為20時,顯示鬧鐘時間並蜂鳴器發聲幾秒鐘。




#include "2440addr.h"   
#include "Option.h"   
#include "2440lib.h"   
#include "def.h"   
  
#define  LED1_ON    (rGPBDAT &=~(1<<5))   
#define  LED1_OFF   (rGPBDAT |=(1<<5) )   
  
void __irq RTC_tickHandler(void);  
void __irq RTC_alarmHandler(void);  
  
  
U8 alarmflag=0;  
  
typedef struct Date //定義一個表示日期時間的結構體   
    {   U16 year;  
        U8 month;  
        U8 day;  
        U8 week_day;  
        U8 hour;  
        U8 minute;  
        U8 second;  
    }date;  
      
date C_date;      
char *week_num[7]={ "SUN","MON", "TUES", "WED", "THURS","FRI", "SAT" };//定義一個指針數組   
  
void Beep_Freq_Set( U32 freq )  
{  
  
    rGPBCON &=~3;  
    rGPBCON |=2;        //設置GPB0為OUT0   
  
    rGPBUP=0x0;     //使能上拉   
  
    rTCFG0 &=~0xff;  
    rTCFG0 |=15;        //預分頻值為15   
      
    rTCFG1 &=~0x0f;  
    rTCFG1 |=0x02;  //分頻值為8   
      
    rTCNTB0 = (PCLK>>7)/freq; //設定定時器0計數緩沖器的值      
    rTCMPB0 = rTCNTB0>>1;     // 定時器0比較緩沖器的值,PWM輸出占空比50%      
    
    rTCON &= ~0x1f;    
    rTCON |= 0xb;   //自動重載,關閉變相,手動更新,開啟定時器0      
    rTCON &= ~2;            //清除手動更新位      
}    
    
void Beep_Stop( void )    
{    
    rGPBCON &= ~3;          //set GPB0 as output      
    rGPBCON |= 1;    
    rGPBDAT &= ~1;       //輸出低電平      
}    
  
void delay(int x)  
{  
    int i,j;  
    for(i=0;i<x;i++)  
    for(j=0;j<1000000;j++);  
}  
/******************************** 
* 
*   設置實時時鐘日期、 時間 
* 
*********************************/  
void RTC_setdate(date *p_date)  
{  
    rRTCCON=0x01;   //RTC讀寫使能,BCD時鐘、計數器、無復位   
      
    rBCDYEAR = p_date->year;  
    rBCDMON = p_date->month;  
    rBCDDATE = p_date->day;  
    rBCDDAY = p_date->week_day;  //設置日期時間   
    rBCDHOUR = p_date->hour;  
    rBCDMIN = p_date->minute;  
    rBCDSEC = p_date->second;  
      
    rRTCCON=0x00;   //RTC讀寫禁止,BCD時鐘、計數器、無復位   
}  
  
/******************************** 
* 
*   讀取實時時鐘日期、 時間 
* 
*********************************/  
void RTC_getdate(date *p_date)  
{  
    rRTCCON=0x01;   //RTC讀寫使能,BCD時鐘、計數器、無復位   
          
    p_date->year = rBCDYEAR+0x2000;  
    p_date->month = rBCDMON;  
    p_date->day = rBCDDATE;  
    p_date->week_day = rBCDDAY;  //讀取日期時間   
    p_date->hour = rBCDHOUR;  
    p_date->minute = rBCDMIN;  
    p_date->second = rBCDSEC;      
  
    rRTCCON=0x00;   //RTC讀寫禁止,BCD時鐘、計數器、無復位   
}  
  
/******************************** 
* 
*   TICK中斷初始化 
* 
*********************************/  
void RTC_tickIRQ_Init(U8 tick)  
{  
    ClearPending(BIT_TICK); //清除標志位   
    EnableIrq(BIT_TICK);    //使能中斷源   
      
    pISR_TICK=(unsigned)RTC_tickHandler;    //中斷函數入口地址   
      
    rRTCCON=0x00;  
      
    rTICNT=(tick&0x7f)|0x80;    //使能中斷   
}  
  
/******************************** 
* 
*   設置鬧鐘日期、 時間及其鬧鐘喚醒模式 
* 
*********************************/  
void RTC_alarm_setdate(date *p_date,U8 mode)  
{  
    rRTCCON = 0x01;  
      
    rALMYEAR = p_date->year;  
    rALMMON = p_date->month;  
    rALMDATE = p_date->day;    
    rALMHOUR = p_date->hour;  
    rALMMIN = p_date->minute;  
    rALMSEC = p_date->second;  
    rRTCALM = mode;     //RTC鬧鐘控制寄存器   
      
    rRTCCON = 0x00;  
      
    ClearPending(BIT_RTC); //清除標志位                     
    EnableIrq(BIT_RTC); //open RTC alarm  INTERRUPT   
      
    pISR_RTC = (unsigned)RTC_alarmHandler;  
}  
  
void Main(void)  
{  
  
    SelectFclk(2);  //設置系統時鐘 400M        
    ChangeClockDivider(2, 1);      //設置分頻 1:4:8   
    CalcBusClk();           //計算總線頻率   
      
    rGPHCON &=~((3<<4)|(3<<6));     
    rGPHCON |=(2<<4)|(2<<6);    //GPH2--TXD[0];GPH3--RXD[0]        
    rGPHUP=0x00;        //使能上拉功能   
          
    Uart_Init(0,115200);  
    Uart_Select(0);  
      
    rGPBCON &=~((3<<10)|(3<<12)|(3<<14)|(3<<16));   //對GPBCON[10:17]清零   
    rGPBCON |=((1<<10)|(1<<12)|(1<<14)|(1<<16));    //設置GPB5~8為輸出   
    rGPBUP &=~((1<<5)|(1<<6)|(1<<7)|(1<<8));        //設置GPB5~8的上拉功能   
    rGPBDAT |=(1<<5)|(1<<6)|(1<<7)|(1<<8);          //關閉LED   
      
    Beep_Stop();    //蜂鳴器停止發聲,蜂鳴器用作鬧鐘聲   
      
    C_date.year = 0x12;  
    C_date.month = 0x05;  
    C_date.day = 0x09;  
    C_date.week_day = 0x03; //設置當前日期時間   
    C_date.hour = 0x12;  
    C_date.minute = 0x00;  
    C_date.second = 0x10;     
      
    RTC_setdate(&C_date);  
      
    C_date.second=0x20;  
      
    RTC_alarm_setdate(&C_date,0x41);//0x41表示使能RTC鬧鐘,以及使能秒時鐘鬧鐘   
      
    RTC_tickIRQ_Init(127);          // 設置1秒鐘tick一次   
      
      
    Uart_Printf("\n ---實時時鐘測試程序---\n");  
    while(Uart_GetKey()!= ESC_KEY)  
    {  
        LED1_OFF;  
        RTC_getdate(&C_date);  
        if(alarmflag)  
        {  
            alarmflag=0;  
          
            Uart_Printf("\nRTC ALARM  %02x:%02x:%02x \n",C_date.hour,C_date.minute,C_date.second);  
            Beep_Freq_Set(1000);  
            delay(5);  
            Beep_Stop();  
        }  
    }  
  
}  
  
/******************************** 
* 
*   TICK中斷 
* 
*********************************/  
void __irq RTC_tickHandler(void)  
{  
    ClearPending(BIT_TICK);  
    LED1_ON;   //刷新LED1   
    Delay(500);  
    RTC_getdate(&C_date);  
    Uart_Printf("RTC TIME: %04x-%02x-%02x  %s %02x:%02x:%02x\n", C_date.year,C_date.month,C_date.day,week_num[C_date.week_day], C_date.hour, C_date.minute, C_date.second );  
      
}   
  
/******************************** 
* 
*   TICK中斷 
* 
*********************************/  
void __irq RTC_alarmHandler(void)  
{  
   alarmflag = 1;  
   ClearPending(BIT_RTC);  
}  
#include "2440addr.h"   
#include "Option.h"   
#include "2440lib.h"   
#include "def.h"   
  
#define  LED1_ON    (rGPBDAT &=~(1<<5))   
#define  LED1_OFF   (rGPBDAT |=(1<<5) )   
  
void __irq RTC_tickHandler(void);  
void __irq RTC_alarmHandler(void);  
  
  
U8 alarmflag=0;  
  
typedef struct Date //定義一個表示日期時間的結構體   
    {   U16 year;  
        U8 month;  
        U8 day;  
        U8 week_day;  
        U8 hour;  
        U8 minute;  
        U8 second;  
    }date;  
      
date C_date;      
char *week_num[7]={ "SUN","MON", "TUES", "WED", "THURS","FRI", "SAT" };//定義一個指針數組   
  
void Beep_Freq_Set( U32 freq )  
{  
  
    rGPBCON &=~3;  
    rGPBCON |=2;        //設置GPB0為OUT0   
  
    rGPBUP=0x0;     //使能上拉   
  
    rTCFG0 &=~0xff;  
    rTCFG0 |=15;        //預分頻值為15   
      
    rTCFG1 &=~0x0f;  
    rTCFG1 |=0x02;  //分頻值為8   
      
    rTCNTB0 = (PCLK>>7)/freq; //設定定時器0計數緩沖器的值      
    rTCMPB0 = rTCNTB0>>1;     // 定時器0比較緩沖器的值,PWM輸出占空比50%      
    
    rTCON &= ~0x1f;    
    rTCON |= 0xb;   //自動重載,關閉變相,手動更新,開啟定時器0      
    rTCON &= ~2;            //清除手動更新位      
}    
    
void Beep_Stop( void )    
{    
    rGPBCON &= ~3;          //set GPB0 as output      
    rGPBCON |= 1;    
    rGPBDAT &= ~1;       //輸出低電平      
}    
  
void delay(int x)  
{  
    int i,j;  
    for(i=0;i<x;i++)  
    for(j=0;j<1000000;j++);  
}  
/******************************** 
* 
*   設置實時時鐘日期、 時間 
* 
*********************************/  
void RTC_setdate(date *p_date)  
{  
    rRTCCON=0x01;   //RTC讀寫使能,BCD時鐘、計數器、無復位   
      
    rBCDYEAR = p_date->year;  
    rBCDMON = p_date->month;  
    rBCDDATE = p_date->day;  
    rBCDDAY = p_date->week_day;  //設置日期時間   
    rBCDHOUR = p_date->hour;  
    rBCDMIN = p_date->minute;  
    rBCDSEC = p_date->second;  
      
    rRTCCON=0x00;   //RTC讀寫禁止,BCD時鐘、計數器、無復位   
}  
  
/******************************** 
* 
*   讀取實時時鐘日期、 時間 
* 
*********************************/  
void RTC_getdate(date *p_date)  
{  
    rRTCCON=0x01;   //RTC讀寫使能,BCD時鐘、計數器、無復位   
          
    p_date->year = rBCDYEAR+0x2000;  
    p_date->month = rBCDMON;  
    p_date->day = rBCDDATE;  
    p_date->week_day = rBCDDAY;  //讀取日期時間   
    p_date->hour = rBCDHOUR;  
    p_date->minute = rBCDMIN;  
    p_date->second = rBCDSEC;      
  
    rRTCCON=0x00;   //RTC讀寫禁止,BCD時鐘、計數器、無復位   
}  
  
/******************************** 
* 
*   TICK中斷初始化 
* 
*********************************/  
void RTC_tickIRQ_Init(U8 tick)  
{  
    ClearPending(BIT_TICK); //清除標志位   
    EnableIrq(BIT_TICK);    //使能中斷源   
      
    pISR_TICK=(unsigned)RTC_tickHandler;    //中斷函數入口地址   
      
    rRTCCON=0x00;  
      
    rTICNT=(tick&0x7f)|0x80;    //使能中斷   
}  
  
/******************************** 
* 
*   設置鬧鐘日期、 時間及其鬧鐘喚醒模式 
* 
*********************************/  
void RTC_alarm_setdate(date *p_date,U8 mode)  
{  
    rRTCCON = 0x01;  
      
    rALMYEAR = p_date->year;  
    rALMMON = p_date->month;  
    rALMDATE = p_date->day;    
    rALMHOUR = p_date->hour;  
    rALMMIN = p_date->minute;  
    rALMSEC = p_date->second;  
    rRTCALM = mode;     //RTC鬧鐘控制寄存器   
      
    rRTCCON = 0x00;  
      
    ClearPending(BIT_RTC); //清除標志位                     
    EnableIrq(BIT_RTC); //open RTC alarm  INTERRUPT   
      
    pISR_RTC = (unsigned)RTC_alarmHandler;  
}  
  
void Main(void)  
{  
  
    SelectFclk(2);  //設置系統時鐘 400M        
    ChangeClockDivider(2, 1);      //設置分頻 1:4:8   
    CalcBusClk();           //計算總線頻率   
      
    rGPHCON &=~((3<<4)|(3<<6));     
    rGPHCON |=(2<<4)|(2<<6);    //GPH2--TXD[0];GPH3--RXD[0]        
    rGPHUP=0x00;        //使能上拉功能   
          
    Uart_Init(0,115200);  
    Uart_Select(0);  
      
    rGPBCON &=~((3<<10)|(3<<12)|(3<<14)|(3<<16));   //對GPBCON[10:17]清零   
    rGPBCON |=((1<<10)|(1<<12)|(1<<14)|(1<<16));    //設置GPB5~8為輸出   
    rGPBUP &=~((1<<5)|(1<<6)|(1<<7)|(1<<8));        //設置GPB5~8的上拉功能   
    rGPBDAT |=(1<<5)|(1<<6)|(1<<7)|(1<<8);          //關閉LED   
      
    Beep_Stop();    //蜂鳴器停止發聲,蜂鳴器用作鬧鐘聲   
      
    C_date.year = 0x12;  
    C_date.month = 0x05;  
    C_date.day = 0x09;  
    C_date.week_day = 0x03; //設置當前日期時間   
    C_date.hour = 0x12;  
    C_date.minute = 0x00;  
    C_date.second = 0x10;     
      
    RTC_setdate(&C_date);  
      
    C_date.second=0x20;  
      
    RTC_alarm_setdate(&C_date,0x41);//0x41表示使能RTC鬧鐘,以及使能秒時鐘鬧鐘   
      
    RTC_tickIRQ_Init(127);          // 設置1秒鐘tick一次   
      
      
    Uart_Printf("\n ---實時時鐘測試程序---\n");  
    while(Uart_GetKey()!= ESC_KEY)  
    {  
        LED1_OFF;  
        RTC_getdate(&C_date);  
        if(alarmflag)  
        {  
            alarmflag=0;  
          
            Uart_Printf("\nRTC ALARM  %02x:%02x:%02x \n",C_date.hour,C_date.minute,C_date.second);  
            Beep_Freq_Set(1000);  
            delay(5);  
            Beep_Stop();  
        }  
    }  
  
}  
  
/******************************** 
* 
*   TICK中斷 
* 
*********************************/  
void __irq RTC_tickHandler(void)  
{  
    ClearPending(BIT_TICK);  
    LED1_ON;   //刷新LED1   
    Delay(500);  
    RTC_getdate(&C_date);  
    Uart_Printf("RTC TIME: %04x-%02x-%02x  %s %02x:%02x:%02x\n", C_date.year,C_date.month,C_date.day,week_num[C_date.week_day], C_date.hour, C_date.minute, C_date.second );  
      
}   
  
/******************************** 
* 
*   TICK中斷 
* 
*********************************/  
void __irq RTC_alarmHandler(void)  
{  
   alarmflag = 1;  
   ClearPending(BIT_RTC);  
}  

\

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved