新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > s3c2440實時時鐘的應用

        s3c2440實時時鐘的應用

        作者: 時間:2016-11-19 來源:網絡 收藏
        實時時鐘RTC)的主要功能是在系統掉電的情況下,利用后備電源使時鐘繼續運行,從而不會丟失時間信息。

        s3c2440內部集成了RTC模塊,而且用起來也十分簡單。其內部的寄存器BCDSEC,BCDMIN,BCDHOUR,BCDDAY,BCDDATE,BCDMON和BCDYEAR分別存儲了當前的秒,分,小時,星期,日,月和年,表示時間的數值都是BCD碼。這些寄存器的內容可讀可寫,并且只有在寄存器RTCCON的第0位為1時才能進行讀寫操作。為了防止誤操作,當不進行讀寫時,要把該位清零。當讀取這些寄存器時,能夠獲知當前的時間;當寫入這些寄存器時,能夠改變當前的時間。另外需要注意的是,因為有所謂的“一秒誤差”,因此當讀取到的秒為0時,需要重新再讀取一遍這些寄存器的內容,才能保證時間的正確。

        下面的程序就是一個簡單的RTC的例子。系統上電,或按鍵時,會在LCD上顯示當前時間的全部信息。并且可以通過UART,在PC機上改變RTC,它們之間的協議為:當PC機發送0xAA時,表示其后的7個數據分別為年、月、日、星期、小時、分和秒,在s3c2440接收到這些數據后,發送0xAA以示確認;當PC機發送其他數據時,對于s3c2440來說沒有任何意義,s3c2440只是把該數據再傳回給PC機。為了簡潔和突出重點,在下面程序中,會省略掉以前文章中介紹過的內容,如不清楚,請翻看本博客中的其他相關內容。


        unsigned char date_buffer[7];//分別表示年、月、日、星期、小時、分、秒
        unsigned char flag;//用于表示更新LCD顯示時間的標志

        //獲取時間
        void get_date(void)
        {
        rRTCCON = 1;

        date_buffer[0] = rBCDYEAR;//年
        date_buffer[1] = rBCDMON;//月
        date_buffer[2] = rBCDDATE;//日
        date_buffer[3] = rBCDDAY;//星期
        date_buffer[4] = rBCDHOUR;//小時
        date_buffer[5] = rBCDMIN;//分
        date_buffer[6] = rBCDSEC;//秒
        //當秒為0時,重新讀取
        if(date_buffer[6]==0)
        {
        date_buffer[0] = rBCDYEAR;//年
        date_buffer[1] = rBCDMON;//月
        date_buffer[2] = rBCDDATE;//日
        date_buffer[3] = rBCDDAY;//星期
        date_buffer[4] = rBCDHOUR;//小時
        date_buffer[5] = rBCDMIN;//分
        date_buffer[6] = rBCDSEC;//秒
        }

        rRTCCON = 0;
        }

        //設置時間
        void set_date(void)
        {
        rRTCCON = 1 ;

        rBCDYEAR = date_buffer[0] ;//年
        rBCDMON= date_buffer[1] ;//月
        rBCDDATE = date_buffer[2] ;//日
        rBCDDAY= date_buffer[3] ;//星期
        rBCDHOUR = date_buffer[4] ;//小時
        rBCDMIN= date_buffer[5] ;//分
        rBCDSEC= date_buffer[6] ;//秒

        rRTCCON = 0 ;
        }

        //在LCD上顯示時間
        void show_date(void)
        {
        unsigned char String[ ]="當前時間:";
        unsigned char String_Y[ ]="年";
        unsigned char String_M[ ]="月";
        unsigned char String_D[ ]="日";

        unsigned char ToWeek[ ][7] = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};

        unsigned char qh,wh;
        const unsigned char *mould;
        int length = sizeof(String);
        int k,xx;

        get_date();//獲取時間

        //在LCD上寫“當前時間:”這幾個字
        for(k=0,xx=0;k{
        qh=String[k]-0xa0;
        wh=String[k+1]-0xa0;
        mould = & __HZK[ (( qh - 1 )*94 + wh- 1 )*32 ];
        Draw_Text16(30+xx,50,0x0f,mould);
        xx+=16;
        k++;
        }

        //在下一行顯示具體的時間,形式如:2010年04月03日星期六21:52:28
        //年
        //人為加上“20”
        mould = & __ASCII[2*16];
        Draw_ASCII(30,70,0x0,mould);
        mould = & __ASCII[0*16];
        Draw_ASCII(38,70,0x0,mould);

        qh=(date_buffer[0]>>4)+48;
        wh=(date_buffer[0]&0x0f)+48;
        mould = & __ASCII[qh*16];
        Draw_ASCII(46,70,0x0,mould);
        mould = & __ASCII[wh*16];
        Draw_ASCII(54,70,0x0,mould);

        qh=String_Y[0]-0xa0;
        wh=String_Y[1]-0xa0;
        mould = & __HZK[ (( qh - 1 )*94 + wh- 1 )*32 ];
        Draw_Text16(62,70,0x0f,mould);

        //月
        qh=(date_buffer[1]>>4)+48;
        wh=(date_buffer[1]&0x0f)+48;
        mould = & __ASCII[qh*16];
        Draw_ASCII(78,70,0x0,mould);
        mould = & __ASCII[wh*16];
        Draw_ASCII(86,70,0x0,mould);

        qh=String_M[0]-0xa0;
        wh=String_M[1]-0xa0;
        mould = & __HZK[ (( qh - 1 )*94 + wh- 1 )*32 ];
        Draw_Text16(94,70,0x0f,mould);

        //日
        qh=(date_buffer[2]>>4)+48;
        wh=(date_buffer[2]&0x0f)+48;
        mould = & __ASCII[qh*16];
        Draw_ASCII(110,70,0x0,mould);
        mould = & __ASCII[wh*16];
        Draw_ASCII(118,70,0x0,mould);

        qh=String_D[0]-0xa0;
        wh=String_D[1]-0xa0;
        mould = & __HZK[ (( qh - 1 )*94 + wh- 1 )*32 ];
        Draw_Text16(126,70,0x0f,mould);

        //星期
        for(k=0,xx=0;k<7-1;k++)
        {
        qh=ToWeek[date_buffer[3]][k]-0xa0;
        wh=ToWeek[date_buffer[3]][k+1]-0xa0;
        mould = & __HZK[ (( qh - 1 )*94 + wh- 1 )*32 ];
        Draw_Text16(142+xx,70,0x0f,mould);
        xx+=16;
        k++;
        }

        //小時
        qh=(date_buffer[4]>>4)+48;
        wh=(date_buffer[4]&0x0f)+48;
        mould = & __ASCII[qh*16];
        Draw_ASCII(194,70,0x0,mould);
        mould = & __ASCII[wh*16];
        Draw_ASCII(202,70,0x0,mould);

        mould = & __ASCII[ :*16 ];
        Draw_ASCII(210,70,0x0f,mould);

        //分
        qh=(date_buffer[5]>>4)+48;
        wh=(date_buffer[5]&0x0f)+48;
        mould = & __ASCII[qh*16];
        Draw_ASCII(218,70,0x0,mould);
        mould = & __ASCII[wh*16];
        Draw_ASCII(226,70,0x0,mould);

        mould = & __ASCII[ :*16 ];
        Draw_ASCII(234,70,0x0f,mould);

        //秒
        qh=(date_buffer[6]>>4)+48;
        wh=(date_buffer[6]&0x0f)+48;
        mould = & __ASCII[qh*16];
        Draw_ASCII(242,70,0x0,mould);
        mould = & __ASCII[wh*16];
        Draw_ASCII(250,70,0x0,mould);
        }

        //按鍵中斷,用于更新LCD上顯示的時間
        void __irq Key4_ISR(void)
        {
        rSRCPND = rSRCPND | 0x1;
        rINTPND = rINTPND | 0x1;
        flag=1;//置標志
        }

        //UART中斷,用于修改時間
        void __irq uartISP(void)
        {
        char ch;
        static char temp;
        static char count;
        rSUBSRCPND |= 0x3;
        rSRCPND |= 0x1<<28;
        rINTPND |= 0x1<<28;

        if(rUTRSTAT0 & 1)//接收數據處理部分
        {

        ch = rURXH0;//接收字節數據
        if(ch==0xaa&&temp==0)//表示接收到修改時間的命令
        {
        temp=1;
        count=0;
        }
        else if(temp==1)//接收時間數據
        {
        date_buffer[count]=ch;//依次存入時間數組內
        count++;
        if(count==7)//7個時間數據全部接收完畢
        {
        rUTXH0=0xaa;//發送0xAA
        set_date();//設置時間
        count=0;
        temp=0;
        flag=1;//更新LCD上顯示的時間
        }
        }
        else
        rUTXH0=ch;//不是接收時間的命令

        }
        }

        void Main(void)
        {
        //初始化寄存器,內容省略
        ……
        Brush_Background(0xffffff);//LCD背景為白色
        show_date();//在LCD上顯示時間

        flag=0;//清標志

        while(1)
        {
        if(flag)//需要更新LCD上的顯示時間
        {
        Brush_Background(0xffffff);
        show_date();
        flag=0;//清標志
        }
        }
        }


        關鍵詞: S3C2440實時時鐘RT

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 沈丘县| 伊金霍洛旗| 栾城县| 白朗县| 探索| 三明市| 达尔| 百色市| 阿克陶县| 大同市| 丰县| 阿拉善右旗| 吉安县| 华阴市| 营山县| 彭州市| 汤阴县| 壤塘县| 谷城县| 濮阳县| 化州市| 修武县| 抚顺县| 林芝县| 临清市| 长宁区| 南投县| 喜德县| 沂南县| 大港区| 林州市| 沿河| 漯河市| 陇西县| 临桂县| 班玛县| 斗六市| 崇文区| 盘山县| 襄汾县| 甘孜|