找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 3656|回復(fù): 4
收起左側(cè)

DS1302編寫(xiě)萬(wàn)年歷出現(xiàn)了問(wèn)題求解答

[復(fù)制鏈接]
ID:76675 發(fā)表于 2015-7-14 20:46 | 顯示全部樓層 |閱讀模式
本帖最后由 安樂(lè)晨 于 2015-7-15 09:17 編輯

#include"stc12c5a.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
uchar lcddate;
uchar dis_time_buf[16]={0};
uchar time_buf[8]={0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0x02};
sbit        lcdrs=P3^5;
sbit        lcden=P3^4;
sbit        lcdrw=P3^6;
sbit         RES=P4^5;
sbit         IO=P2^7;
sbit         SCK=P4^0;
#define ds_second_add                0x80
#define ds_minute_add                0x82
#define ds_hour_add                    0x84
#define ds_day_add                        0x86
#define ds_month_add                0x88
#define ds_week_add                        0x8a
#define ds_year_add                        0x8c
#define ds_control_add                0x8e
#define ds_charger_add                0x90
#define ds_clkburst_add                0xbe
void delayms(uint x)
//晶振為12M時(shí),j<112;當(dāng)晶振為11.0592M時(shí),j<122                        
{
  uint i,j;
  for(i=0;i<x;i++)
    for(j=0;j<122;j++);
}
void delayus(uint t)
//微秒延時(shí)                                          
{
  for(;t>0;t--)
   {
         _nop_();
   }
}
void write_com(uchar com)                                  //給液晶指令
{
        lcdrs=0;
        P0=com;
        delayus(20);   //delayms(5);
        lcden=1;
        delayus(20);
        lcden=0;
}
void write_date(uchar date)                                  //向液晶寫(xiě)數(shù)據(jù)
{
        lcdrs=1;
        P0=date;
        delayus(20);
        lcden=1;
        delayus(20);
        lcden=0;
}
void lcd_xy(uchar x,uchar y)                           //液晶兩行的地址
{
        uchar address;
        if(y==0)
                address=0x80+x;
        else
                address=0xc0+x;
        write_com(address);
}
void lcd_write_date(uchar x,uchar y,uchar date)           //確定液晶地址并輸入數(shù)據(jù)
{
        lcd_xy(x,y);
        write_date(date);        
}
void lcd_init()                                                                                //初始化液晶
{
        lcden=0;
        lcdrw=0;
        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
}
void ds_init(void)                                                                         //初始化ds1302時(shí)鐘芯片
{
        RES=0;                        //RST腳置低
        SCK=0;                        //SCK腳置低
}
void ds_write_date(uchar add,uchar date)                        //向DS1302地址寫(xiě)入數(shù)據(jù)
{
        uchar i,temp,m,n;
        RES=0;
        SCK=0;
        RES=1;
        //最低位置零,寄存器0位為0時(shí)寫(xiě),為1時(shí)讀
        for(i=0;i<8;i++)
        {
                SCK=0;
                temp=add;
                IO=(bit)(temp&0x01);
                add=add>>1;
                SCK=1;
        }
        m=date/10;
        n=date%10;
        date=m*16+n;
        for(i=0;i<8;i++)
        {
                SCK=0;
                temp=date;
                IO=(bit)(temp&0x01);
                date=date>>1;
                SCK=1;
        }
        RES=0;
}
uchar ds_read_date(uchar add)                                                 //選中地址后從DS中讀出該地址數(shù)據(jù)
{
        uchar i,temp,date1,date2;
        RES=0;
        SCK=0;
        RES=1;
        add=add|0x01;
        for(i=0;i<8;i++)
        {
                SCK=0;
                temp=add;
                IO=(bit)(temp&0x01);
                add=add>>1;
                SCK=1;
        }
        for(i=0;i<8;i++)
        {
                SCK=1;
                SCK=0;
                lcddate=(IO&0x80);
                lcddate>>=1;
        }
        RES=0;
        date1=lcddate;
        date2=date1/16;
        date1=date1%16;
        date1=date1+date2*10;
        return (date1);
}
void ds_write_time()                                                   //將時(shí)間數(shù)據(jù)按照各自地址輸入DS
{
        ds_write_date(ds_control_add,0x00);                        //關(guān)閉寫(xiě)保護(hù)
        ds_write_date(ds_second_add,0x80);                        //暫停時(shí)鐘
        ds_write_date(ds_year_add,time_buf[1]);
        ds_write_date(ds_month_add,time_buf[2]);
        ds_write_date(ds_day_add,time_buf[3]);
        ds_write_date(ds_hour_add,time_buf[4]);
        ds_write_date(ds_minute_add,time_buf[5]);
        ds_write_date(ds_second_add,time_buf[6]);
        ds_write_date(ds_week_add,time_buf[7]);
        ds_write_date(ds_control_add,0x80);                         //打開(kāi)寫(xiě)保護(hù)
}
void ds_read_time()                                                                   //從DS中按照各自地址讀出時(shí)間數(shù)據(jù)
{
        time_buf[1]=ds_read_date(ds_year_add);
        time_buf[2]=ds_read_date(ds_month_add);
        time_buf[3]=ds_read_date(ds_day_add);
        time_buf[4]=ds_read_date(ds_hour_add);
        time_buf[5]=ds_read_date(ds_minute_add);
        time_buf[6]=ds_read_date(ds_second_add)&0x7f;
        time_buf[7]=ds_read_date(ds_week_add);
}
void display()                                                                                 //將數(shù)據(jù)輸入到液晶上
{
        lcd_write_date(1,0,dis_time_buf[0]+'0');
        lcd_write_date(2,0,dis_time_buf[1]+'0');
        lcd_write_date(3,0,dis_time_buf[2]+'0');
        lcd_write_date(4,0,dis_time_buf[3]+'0');
        lcd_write_date(5,0,'-');
        lcd_write_date(6,0,dis_time_buf[4]+'0');
        lcd_write_date(7,0,dis_time_buf[5]+'0');
        lcd_write_date(8,0,'-');
        lcd_write_date(9,0,dis_time_buf[6]+'0');
        lcd_write_date(10,0,dis_time_buf[7]+'0');
        lcd_write_date(12,0,dis_time_buf[14]+'0');
        lcd_write_date(4,1,dis_time_buf[8]+'0');
        lcd_write_date(5,1,dis_time_buf[9]+'0');
        lcd_write_date(6,1,':');
        lcd_write_date(7,1,dis_time_buf[10]+'0');
        lcd_write_date(8,1,dis_time_buf[11]+'0');
        lcd_write_date(9,1,':');
        lcd_write_date(10,1,dis_time_buf[12]+'0');
        lcd_write_date(11,1,dis_time_buf[13]+'0');
}
void time0() interrupt 1
{
        
        static uchar t;
        TL0 = (65535-60000)%256; // 初始值
        TH0 = (65535-60000)/256;
        TF0=0;
        t++;
        if(t==4)
        {
                t=0;
                ds_read_time();
                dis_time_buf[0]=(time_buf[0]>>4);
                dis_time_buf[1]=(time_buf[0]&0x0f);
                dis_time_buf[2]=(time_buf[1]>>4);
                dis_time_buf[3]=(time_buf[1]&0x0f);
                dis_time_buf[4]=(time_buf[2]>>4);
                dis_time_buf[5]=(time_buf[2]&0x0f);
                dis_time_buf[6]=(time_buf[3]>>4);
                dis_time_buf[7]=(time_buf[3]&0x0f);
                dis_time_buf[14]=(time_buf[7]&0x07);
                dis_time_buf[8]=(time_buf[4]>>4);
                dis_time_buf[9]=(time_buf[4]&0x0f);
                dis_time_buf[10]=(time_buf[5]>>4);
                dis_time_buf[11]=(time_buf[5]&0x0f);
                dis_time_buf[12]=(time_buf[6]>>4);
                dis_time_buf[13]=(time_buf[6]&0x0f);
        }
}
void init_time0()
{
        TMOD=0x01;
        TL0 = (65535-60000)%256; // 初始值
        TH0 = (65535-60000)/256;
        TR0=1;
        ET0=1;
        EA=1;
}
void main()
{
        delayms(50);
        lcd_init();
        ds_init();
        delayms(10);
        ds_write_time();
        init_time0();
        while(1)
        {
                display();
        }
}

運(yùn)行結(jié)果

運(yùn)行結(jié)果
回復(fù)

使用道具 舉報(bào)

ID:1 發(fā)表于 2015-7-14 22:58 | 顯示全部樓層
秒表不走??
回復(fù)

使用道具 舉報(bào)

ID:76675 發(fā)表于 2015-7-15 09:13 | 顯示全部樓層

是的。年的前兩位可以通過(guò)初始的time_buf改變,其他的寫(xiě)入初始數(shù)據(jù)卻不能正常顯示,只是顯示零。而且,我的問(wèn)題是不知道ds1302中的SCLK是怎么工作的,它工作的時(shí)候需要外部的定時(shí)器么?

評(píng)分

參與人數(shù) 1黑幣 +35 收起 理由
admin + 35 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:85868 發(fā)表于 2015-7-16 19:54 | 顯示全部樓層
我有完整程序,20天前做的課程設(shè)計(jì)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表