新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于PIC16F877A的萬年歷程序

        基于PIC16F877A的萬年歷程序

        作者: 時間:2016-11-13 來源:網絡 收藏
        本代碼在Proteus上仿真通過,在單片機上也測試成功,暫時還未加入更改時間的模塊,有時間會加入的,另外有關如何將公歷轉為農歷,請參閱http://www.qylk.blog.163.com/blog/static/13468735620108284232791/

        另外還可參考他人一篇博文,寫的挺多的:http://wujieflash.blog.163.com/blog/static/5024751920080226525471/

        本文引用地址:http://www.104case.com/article/201611/316254.htm

        代碼包下載:http://qylk2011.googlecode.com/files/time.rar

        代碼如下:

        //使用4M晶振

        #include
        __CONFIG(XT&WDTDIS);
        #define Rssp_On 0x3f//顯示開指令
        #define Rssp_Off 0x3e//顯示關指令
        #define Col_Add 0x40//列
        #define Page_Add 0xb8//頁
        #define Start_Line 0xc0//起始行

        #define Rs RC2 //定義12864液晶接口
        #define RW RC1
        #define Ce RC0
        #define Cs1 RC3
        #define Cs2 RC4

        #define T_CLK RA1 //實時時鐘時鐘線引腳
        #define T_IO RA2 //實時時鐘數據線引腳
        #define T_RST RA0 //實時時鐘復位線引腳
        #define TRI TRISA2 //I/O作為輸入

        #define DQ RA3 //定義18B20數據端口
        #define DQ_DIR TRISA3 //定義18B20D口方向寄存器
        #define DQ_HIGH() DQ_DIR =1 //設置數據口為輸入
        #define DQ_LOW() DQ = 0; DQ_DIR = 0 //設置數據口為輸出
        unsigned char temp1; //采集到的溫度高8位
        unsigned char temp2; //采集到的溫度低8位,轉換后的溫度值BCD碼形式
        const unsigned char tablexiao[16]={0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,9};
        unsigned char moon[3];
        unsigned char m_temp[3];
        unsigned char timebuf[7];
        bit display_time; //刷新時間顯示標志位
        bit display_tem; //刷新溫度顯示標志位
        bit tem_en; //啟動溫度顯示標志位
        unsigned char n; //輔助于timer1
        unsigned char n2; //輔助于timer1
        const unsigned char shuzi[]={
        /*-- 文字: 0 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,

        /*-- 文字: 1 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0x20,0x30,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,

        /*-- 文字: 2 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0x60,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x20,0x00,

        /*-- 文字: 3 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0x30,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x18,0x20,0x20,0x21,0x21,0x1E,0x00,

        /*-- 文字: 4 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x06,0x05,0x04,0x04,0x04,0x3F,0x04,

        /*-- 文字: 5 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0xF8,0x48,0x48,0x48,0x48,0x88,0x00,0x00,0x18,0x20,0x20,0x20,0x20,0x1F,0x00,

        /*-- 文字: 6 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0xE0,0x10,0x88,0x88,0x88,0x30,0x00,0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00,

        /*-- 文字: 7 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0x08,0x08,0x08,0x08,0xC8,0x38,0x00,0x00,0x00,0x00,0x30,0x0E,0x01,0x00,0x00,

        /*-- 文字: 8 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0x60,0x90,0x08,0x08,0x08,0x90,0x60,0x00,0x0C,0x12,0x21,0x21,0x21,0x12,0x0C,

        /*-- 文字: 9 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x19,0x22,0x22,0x22,0x11,0x0F,0x00,

        /*-- 文字: : --*/
        /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,

        /*-- 文字: . --11*/
        /*-- 宋體12; 此字體下對應的點陣為:寬x高=8x16 --*/
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,
        };

        const unsigned char hanzi[]=
        {
        /*-- 文字: 年 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x20,0x30,0xDC,0xCF,0xCF,0xCC,0xCC,0xFC,0xFC,0xCC,0xCC,0xCC,0x0C,0x00,0x00,
        0x0C,0x0C,0x0C,0x0F,0x0F,0x0C,0x0C,0x0C,0x7F,0x7F,0x0C,0x0C,0x0C,0x0C,0x0C,0x00,

        /*-- 文字: 月 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x00,0x00,0xFE,0xFE,0x26,0x26,0x26,0x26,0x26,0x26,0xFE,0xFE,0x00,0x00,0x00,
        0x00,0x40,0x70,0x3F,0x0F,0x03,0x03,0x03,0x03,0x23,0x63,0x7F,0x3F,0x00,0x00,0x00,

        //*-- 文字: 星 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x00,0x7E,0xFE,0xD6,0x56,0x56,0xD6,0xD6,0x56,0x56,0x7E,0x7E,0x00,0x00,0x00,
        0x00,0x66,0x67,0x6B,0x6B,0x6B,0x6B,0x7F,0x7F,0x6B,0x6B,0x6B,0x6B,0x60,0x60,0x00,

        /*-- 文字: 期 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x0C,0xFF,0xFF,0xAC,0xFF,0xFF,0x0C,0xFE,0xFE,0x66,0x66,0xFE,0xFE,0x00,0x00,
        0x26,0x36,0x1F,0x07,0x06,0x1F,0x57,0x66,0x3F,0x1F,0x03,0x63,0x7F,0x3F,0x00,0x00,

        /*-- 文字: 一 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

        /*-- 文字: 二 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x00,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x00,0x00,0x00,
        0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,

        /*-- 文字: 三 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x00,0x0C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x8C,0x0C,0x00,0x00,0x00,
        0x00,0x30,0x30,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x30,0x00,0x00,

        /*-- 文字: 四 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0xFE,0xFE,0x06,0x06,0xFE,0xFE,0x06,0xFE,0xFE,0x06,0x06,0xFE,0xFE,0x00,0x00,
        0x00,0x7F,0x7F,0x36,0x37,0x33,0x31,0x30,0x31,0x33,0x33,0x33,0x7F,0x7F,0x00,0x00,

        /*-- 文字: 五 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x06,0xC6,0xC6,0xC6,0xC6,0xFE,0xFE,0xC6,0xC6,0xC6,0xC6,0x06,0x06,0x00,0x00,
        0x30,0x30,0x30,0x30,0x30,0x3F,0x3F,0x30,0x30,0x30,0x3F,0x3F,0x30,0x30,0x30,0x00,

        /*-- 文字: 六 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x60,0x60,0x60,0x60,0x60,0x62,0x6E,0x6C,0x60,0x60,0x60,0x60,0x60,0x60,0x00,
        0x00,0x20,0x30,0x1C,0x0E,0x03,0x00,0x00,0x00,0x01,0x03,0x0E,0x38,0x30,0x00,0x00,

        /*-- 文字: 七 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x80,0x80,0x80,0x80,0xFE,0xFE,0xC0,0x40,0x60,0x60,0x30,0x30,0x30,0x00,0x00,
        0x00,0x01,0x01,0x01,0x00,0x3F,0x7F,0x60,0x60,0x60,0x60,0x60,0x78,0x38,0x00,0x00,

        /*-- 文字: 八 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,
        0x20,0x30,0x1C,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x0E,0x18,0x30,0x20,0x00,

        /*-- 文字: 九 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x18,0x18,0x18,0x18,0xFF,0xFF,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,
        0x20,0x60,0x30,0x18,0x0E,0x07,0x01,0x00,0x00,0x3F,0x7F,0x60,0x60,0x78,0x30,0x00,

        /*-- 文字: 十 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

        /*-- 文字: 冬 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x00,0x30,0x38,0x9C,0xBF,0xEF,0xCC,0xEC,0xBC,0x9C,0x8C,0x00,0x00,0x00,0x00,
        0x03,0x03,0x03,0x03,0x11,0x11,0x36,0x36,0x24,0x6D,0x6D,0x01,0x03,0x03,0x03,0x00,

        /*-- 文字: 臘 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0xFE,0xFE,0x26,0xFE,0xFE,0x60,0x6C,0x7F,0x7F,0x6C,0x7F,0x7F,0x6C,0x60,0x00,
        0x60,0x7F,0x1F,0x61,0x7F,0x3F,0x00,0x7F,0x7F,0x29,0x29,0x29,0x7F,0x7F,0x00,0x00,

        /*-- 文字: 日 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x00,0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xFF,0xFF,0x00,0x00,0x00,
        0x00,0x00,0x00,0x7F,0x7F,0x30,0x30,0x30,0x30,0x30,0x30,0x7F,0x7F,0x00,0x00,0x00,

        /*-- 文字: 初 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x18,0x9B,0xDF,0xFE,0xB8,0xC0,0x4C,0x0C,0xFC,0xFC,0x0C,0x0C,0xFC,0xFC,0x00,
        0x02,0x03,0x01,0x7F,0x7F,0x03,0x66,0x30,0x1C,0x0F,0x63,0x60,0x70,0x3F,0x1F,0x00,

        /*-- 文字: ℃ --*/
        /*-- 宋體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x00,0x02,0x05,0xE2,0x18,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x04,0x1E,0x00,0x00,
        0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x18,0x00,0x00,

        /*-- 文字: 廿 --*/
        /*-- 黑體12; 此字體下對應的點陣為:寬x高=16x16 --*/
        0x30,0x30,0x30,0x30,0xFF,0xFF,0x30,0x30,0x30,0x30,0xFF,0xFF,0x30,0x30,0x30,0x00,
        0x00,0x00,0x00,0x00,0x7F,0x7F,0x18,0x18,0x18,0x18,0x7F,0x7F,0x00,0x00,0x00,0x00,
        };

        const unsigned int table[101] = {0x4693,
        0xDA9B, 0x052B, 0x2A5B, 0xDAAE, 0x756A, 0xDDD5, 0x0BA4, 0x5B49, 0xDD53, 0x0A95,
        0x452D, 0xD55D, 0x9AB5, 0xDBAA, 0x05D2, 0x6DA5, 0xEE8A, 0x0D4A, 0x4C95, 0xDA9E,
        0x0556, 0x2AB5, 0xDADA, 0x66D2, 0xD765, 0x0725, 0x564B, 0xD657, 0x0CAB, 0x355A,
        0xD56E, 0xBB69, 0xDF52, 0x0B52, 0x5B25, 0xDD2B, 0x0A4B, 0x54AB, 0xD2BB, 0x05AD,
        0x2B6A, 0xDDAA, 0x7D92, 0xDEA5, 0x0D25, 0x5A55, 0xEA4D, 0x04B6, 0x35B5, 0xE6D2,
        0x8EC9, 0xDF92, 0x0E92, 0x6D26, 0xE516, 0x0A57, 0x44D6, 0xE365, 0x0755, 0x3749,
        0xD74B, 0x7693, 0xDAAB, 0x052B, 0x5A5B, 0xDABA, 0x056A, 0x4B65, 0xDBAA, 0x8B4A,
        0xDD95, 0x0A95, 0x652D, 0xD56D, 0x0AB5, 0x55AA, 0xE5C5, 0x0DA5, 0x3D4A, 0xDE4D,
        0x7C96, 0xDCCE, 0x0556, 0x5AB5, 0xEAD2, 0x06D2, 0x5EA5, 0xD72A, 0x868B, 0xD697,
        0x04AB, 0x655B, 0xE556, 0x0B6A, 0x4752, 0xDB95, 0x0B25, 0x2A8B, 0xDA4F, 0x04AB
        };

        void delay(unsigned int t)
        {
        unsigned int i,j;
        for(i=0;i{
        for(j=0;j<10;j++)
        {
        asm("NOP");
        }
        }
        }
        void data_cvt (unsigned char yy, unsigned char mm, unsigned char dd, unsigned char *moon)
        { unsigned char i,j,leap;
        unsigned int days1,days2,x;
        days1 = yy * 365 + ((yy+3)>>2) + (mm-1)*30 + dd;
        if ((mm >2) && ((yy & 3) == 0) && (yy != 100))
        days1 ++;
        switch(mm)
        {
        case 3: days1--;
        break;
        case 11:
        case 12: days1 ++;
        case 9:
        case 10: days1 ++;
        case 8: days1 ++;
        case 2:
        case 6:
        case 7: days1 ++;
        }
        days1 -=35;
        days2=0;
        leap=0xFF;
        for (i=0; i<=100; i++)
        {x=table[i];
        for (j=0; j<12; j++)
        {
        days2 += 29 + (x & 1);
        if (days2 >= days1)
        break;

        if (j==leap)
        {
        days2 + =16 + (table[i] >> 12);
        if (days2 >= days1)
        { j |= 0x80;
        x = !(table[i] >> 12);
        break;
        }
        }
        x >>= 1;
        }
        if (days2 >= days1)
        break;

        leap = x-1;
        }
        * moon++ = i; //output result
        * moon++ = j+1;
        * moon = (unsigned char) (29 + (x & 1) -(days2-days1));
        }

        void delay_T(unsigned char x,unsigned char y)
        {
        unsigned char z;
        do{
        z=y;
        do{
        ;
        }while(--z);
        }while(--x);
        }

        void init(void)
        {
        asm("CLRWDT");
        ADCON1=0X06;
        OPTION=0x81;
        TRISA=0B00000000;
        TRISB=0B00000000;
        TRISC=0B00000000;
        TRISD=0B00000000;
        TRISE=0B00000000;
        PORTA=0x01;
        PORTB=0x00;
        PORTC=0x00;
        PORTD=0x00;
        PORTE=0x00;
        RBIE=0;
        }
        unsigned char reset(void)
        {
        unsigned char outbit;
        DQ_LOW(); //主機拉至低電平
        delay_T(2,50); //延時503us(480us~960us)
        DQ_HIGH(); //釋放總線等電阻拉高總線,并保持15~60us
        delay_T(2,8); //這里延時70us
        if(DQ==1) outbit=0; //檢測響應,沒有接收到應答信號,說明復位不正確,下次繼續復位
        else outbit=1; //接收到應答信號
        delay_T(2,60); //延時430us ,等待總線恢復高電平
        return outbit;
        }

        void write_byte(unsigned char val)
        {
        unsigned char i;
        unsigned char temp;
        for(i=8;i>0;i--)
        {
        temp=val&0x01; //依次提取每一位
        DQ_LOW(); //從高拉至低電平,產生寫時間隙
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
        if(temp==1) DQ_HIGH(); //如果寫1,拉高電平
        delay_T(2,7); //延時63us(>45us)
        DQ_HIGH(); //拉高電平,以備下次寫數據
        NOP();
        NOP();
        val=val>>1; //右移一位
        }
        }

        unsigned char read_byte(void)
        {
        unsigned char i;
        unsigned char value=0; //讀出溫度
        static bit j;
        for(i=8;i>0;i--)
        {
        value>>=1; //已經讀取的位右移一位
        DQ_LOW();
        NOP();
        NOP();
        NOP();
        NOP();
        NOP();
        NOP(); //6us
        DQ_HIGH(); //拉至高電平
        NOP();
        NOP();
        NOP();
        NOP();
        NOP(); //4us
        j=DQ; //檢測收到的位
        if(j) value|=0x80; //收到1,value最高位置1
        delay_T(2,7); //63us
        }
        return(value);
        }
        void convert_T(void)
        {
        if(reset()==1) //ds18b20響應了
        {
        write_byte(0xcc); // 跳過多器件識別
        write_byte(0x44); // 啟動溫度轉換
        }
        }
        void read_T(void)
        {
        unsigned char Lsb,Msb;
        if(reset()==1)
        {
        write_byte(0xcc); // 每次讀寫前,跳過多器件識別
        write_byte(0xbe); // 讀暫存器
        Lsb=read_byte(); // 低字節
        Msb=read_byte(); // 高字節
        temp2=Lsb&0x0f; //取出低字節的小數部分的四位
        temp1=(Lsb>>4)|(Msb<<4); //將高字節的低四位與低字節的高四位和在一塊,即位代表溫度的整數部分
        }
        }

        void write_com(unsigned char cmdcode)
        {

        Rs=0; //選擇指令
        RW=0; //選擇寫
        PORTB=cmdcode;//寫指令碼
        asm("NOP");
        asm("NOP");
        asm("NOP");
        Ce=1;//開讀寫
        asm("NOP");
        asm("NOP");
        asm("NOP");
        Ce=0;//關讀寫
        }

        void write_data(unsigned char Rsspdata)
        {
        Rs=1;//選擇數據
        RW=0;//選擇寫
        PORTB=Rsspdata;
        asm("NOP");
        asm("NOP");
        asm("NOP");
        Ce=1;//開讀寫
        asm("NOP");
        asm("NOP");
        asm("NOP");
        Ce=0;//關讀寫
        }

        void Clr_Scr(void)
        {
        unsigned char j,k;
        Cs1=1;
        Cs2=1;
        write_com(Page_Add+0);//定位到第0頁(頁起始位置0-7)
        write_com(Col_Add+0);//定位到第0列(列起始位置0-63)
        for(k=0;k<8;k++)
        {
        write_com(Page_Add+k);
        for(j=0;j<64;j++) write_data(0x00);//清屏
        }
        }

        void write_x_y(unsigned char x,unsigned char y)
        {
        y=y&0x7f;//限制列y在0~127
        x=x&0x07;//限制行x在0~7
        if(y<64)//在左屏
        {
        Cs1=1;
        Cs2=0;//左屏可設置
        write_com(Col_Add+y);//設置列地址
        }
        else //在右屏
        {
        Cs1=0;
        Cs2=1;//右屏可設置
        y&=0x3f;//將y在改為0~64的序列(y-64)
        write_com(Col_Add+y);//設置列地址
        }
        write_com(Page_Add+x);//設置為當前頁
        }

        void init_lcd(void)
        {
        delay(250);//延時48 ms(通過MPLAB IDE測得)
        delay(250);
        Cs1=1;
        Cs2=1; //選擇全屏(CS2=1,CS1=0:左屏,CS2=0,CS1=1:右屏)
        delay(250);
        write_com(Rssp_Off);//顯示關
        write_com(Page_Add+0);//定位到第0頁指令(頁起始位置0-7)
        write_com(Start_Line+0);//定位從DDRAM中的第0行開始往屏幕上顯示
        write_com(Col_Add+0);//定位到第0列指令(列起始位置0-63)
        write_com(Rssp_On);//顯示開
        }

        void write_english(unsigned char x,unsigned char y, unsigned char en)
        {
        unsigned char j=0,i=0;
        for(j=0;j<2;j++) //使用兩行顯示一個字符
        {
        write_x_y(x+j,y);//寫地址
        for(i=0;i<8;i++) write_data(shuzi[en*16+8*j+i]);//使用8列顯示一個字符
        }
        }
        void write_chinese(unsigned char x,unsigned char y, unsigned char hz)
        {
        unsigned char j=0,i=0;
        for(j=0;j<2;j++)
        {
        write_x_y(x+j,y);
        for(i=0;i<16;i++) write_data(hanzi[hz*32+16*j+i]);
        }
        }

        void RTInputByte(unsigned char d)
        {
        unsigned char i;
        for(i=0;i<8;i++)
        {
        if(d&0x01)
        T_IO=1;
        else
        T_IO=0;
        d=d>>1;
        asm("NOP");
        asm("NOP");
        asm("NOP");
        T_CLK = 1;
        asm("NOP");
        asm("NOP");
        asm("NOP");
        asm("NOP");
        T_CLK = 0;
        asm("NOP");
        asm("NOP");
        asm("NOP");
        }
        }

        unsigned char RTOutputByte(void)
        {
        unsigned char i,b;
        TRI=1;
        for(i=8; i>0; i--)
        {
        b= b>>1; /*相當于匯編中的 RRC */
        if(T_IO==1)
        b|=0x80;
        else
        b&=0x7f;
        T_CLK = 1;
        asm("NOP");
        T_CLK = 0;
        }
        TRI=0;
        return b;
        }

        void W1302(unsigned char ucAddr, unsigned char ucDa)
        {
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        RTInputByte(ucAddr); /* 地址,命令 */
        RTInputByte(ucDa); /* 寫1Byte數據*/
        T_CLK = 1;
        T_RST = 0;
        }

        unsigned char R1302(unsigned char ucAddr)
        {
        unsigned char ucData;
        T_RST = 0;
        T_CLK = 0;
        T_RST = 1;
        RTInputByte(ucAddr); /* 地址,命令 */
        ucData = RTOutputByte(); /* 讀1Byte數據 */
        T_CLK = 1;
        T_RST = 0;
        return(ucData);
        }


        void Set1302(unsigned char *pClock)
        {
        unsigned char i;
        unsigned char ucAddr = 0x80;
        W1302(0x8e,0x00); /* 控制命令,WP=0,寫操作?*/
        for(i =7; i>0; i--)
        {
        W1302(ucAddr,*pClock); /* 秒 分 時 日 月 星期 年 */
        pClock++;
        ucAddr +=2;
        }
        W1302(0x8e,0x80); /* 控制命令,WP=1,寫保護?*/
        }

        void Get1302(unsigned char ucCurtime[])
        {
        unsigned char i;
        unsigned char ucAddr = 0x81;
        for (i=0; i<7; i++)
        {
        ucCurtime[i] = R1302(ucAddr);/*格式為: 秒 分 時 日 月 星期 年 */
        ucAddr += 2;
        }
        }


        void timerinit(void)
        {
        T1CON=0X01;
        TMR1IF=0; //清除TMR1中斷標志
        TMR1IE=1; //TMR1中斷允許
        TMR1H=0x3C; //賦初值,以便TMR1精確地每50ms中斷一次
        TMR1L=0xC9;
        PIR1=0;
        PEIE=1;
        GIE=1;
        }

        void interrupt T1(void)
        {
        if(TMR1IF==1) //中斷類型判斷
        {
        TMR1H=0X3C;
        TMR1L=0xC0;
        TMR1IF=0;
        if(++n>19)//n=20時 為1s計時
        {
        display_time=1;
        n=0;
        }
        if (n==10) tem_en=1; //當n=10,啟動溫度顯示,以錯開時間顯示的時間
        if(tem_en)
        if(++ n2 >19)//n2=20時 為1s計時
        {
        display_tem=1;
        n2=0;
        }
        }
        }

        void main(void)
        {
        unsigned char j,t,k;
        init();
        init_lcd();//初始化屏幕
        Clr_Scr();//清屏
        //畫屏幕中央分割豎線
        for(j=0;j<8;j++)
        {write_x_y(j,58);
        write_data(0xff);
        }
        for(j=0;j<8;j++)
        {write_x_y(j,59);
        write_data(0xff);
        }
        //結束畫線

        Get1302(timebuf); //獲取系統時間
        if(timebuf[0]==0) //獲取時間不正確,則時間初始化
        {
        timebuf[6]=0x10;//10年
        timebuf[4]=0x05;//05月
        timebuf[3]=0x05;//01日
        timebuf[5]=0x06;//星期6(1-7)
        timebuf[2]=0x21;//21點
        timebuf[1]=0x46;//46分
        timebuf[0]=0x02;//02秒
        Set1302(timebuf); //將以上時間寫入時鐘芯片
        }

        timerinit();//定時器開啟
        while(1)//主循環
        {
        //以下為溫度處理
        if(display_tem)//每1秒刷新一次溫度
        {
        display_tem=0;//標志位歸0
        convert_T();
        delay(250);
        read_T();
        if(temp1>80) temp1=0;//溫度范圍規定
        if(temp2>15) temp2=0;
        write_english(2,72,temp1/10);
        write_english(2,80,temp1%10);
        write_english(2,88,11); //.
        write_english(2,96,tablexiao[temp2]);
        write_chinese(2,104,18); //℃
        }
        //以下為日期刷新
        if(display_time) //每過1 秒,進入此函數刷新時間
        {
        display_time=0;//標志位歸0
        convert_T();
        Get1302(timebuf);

        //以下為公歷轉農歷moon[0]記錄年,moon[1]記錄月,moon[2]記錄日
        m_temp[0]=(timebuf[6]>>4)*10+timebuf[6]&0x0f;//公歷日期 十六進制轉十進制
        m_temp[1]=(timebuf[4]>>4)*10+timebuf[4]&0x0f;
        t=(timebuf[3]>>4)*10;
        k= timebuf[3]&0x0f;
        m_temp[2]=t+k;
        data_cvt(m_temp[0],m_temp[1],m_temp[2],& moon[0]);//公歷轉農歷函數調用
        //以下為顯示公歷日期
        write_english(0,4,2); //20xx年
        write_english(0,12,0);
        write_english(0,20,(timebuf[6]>>4)&0x0f);
        write_english(0,28,timebuf[6]&0x0f);
        write_chinese(0,40,0);

        write_english(2,0,(timebuf[4]>>4)&0x01);//xx月
        write_english(2,8,timebuf[4]&0x0f);
        write_chinese(4,0,1);

        write_english(3,24,(timebuf[3]>>4)); //xx日
        write_english(3,32,timebuf[3]&0x0f);
        write_chinese(3,40,16);

        write_chinese(6,4,2);//星期x
        write_chinese(6,20,3);
        write_chinese(6,36,(timebuf[5]&0x07)+2);
        //以下為農歷日期顯示

        write_chinese(4,64,moon[1]+3); //顯示月份,在一到十就顯示相應數字,十一用廿,十二用臘表示
        write_chinese(4,80,1);//“月”

        //以下為農歷日的處理
        switch(moon[2]/10)//判斷農歷日十位為:初,十,廿,三
        {case 0:write_chinese(4,96,17);break;
        case 1:write_chinese(4,96,13);break;
        case 2:write_chinese(4,96,19);break;
        case 3:write_chinese(4,96,6);break;
        }
        if (moon[2]%10==0)//農歷日為整十,則相應個位不能顯示為零,而因該顯示為十,比如:三十
        write_chinese(4,112,13);
        else
        write_chinese(4,112,3+moon[2]%10);

        write_english(0,64,(timebuf[2]>>4)&0x03); //時分秒顯示
        write_english(0,72,timebuf[2]&0x0f);
        write_english(0,80,10); //:
        write_english(0,88,(timebuf[1]>>4)&0x0f);
        write_english(0,96,timebuf[1]&0x0f);
        write_english(0,104,10); //:
        write_english(0,112,(timebuf[0]>>4)&0x0f);
        write_english(0,120,timebuf[0]&0x0f);
        }
        }
        }



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 承德县| 静安区| 台东县| 乐平市| 休宁县| 多伦县| 蒲江县| 梓潼县| 松阳县| 纳雍县| 宝鸡市| 延庆县| 阿瓦提县| 靖宇县| 连江县| 九龙县| 永仁县| 壤塘县| 荣成市| 临洮县| 白沙| 九龙县| 西峡县| 高唐县| 高邑县| 城固县| 连云港市| 垦利县| 临西县| 尼玛县| 莱州市| 南涧| 威海市| 梁河县| 安泽县| 焦作市| 紫金县| 荔浦县| 河源市| 麟游县| 昌都县|