Thông báo

Collapse
No announcement yet.

Cần giúp-Set bit CH=0 trong Ds1307

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Cần giúp-Set bit CH=0 trong Ds1307

    Mình đang làm đồng hồ 4 số dùng 89s52 và Ds1307 và
    Có dùng dòng lệnh sau để set bit CH=0, đặt trước vòng while(1)

    void CH_clear(void)
    {
    i2c_start();
    i2c_write(0xd0);
    i2c_write(0);
    i2c_write(0);
    i2c_stop();
    }


    Nhưng mỗi khi rút ra, cắm điện lại là phần giây nó lúc nào cũng đếm lại từ đầu, nó không lưu phần giây. Bạn nào biết thì giúp mình với. Cảm ơn nhiều!

    //DONG HO SU DUNG TIMER
    //PHAN CUNG: 89S52; THACH ANH: 24MHZ ;
    //SU DUNG 4 LED 7 DOAN GIO : PHUT - HEN GIO

    /************KHAI BAO THU VIEN, DINH NGHIA********************************************* ***********/
    #include<AT89X52.H>

    #define Set_key P3_6
    #define Up_key P3_5
    #define Dw_key P3_4
    #define Alarm P3_3
    #define Ok P3_2
    #define Loa P3_1
    #define Loa_HG P3_7
    #define PM P3_0
    #define SDA P1_1
    #define SCL P1_0
    #define DS1307_ID 0xD0
    #define SEC 0x00
    #define MIN 0x01
    #define HOUR 0x02
    #define A_MIN 0x08
    #define A_HOUR 0x09



    /************KHAI BAO BIEN, MANG...******************************************* ********************/
    unsigned char led7_data[10] = {0x3F,0x6,0x5b,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F} ; //Decimal to Led7seg
    unsigned char t_view,time,index,F_set,B_nhay,get_t ;
    unsigned char hour,sec,min;
    unsigned char alarm,Display,Data,a_hour,a_min,on_off;

    /************KHAI BAO HAM, CHUONG TRINH CON*********************************************** ********/
    void set_main(void); // Chuong trinh khoi tao main
    void setup_timer(void); // Chuong trinh cai dat timer 1 va 0
    void delay(unsigned int time); // Delay
    void Fix_time(void); // Kiem tra va hieu chinh gia tri cua gio,phut,giay
    void Keypad(void); // Kiem tra xu ly phim nhan.
    void T1_ISR(void); //ngat timer 1 phuc vu nhay led
    void T0_ISR(void); // Dung ngat timer 0 de quet led

    /************CAC CHUONG TRINH CON*********************************************** ******************/


    // LOA
    void bip(void)
    {
    unsigned char n;
    for(n=0;n<100;n++)
    {
    Loa=1; delay(50);
    Loa=0; delay(50);
    }
    }


    // FOR I2C
    /************************************************** *********************/

    void I2C_start(void)
    {
    SCL = 1; SCL = 0;
    SDA = 1; SCL = 1;
    delay(2);
    SDA = 0; delay(2);
    SCL = 0; delay(2);
    }
    void I2C_stop(void)
    {
    SCL = 1; SCL = 0;
    SDA = 0; delay(2);
    SCL = 1; delay(2);
    SDA = 1;
    }
    bit I2C_write(unsigned char dat)
    {
    unsigned char i;
    for (i=0;i<8;i++)
    {
    SDA = (dat & 0x80) ? 1:0;
    SCL=1;SCL=0;
    dat<<=1;
    }
    SCL = 1; delay(2);
    SCL = 0;
    return dat;
    }
    unsigned char I2C_read(void)
    {
    bit rd_bit;
    unsigned char i, dat;
    dat = 0x00;
    for(i=0;i<8;i++) /* For loop read data 1 byte */
    {
    delay(2);
    SCL = 1; /* Set SCL */
    delay(2);
    rd_bit = SDA; /* Keep for check acknowledge */
    dat = dat<<1;
    dat = dat | rd_bit; /* Keep bit data in dat */
    SCL = 0; /* Clear SCL */
    }
    return dat;
    }


    // FOR DS1307
    /************************************************** *********************/

    unsigned char DS1307_get(unsigned char addr)
    {
    unsigned int temp,ret;
    I2C_start(); /* Start i2c bus */
    I2C_write(DS1307_ID); /* Connect to DS1307 */
    I2C_write(addr); /* Request RAM address on DS1307 */
    I2C_start(); /* Start i2c bus */
    I2C_write(DS1307_ID+1); /* Connect to DS1307 for Read */
    ret = I2C_read(); /* Receive data */
    I2C_stop();
    //*********************************************
    temp = ret; /*BCD to HEX*/
    ret = (((ret/16)*10)+ (temp & 0x0f)); /*for Led 7seg*/
    //*********************************************
    return ret;
    }



    void DS1307_Write(unsigned char addr,unsigned char dat)
    {
    unsigned int temp;
    //********************************************** /*HEX to BCD*/
    temp = dat ; /*for Led 7seg*/
    dat = (((dat/10)*16)|(temp %10));
    //**********************************************
    I2C_start(); /* Start i2c bus */
    I2C_write(DS1307_ID); /* Connect to DS1307 */
    I2C_write(addr); /* Request RAM address on DS1307 */
    I2C_write(dat); /* Connect to DS1307 for Read */
    I2C_stop();
    }


    /*********************CHUONG TRINH TAO NHAP NHAY LED*********************/
    void Out_1Hz()
    {
    I2C_start(); /* Start i2c bus */
    I2C_write(0xD0); /* Connect to DS1307 */
    I2C_write(0x07); //vi tri con tro RTC
    I2C_write(0x10);
    I2C_stop();
    }

    /****************CHUONG TRINH GHI HEN GIO**************/
    void Write_Alarm()
    {
    DS1307_Write(A_MIN,a_min);
    DS1307_Write(A_HOUR,a_hour);

    }


    void Read_Alarm()
    {
    a_min = DS1307_get(A_MIN);
    a_hour = DS1307_get(A_HOUR);

    }



    /**************GHI GIA TRI SETUP VAO DS1307************/
    void Write_DS1307()
    {
    DS1307_Write(0x02,hour);
    DS1307_Write(0x01,min);
    DS1307_Write(0x00,sec);
    }

    /*********DOC GIA TRI TRONG DS1307********/
    void Read_DS1307()
    {
    sec = DS1307_get(SEC);
    min = DS1307_get(MIN);
    hour = DS1307_get(HOUR);
    }




    /***********CHUONG TRINH TAO THOI GIAN TRE*************/
    void delay(unsigned int time)
    { while(time--); }


    /*********************CAI DAT GIA TRI TIMER BAN DAU***********************/
    void setup_timer(void) // Setup timer 0 va timer 1
    {
    TMOD=0x11; // timer0 & timer1 set che do 1
    TH0=-1000/256; TL0=-1000%256;
    TH1=0x3C; TL1=0xAF;
    ET1=1; ET0=1; EA=1;
    TF0=0; TF1=0; TR0=1; TR1=1;
    }


    void Fix_time(void) // Kiem tra va hieu chinh gia tri cua gio,phut,giay
    {
    //Tang
    if(sec==60) {sec=0;min++; }
    if(min==60) {min=0;hour++; }
    if(hour==24) hour=0;
    //Giam
    if(sec== -1) {sec=59;min--;}
    if(min== -1) {min=59;hour-- ;}
    if(hour== -1)hour= 23;
    }
    /**************************************/

    //*********************************CHUONG TRÌNH NÚT BAM CAI DAT HE THONG*****************************
    void Keypad(void) // Kiem tra phim nhan.
    {
    //********************Neu nhan nut Ok*******************************************
    if(!Ok)
    {
    delay(1000);
    while(!Ok){;} delay(1000);// chong rung phim
    bip();
    Display=F_set=alarm=0;// Goi hien thi chuong trinh Dong Ho Chay
    if(on_off==1)// Neu bat che do Hen gio = 1
    {
    Write_Alarm();// ghi che do hen gio
    }
    else
    {
    Write_DS1307(); // ghi che do Gio - Phut - Giay
    }
    }
    //***********************Neu nhan nut Setup*******************************************

    if(Display==0)
    {
    if(!Set_key)
    {
    bip();
    F_set++;
    if(F_set==3)
    {
    F_set=0;
    Write_DS1307();
    }
    }
    if(F_set==1)
    {
    if(!Up_key)
    {
    hour++;Fix_time(); delay(50000);
    }
    if(!Dw_key)
    {
    hour--;Fix_time(); delay(50000);
    }
    }
    if(F_set==2)
    {
    if(!Up_key)
    {
    min++;Fix_time(); delay(50000);
    }
    if(!Dw_key)
    {
    min--;Fix_time(); delay(50000);
    }
    }

    }

    //******************** Neu nhan nut Alarm - Hen gio *************
    if(!Alarm)
    {
    bip(); Display=1;// Keu tieng Bip và bat hien thi hen gio
    }
    //************************************************** *************
    if(Display==1)// Neu hien thi hen gio bat 00 - 00
    {
    if(!Set_key)
    {
    bip(); alarm++;
    if(alarm==4) alarm=1;

    }
    if(alarm==1)
    {
    if(!Up_key) //hour++;

    {
    a_hour=a_hour+1; delay(50000);
    if(a_hour==24) a_hour=0;
    }
    if(!Dw_key) //hour--;

    {
    a_hour=a_hour-1; delay(50000);
    if(a_hour== -1) a_hour= 23;
    }
    }
    if(alarm==2)
    {
    if(!Up_key) //min++;

    {
    a_min=a_min+1; delay(50000);
    if(a_min==60) {a_min=0;a_hour++; }
    }
    if(!Dw_key) //min--;

    {
    a_min=a_min-1; delay(50000);
    if(a_min== -1) {a_min=59;a_hour-- ;}
    }
    }
    if(alarm==3)
    {
    if(!Up_key) //hour++;
    {
    on_off=1; delay(50000);
    }
    if(!Dw_key) //hour--;
    {
    on_off=0; delay(50000);
    }
    }


    }
    Fix_time(); //kiem tra tran so
    delay(20000);
    }

    /********************/
    void T1_ISR(void) interrupt 3 // Dung ngat Timer1 de doc DS1307
    {
    TR1=0;
    TF1=0;
    TH1=0x3C;//29 // nap lai gia tri cho thanh ghi 15535
    TL1=0xAF;// 27 // Gia tri cho Timer0: 50000(us)x10=0.5(s)
    time++;
    if(time==10)
    {time=0; B_nhay++; get_t=1;
    if(B_nhay==2)
    B_nhay=0;
    }
    TR1=1;
    }


    /*************************************/
    void T0_ISR(void) interrupt 1 // Dung ngat timer 0 de quet led
    {
    TR0=0;
    TF0=0;
    TH0=0xfc;//-1000/256; // Nap lai gia tri cho thanh ghi
    TL0=0x18;//-1000%256;
    if(Display==0)
    {
    index++;
    //giay
    if(index==1)
    {
    if(F_set==3 && B_nhay==1){index++; index++;}
    else
    {
    t_view=sec; //sec;
    P0=0x00;
    P2=0x02;//00000010
    P0=led7_data[t_view%10]; }} //lay so du sau khi chia 10

    if(index==2)
    {
    P0=0x00;
    P2=0x01;//00010000
    P0=led7_data[t_view/10]; } //xuat gia tri hang chuc
    //phut
    if(index==3){
    if(F_set==2 && B_nhay==1){index++; index++;}
    else
    { t_view=min;
    P0=0x00;
    P2=0x08;//00001000
    P0=led7_data[t_view/10]; }}

    if(index==4)
    {
    P0=0x00;
    P2=0x04;//00000100
    P0=led7_data[t_view%10]; }
    //gio
    if(index==5) {
    if(F_set==1 && B_nhay==1){index=0;}
    else
    { t_view=hour;
    P0=0x00;
    P2=0x20;//00100000
    P0=led7_data[t_view/10]; } }

    if(index==6)
    {
    P0=0x00;
    P2=0x10;//00000001
    P0=led7_data[t_view%10];
    index=0; }
    }
    //*************************CHUONG TRINH HIEN THI HEN GIO**********************
    if(Display==1)
    {
    index++;
    if(index==1)// Hien thi Hen gio
    {
    if(alarm==1 && B_nhay==1){ index++; index++; }
    else
    {
    Data=a_hour;
    P0=0x00;
    P2=0x20;
    P0=led7_data[Data/10];
    }
    }
    if(index==2)
    {

    P0=0x00;
    P2=0x10;
    P0=led7_data[Data%10];
    }
    if(index==3)// Hen phut
    {
    if(alarm==2 && B_nhay==1){ index++; index++; }
    else
    {
    Data=a_min;

    P0=0x00;
    P2=0x08;//
    P0=led7_data[Data/10];
    }
    }
    if(index==4)
    {

    P0=0x00;
    P2=0x04;
    P0=led7_data[Data%10];
    }
    if(index==5)// Hien thi che do on - off Hen gio
    {
    if(alarm==3 && B_nhay==1){ index=0; }
    else
    {

    P0=0x00;
    if(on_off==1)
    {
    P2=0x02; //00100000 - Hang Don vi
    P0=0x00;// sang het 2 led giay -So 8
    }
    else
    {
    P2=0x01;//00010000 - Hang chuc
    P0=0x00; // tat het 2 led giay
    }
    }
    index=0;
    }

    }
    TR0=1;
    }
    /************CHUONG TRINH CHINH********************************************* **********************/
    void main()
    {
    P1=0xFF;
    P0=0xFF;
    P2=0x00;
    Set_key=Up_key=Dw_key=1;
    Loa_HG=Loa=0;
    time=index=0;
    sec=0;
    F_set=get_t=0;
    setup_timer();
    Read_Alarm();
    Out_1Hz();
    a_min=a_hour = 0;
    while(1)

    {
    Keypad();
    if(hour>=12) PM=0; // Neu gio lon hon 12 là gio dem bat led PM
    else PM=1;


    if(F_set==0)
    {
    if(get_t == 1)
    {
    get_t = 0;
    Read_DS1307();// Doc gia tri trong DS1307
    }
    }

    Loa_HG=0;
    // Neu hen gio = gio và hen phut bang phut thi keu bip bip


    if(((a_min==min)&&(a_hour==hour)))

    {
    if(sec<59)
    {
    //bip();
    Loa_HG=1;
    //delay(1000); // Thoi gian tre cho hen gio
    }
    }



    }
    }

  • #2
    Bạn đặt điều kiện : nếu bit CH = 1 thì thực hiện clear bit CH, ngược lại nếu bit CH = 0 thì nhảy vào thực hiện chương trình chính.

    Comment


    • #3
      Nguyên văn bởi tramng Xem bài viết
      Bạn đặt điều kiện : nếu bit CH = 1 thì thực hiện clear bit CH, ngược lại nếu bit CH = 0 thì nhảy vào thực hiện chương trình chính.
      Em viết như vậy, không biết có thể đơn gian hơn được không ạ

      void CH_clear(void)
      {
      I2C_start();
      I2C_write(0xd0);
      I2C_write(0);
      I2C_start();
      I2C_write(0xd1);
      a = I2C_read();
      I2C_stop();
      if(a&0x80)
      {
      I2C_start();
      I2C_write(0xd0);
      I2C_write(0);
      I2C_write(0);
      I2C_stop();
      }


      }

      Comment


      • #4
        Để giây đếm tiếp, đầu tiên bạn đọc giá trị giây, sau đó clear CH, tiếp đó bạn set lại giá trị giây của DS1307 bằng giá trị bạn đọc được trước lúc clear CH để nó đếm tiếp.

        Comment


        • #5
          Làm cách nay không tối ưu. Bác khai báo biến các biến tạm giot, phut, giayt trong bộ nhớ ROM, lúc khởi tạo cho DS1307 bạn nạp các giá trị tạm này vào, cách khai báo như sau:
          unsigned char code giayt, phutt,giot;
          QTCP

          Comment


          • #6
            Còn khi đọc giờ phú giây ra thì bác lưu giá trị giờ phút giây vào 3 biến này.
            QTCP

            Comment


            • #7
              Nguyên văn bởi quoctuan10 Xem bài viết
              Làm cách nay không tối ưu. Bác khai báo biến các biến tạm giot, phut, giayt trong bộ nhớ ROM, lúc khởi tạo cho DS1307 bạn nạp các giá trị tạm này vào, cách khai báo như sau:
              unsigned char code giayt, phutt,giot;
              Cảm ơn anh! Anh viết em vài dòng được không...em chưa hiểu lắm ạ

              Comment


              • #8
                Lúc khai báo biến mình khai báo thêm là:
                unsigned char code hourt, mint, sect; //ba biến này khai báo trong ROM lưu thời gian hiện tại để khi mất điện không bị mất
                Dưới lệnh gọi hàm Read_Ds1307 bạn thêm lệnh này:
                hourt=hour;
                mint=min; //L7u giá trị thời gian hiện tại vào 3 biến trong ROM;
                sect=sec;
                Lúc khởi tạo thời gian ban đầu cho ds1307 thay vì gán hour=min=sec=0 thì bạn gán:
                hour=hourt;
                min=mint; //Gán thời gian trở lại cho ds1307, nếu có mất điện, ds1307 sẽ không đếm từ 0 mà đếm từ hourt, mint, sect
                sec=sect;
                QTCP

                Comment


                • #9
                  Nguyên văn bởi quoctuan10 Xem bài viết
                  Lúc khai báo biến mình khai báo thêm là:
                  unsigned char code hourt, mint, sect; //ba biến này khai báo trong ROM lưu thời gian hiện tại để khi mất điện không bị mất
                  Dưới lệnh gọi hàm Read_Ds1307 bạn thêm lệnh này:
                  hourt=hour;
                  mint=min; //L7u giá trị thời gian hiện tại vào 3 biến trong ROM;
                  sect=sec;

                  Lúc khởi tạo thời gian ban đầu cho ds1307 thay vì gán hour=min=sec=0 thì bạn gán:
                  hour=hourt;
                  min=mint; //Gán thời gian trở lại cho ds1307, nếu có mất điện, ds1307 sẽ không đếm từ 0 mà đếm từ hourt, mint, sect
                  sec=sect;
                  Biến trong ROM mà còn thay đổi được giá trị sao hả bạn ?

                  Comment


                  • #10
                    Thật ra nói ROM là chưa đủ, phải là Flash ROM.
                    QTCP

                    Comment


                    • #11
                      Nguyên văn bởi quoctuan10 Xem bài viết
                      Thật ra nói ROM là chưa đủ, phải là Flash ROM.
                      89 biến nằm trên Flash ROM còn thay đổi giá trị được sao hả bạn ????

                      Comment

                      Về tác giả

                      Collapse

                      AT89SXX Tìm hiểu thêm về AT89SXX

                      Bài viết mới nhất

                      Collapse

                      • vi van pham
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi vi van pham
                        Cám ơn những lời chúc tốt đẹp của em.

                        Việc em làm giống như chê sếp dốt, chẳng những không có miếng xôi nào để ăn mà còn chịu nhiều trù dập lên bờ , xuống ruộng.

                        Hãy tránh vết xe đổ của tui đi. Dành thời gian lo cho gia đình....
                        hôm nay, 02:00
                      • nhathung1101
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi nhathung1101
                        Ngoại ngữ là không thể thiếu, nhất là làm việc với công nghệ.

                        Nhưng học để tán gái hay để đọc datasheet, manual là chuyện cần quan tâm.

                        Và đọc ở nguồn nào đáng tin cậy, chứ cứ lên tictok hay facebook học lỏm thì...
                        Hôm qua, 22:18
                      • dinhthuong80
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi dinhthuong80
                        Bác nói rất khách quan và chính xác. Ngoại ngữ là chìa khóa thăng tiến dù làm gì. Chả thế mà nay nước mình dạy tiếng Anh từ tiểu học.

                        Nhớ hồi năm 2006 em ra Hải Phòng, Hải Dương tìm việc, thời đó ở Bình Dương lương công...
                        Hôm qua, 14:51
                      • dinhthuong80
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi dinhthuong80
                        Cảm ơn bạn, ĐT cũng có ý nghĩ như vậy.

                        Thực ra, lỗi của hãng đó ( gọi là hãng vì không chỉ một model sản phẩm) là về phần cứng, ĐT tuy không biết về lập trình phần mềm nhưng cũng thấy rằng sẽ chẳng khó khăn gì đáng...
                        Hôm qua, 14:39
                      • dinhthuong80
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi dinhthuong80
                        Dạ, bác bảy mấy tuổi đời rồi cũng không kém bố cháu bao nhiêu. Tuổi nghề thì bác cũng đáng tuổi cha chú.

                        Nhưng 2 điều trên thì chưa hẳn đã đáng quí và đáng tôn trọng bằng việc bác rất nhiệt tình chia sẻ kinh nghiệm chuyên...
                        Hôm qua, 14:28
                      • bqviet
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi bqviet
                        Đúng, nếu chú tâm thì chỉ cần mỗi tiếng Việt là đã khá đủ để làm đa số công việc thông thường, ở thời đại ngày nay khi tài liệu sách vở phương tiện thông tin liên lạc đã nhiều. Nhưng cũng chính ở thời nay giao lưu các nước nhiều...
                        21-02-2025, 20:26
                      • mèomướp
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi mèomướp
                        Dạ cháu nghĩ chú dinh... cứ mạnh dạn gửi thư đi ạ, chú có thể gửi bằng văn bản in chuyển phát nhanh sẽ có giá trị hơn. Vấn đề chưa hẳn là cần hãng làm gì đó, mà chỉ đơn giản là mình cảm thấy nhẹ lòng vì đã làm những việc bản...
                        21-02-2025, 12:32
                      • vi van pham
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi vi van pham
                        Những lần hắt hơi sổ mũi làm tôi mệt lã, phải dùng rượu uống để ngũ. Tôi cũng đang uống rượu 1 mình, viết vài dòng này cho em ( có lẽ dt chỉ bằng tuổi em tôi).

                        Dinh thuong dang đi vào vết xe đổ của tôi. Càng chứng minh, có...
                        20-02-2025, 21:31
                      • bqviet
                        Trả lời cho Hỏi về cách hàn linh kiện ( giúp tớ với )
                        bởi bqviet
                        Thiết nghĩ thi thoảng bác lên đây chia xẻ ít kinh nghiệm cũng vui rồi. Còn chuyện con người sinh lão bệnh tử là thường, sống cùng với quy luật đó thôi. Bqv nhớ trước đây bác từng kể về chuyện rang chì ô-xít bằng chảo để phục hồi bình điện, đấy cũng là thành quả đáng nể phục ở thời kỳ thiếu thốn đó.
                        20-02-2025, 17:22
                      • dinhthuong80
                        Trả lời cho Tiếng Anh cho người Việt
                        bởi dinhthuong80
                        Tiếng Anh, Đình Thường phải nói là rất tệ, khiến việc giao tiếp đời thường thôi cũng khó chứ nói gì về kĩ thuật.

                        Nhân tiện, nhờ các bạn, các bác xem giúp thư ĐT viết thế này liệu có thể gửi tới địa chỉ nhận hay chăng,...
                        20-02-2025, 11:52
                      Đang tải...
                      X