Thông báo

Collapse
No announcement yet.

Một số điều lưu ý khi giao tiếp với DS1307!

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

  • #16
    Nguyên văn bởi thongtr Xem bài viết
    Pac nào có thể viết một đoạn chương trình ngắn để nhập giá trị ngày tháng vào trong chip DS1307 với. Mình chưa hiểu lắm về tổ chức bộ nhớ của DS1307 tới!! tức là ở ô nhớ nào thì nhập giá trị ngày ô nhớ nào là nhập giá trị tháng!!
    giúp mình với nhé!! mình đang cần gấp!!
    thanks!
    Các ô nhập giá trị ngày, tháng.... có địa chỉ như thế nào đều nằm trong bảng địa chỉ có trong datasheet, bác giở ra mà xem. Còn đây là đoạn chương trình mẫu cho bác tham khảo.
    void i2c_write(unsignchar add, unsign char data)
    {
    i2c_start();
    i2c_write(0xd0); //đây là địa chỉ của DS1307 trên Bus I2C
    i2c_write(add); // Đây là địa chỉ thanh ghi ngày hoặc tháng hoặc.... cần đặt
    i2c_write(data); // Giá trị cần ghi vào
    i2c_stop();
    }
    Nỏ biết chữ mần răng ký được??!! Thôi nhé.

    Comment


    • #17
      Lưu ý cái này nhé các bác: Nếu bác nào dùng chân SQW/OUT thì chú ý dòng ra/vào trên nó, ví dụ, khi active thì dòng cấp cho DS1307 khoảng vài mA=> Dòng qua SQW phải nhỏ hơn vài mA tức là trở kháng tải phải lớn hơn vài KOhm => Nên dùng OA thay cho Tran như trong Appnote. Nếu tải quá nhỏ thì con này dễ bị treo bộ dao động lắm.
      Nỏ biết chữ mần răng ký được??!! Thôi nhé.

      Comment


      • #18
        Nguyên văn bởi thangktvta Xem bài viết
        Các ô nhập giá trị ngày, tháng.... có địa chỉ như thế nào đều nằm trong bảng địa chỉ có trong datasheet, bác giở ra mà xem. Còn đây là đoạn chương trình mẫu cho bác tham khảo.
        void i2c_write(unsignchar add, unsign char data)
        {
        i2c_start();
        i2c_write(0xd0); //đây là địa chỉ của DS1307 trên Bus I2C
        i2c_write(add); // Đây là địa chỉ thanh ghi ngày hoặc tháng hoặc.... cần đặt
        i2c_write(data); // Giá trị cần ghi vào
        i2c_stop();
        }
        mình viết bằng ngôn ngữ assembly Pác ơi!! pác nói kỹ hơn về tổ chức ô nhớ của ds1307 mình cũng có datasheet rồi nhưng mình cũng chẳng hiểu gì cả!!
        ví dụ như để trước khi truyền data về tháng thì mình phải truyền địa chỉ ô nhớ
        như thế nào. để Ds1307 biết là mình đang chuẩn bị truyền data về tháng!!
        Pác trả lời nhanh cho mình nhé!
        thanks!!
        Giúp nhau cùng tiến bộ....
        Học học..... vì tất cả......

        Comment


        • #19
          Nguyên văn bởi thongtr Xem bài viết
          mình viết bằng ngôn ngữ assembly Pác ơi!! pác nói kỹ hơn về tổ chức ô nhớ của ds1307 mình cũng có datasheet rồi nhưng mình cũng chẳng hiểu gì cả!!
          ví dụ như để trước khi truyền data về tháng thì mình phải truyền địa chỉ ô nhớ
          như thế nào. để Ds1307 biết là mình đang chuẩn bị truyền data về tháng!!
          Pác trả lời nhanh cho mình nhé!
          thanks!!
          Viết bằng Assem thì hơi khó rồi. Không sao. Thế này nhé, bác giở datasheet ra, xem cái bảng DS1307 TIMEKEEPER REGISTERS, đây là các thanh ghi điều khiển của con DS1307 bao gồm từ địa chỉ 00h đến 07h. Thứ tự như thế này:
          00h: seconds
          01h: minutes
          02h: hours
          03h: day
          .....
          Trong một thanh ghi sẽ có 8 bit, các bit này có thể thực hiện nhiều chức năng khác nhau, tuy nhiên bác chưa cần quan tâm cái này để khỏi phức tạp vấn đề, chỉ cần quan tâm cái đống địa chỉ và chức năng như tôi đưa ra ở trên là đc. Ví dụ khi muốn truyền địa chỉ data cho tháng thì phải đưa con trỏ chỉ đến thanh ghi 05h, thế thôi! Chúc bác thành công!
          Nỏ biết chữ mần răng ký được??!! Thôi nhé.

          Comment


          • #20
            Mình cảm ơn Pác rất nhiều!!
            thanks!!
            Giúp nhau cùng tiến bộ....
            Học học..... vì tất cả......

            Comment


            • #21
              các bạn thử đọc chương trình của mình nhé sao mình nạp cho con chip ds1307 chẳng đc

              CONTOL_DS1307:
              WRITE_DS1307:
              ACALL SEND_STAR
              MOV A,DS1307W
              ACALL SEND
              MOV A,07H ;CONTROL REGISTOR
              ACALL SEND
              MOV A,#02H
              ACALL SEND
              MOV A,00H ;
              ACALL SEND
              MOV A,#19H ;19 S
              ACALL SEND
              MOV A,#38H ;38 PHUT
              ACALL SEND
              MOV A,#18H ;18h 38 phut 19 s
              ACALL SEND
              ACALL SEND_STOP
              SJMP $

              SEND_STAR:
              SETB SDA
              SETB SCL
              JNB SCL,$
              CLR SDA
              NOP
              CLR SCL
              RET
              SEND_STOP:
              CLR SDA
              SETB SCL
              JNB SCL,$
              SETB SDA
              RET
              SEND:
              MOV R4,#8
              AGAIN:
              JB ACC.7,SETBIT
              CLR SDA
              SJMP AGAIN1
              SETBIT:
              SETB SDA
              AGAIN1:
              SETB SCL
              JNB SCL,$
              CLR SCL
              RL A
              DJNZ R4,AGAIN
              CLR SDA
              SETB SCL
              JNB SCL,$
              CLR SCL
              RET

              và đây là sơ đồ mình vẽ trong Proteus
              các bạn tham khảo giúp mình nhe!!
              thanks!
              Attached Files
              Last edited by thongtr; 25-07-2007, 16:21.
              Giúp nhau cùng tiến bộ....
              Học học..... vì tất cả......

              Comment


              • #22
                Có bác nào có code viết bằng HT-PIC cho PIC 18F không cho xin cái đê.
                “If you create your own electricity, heating and water systems, you create your own politics. Maybe that’s what they’re afraid of.” –– Michael Reynolds

                Comment


                • #23
                  Mình copy lại bài bên PICVietnam.com. Cái này viết cho PIC16. Với PIC18 thì thay header file trong I2C.c thành # include "pic18.h"

                  Tiếp theo là về module I2C, một chuẩn giao tiếp quan trọng khi giao tiếp với ngoại vi như EEPROM, RTS(DS1307),...

                  Do đó, mình xin cung cấp cho các bạn các hàm và thực thi của các hàm này trên HTPIC. Mình có tham khảo cả ở bọn htsoft nhưng nó viết sai một số hàm không chạy được, mình đã viết lại toàn bộ.

                  Đầu tiên là hàm I2C.h:

                  Code:
                  //I2C.h
                  //Declare some functions
                  void I2C_Init(void);          // khởi tạo I2C ở chế độ Master, Baud = 100 Khz
                  void I2C_waitForIdle(void); // Chờ khi nào đường bus ở chế độ Idle (rảnh rỗi)
                  void I2C_Start(void);        // Khởi động I2C - Master chiếm đường bus
                  void I2C_repStart(void);   // Chế độ Restart
                  void I2C_stop(void);         // Stop I2C - Master nhường đường bus cho thiết bị khác
                  unsigned char I2C_write( unsigned char I2CWriteData ); // ghi một byte lên đường SDA
                  unsigned char I2C_read( unsigned char ack ); // Đọc một byte với mã ACK (ACK = 0 nếu ack = 1, và ACK = 1 nếu ack = 0) -> dùng xác nhận từ master đối với slave.
                  void I2C_NACK(void);  // tạo bít Not Ack
                  Và sau đây là thực thi của các hàm này:

                  Code:
                  // I2C.c
                  # include "pic.h"
                  # include "I2C.h"
                  //======================================================================================================
                  void I2C_Init(void){
                  /*	// Configure for Master Mode
                  	SSPM3 = 1;
                  	SSPM2 = 0;
                  	SSPM1 = 0;
                  	SSPM0 = 0;				ss	// I2C Master Mode, clock = Fosc/(4*(SSPADD + 1));
                  	
                  	WCOL = 0;					//No conllision
                  	
                  	SSPEN = 1;					// Enables the serial port and 
                  */	
                  	SSPCON = 0b00101000;		// set IIC port to Master mode with BRG	
                  	SSPSTAT = 0b00000000;		// Standard speed mode - 100Hz
                  	SSPCON2 = 0;
                  	
                  	//TRIS_SCL = 0;
                  	//TRIS_SDA = 0;				// configure SDA and SCL as Output
                  	
                  	SSPADD = 9;			   	 // BAUD = 100KHz
                  	SSPIF = 0;      				// clear SSPIF interrupt flag
                   	BCLIF = 0;      				// clear bus collision flag
                  	STAT_CKE  = 0;     			// use I2C levels      worked also with '0'
                   	STAT_SMP = 1;     			// disable slew rate control  worked also with '0'
                  }
                  //=============================================================================
                  void I2C_waitForIdle(void)
                  {
                   	while (( SSPCON2 & 0x1F ) | STAT_RW) ; //CLRWDT(); // wait for idle and not writing
                  }
                  
                  //=============================================================================
                  void I2C_Start(void){
                  	//SSPIF = 0;
                  	SEN = 1;
                  	//while(!SSPIF);
                  	while(SEN);
                  }
                  //==============================================================================
                  void I2C_repStart(void)
                  {
                  	 I2C_waitForIdle();
                  	 RSEN = 1;
                  }
                  //=============================================================================
                  void I2C_stop(void)	
                  {
                  	 I2C_waitForIdle();
                  	 PEN = 1; 
                  }
                  //==============================================================================
                  unsigned char I2C_write( unsigned char I2CWriteData ){
                  	 I2C_waitForIdle();
                  	 SSPBUF = I2CWriteData;
                  	 I2C_waitForIdle();
                  	  return (!ACKSTAT); // function returns '1' if transmission is acknowledged	
                  	// 1: Success
                  	// 0: Fail to send 
                  }
                  //============================================================================
                  unsigned char I2C_read( unsigned char ack ){
                  	unsigned char I2C_ReadData;
                  	 I2C_waitForIdle();
                  	 RCEN = 1;
                  	 I2C_waitForIdle();
                  	 I2C_ReadData = SSPBUF;
                  	 I2C_waitForIdle();
                  	 if ( ack )  	ACKDT=0;
                      	 else             ACKDT = 1;
                   	 ACKEN = 1;               // send acknowledge sequence
                  	 I2C_waitForIdle();
                  	 return( I2C_ReadData );
                  }
                  /******************************************************************************************/
                  
                  void I2C_NACK(void)
                  {
                  	I2C_waitForIdle();
                  	if (ACKSTAT){
                  		PEN=1;						//Stop
                     		I2C_waitForIdle();			//Wait until action is finished
                  		while(PEN);
                     	};
                  }
                  Còn việc dùng nó quá đơn giản, ví dụ với Ds1307 thì đầu tiên bạn phải:

                  - Khởi tạo I2C bằng I2C_Start();
                  - Start bằng I2C_Start();
                  - Chọn slave giao tiếp bằng cách ghi địa chỉ và bit RW tương ứng với chế độ đọc hay ghi.
                  - Ghi dữ liệu lựa chọn byte nào cần ghi hay cần đọc trong bảng RAM của DS1307.
                  - Ghi dữ liệu hay là đọc dữ liệu.

                  Chú ý: khi ghi xong, muốn đọc thì phải làm lại tức là phải restart nhé.

                  Chúc các bạn thành công.
                  Technical sale at WT Microelectronics S'pore
                  Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
                  Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

                  Comment


                  • #24
                    chú ý: Đối với các chương trình yêu cầu đáp ứng thời gian thực,thì việc mô phỏng gần như botay, không thể chạy được và kết quả là bạn nhận 1 thông báo lõi.
                    Chúc vui!

                    Comment


                    • #25
                      Các bác xem giùm em sao em viết code như sau khi chạy chỉ xuất ra kết quả trên LCD như sau:
                      Time:00:00:00
                      Date:00/00/2000
                      Con số 2000 có vẻ như là năm 2000. Phải chăng con DS1307 của em chưa bóc tem ?
                      Code:
                      #include <pic18.h>
                      #include <stdio.h>
                      #include "delay.h"
                      #include "i2c.h"
                      #include "LCD.h"
                      
                      		               		
                      //***************************************************************************//
                      		__CONFIG(1,HSPLL & USBPLL	& PLLDIV5 & CPUDIV1 & FCMDIS & IESODIS);
                      		__CONFIG(2,VREGEN & PWRTDIS & BOREN & BORV20 & WDTDIS & WDTPS32K);
                      		__CONFIG(3,CCP2RC1 & PBADDIS & LPT1DIS & MCLREN);
                      		__CONFIG(4,STVREN & LVPDIS &  XINSTDIS & DEBUGDIS);
                      		__CONFIG(5,UNPROTECT);
                      		__CONFIG(6,UNPROTECT);
                      		__CONFIG(7,UNPROTECT);
                                     
                      //=============================================================================
                      
                      typedef unsigned char BYTE;
                      //==========================
                      // initial DS1307
                      //==========================
                      void init_DS1307()
                      {
                      	SSPMode(MASTER_MODE);
                      	
                      }
                      //==========================
                      // write data one byte to
                      // DS1307
                      //==========================
                      void write_DS1307(BYTE address, BYTE data)
                      {
                         short int status;
                         i2c_Start();
                         i2c_SendByte(0xd0);
                         i2c_SendByte(address);
                         i2c_SendByte(data);
                      //   i2c_Stop();
                         i2c_Restart();
                         status=i2c_SendByte(0xd0);
                         while(status==1)
                         {
                            i2c_Start();
                            status=i2c_SendByte(0xd0);
                         }
                      }
                      //==========================
                      // read data one byte from DS1307
                      //==========================
                      BYTE read_DS1307(BYTE address)
                      {
                         BYTE data;
                         i2c_Start();
                         i2c_SendByte(0xd0);
                         i2c_SendByte(address);
                         i2c_Start();
                         i2c_SendByte(0xd1);
                         data=i2c_GetByte(0);
                         i2c_Stop();
                         return(data);
                      }
                      
                      
                      void main(void)
                      {
                          int sec,min,hour,day,date,month,year;
                      	char buffer[16];
                      	//Timer
                      	T1CON = 0b00011101;		//Clock chia 2
                      
                      	LCD_Init();
                      	
                      	init_DS1307();
                      	sec=read_DS1307(0);
                          write_DS1307(0,sec & 0x7F); // enable oscillator(bit 7 =0)
                      
                         	while(1)
                         {
                           sec=read_DS1307(0);   // read second
                           min=read_DS1307(1);   // read minute
                           hour=read_DS1307(2);  // read hour
                           day=read_DS1307(3);   // read day
                           date=read_DS1307(4);  // read date
                           month=read_DS1307(5); // read month
                           year=read_DS1307(6);  // read year
                      
                           sprintf(buffer,"Time:%02X:%02X:%02X",hour,min,sec);
                      	 LCD_Gotoxy(1,1); //Cot 1, dong 2
                           LCD_WriteString(buffer);
                      
                           sprintf(buffer,"Date:%02X/%02X/20%02X\r\n",date,month,year); 
                      	 LCD_Gotoxy(1,2); //Cot 1, dong 2
                           LCD_WriteString(buffer);
                      
                           DelayBigMs(500);
                      	 CLRWDT();
                      	}
                      
                      }
                      Attached Files
                      “If you create your own electricity, heating and water systems, you create your own politics. Maybe that’s what they’re afraid of.” –– Michael Reynolds

                      Comment


                      • #26
                        Trước hết để kiểm tra thì bác nên ghi và đọc vài giá trị ở vị trí RAM DS1307 từ 08 trở lên xem sao, vì con này có 56 byte EEPROM nội cho người sử dụng lưu dữ liệu mà. Nếu nó chạy tốt thì coi như khởi tạo I2C đã thành công, sau đó tính tiếp!
                        Chào!
                        Last edited by natra2k2; 26-07-2007, 00:09.

                        Comment


                        • #27
                          Khi write vào con này bạn nên để thời gian trễ giữa 2 byte ghi. Khoảng 10ms là ổn.

                          Comment


                          • #28
                            Nguyên văn bởi natra2k2 Xem bài viết
                            Trước hết để kiểm tra thì bác nên ghi và đọc vài giá trị ở vị trí RAM DS1307 từ 08 trở lên xem sao, vì con này có 56 byte EEPROM nội cho người sử dụng lưu dữ liệu mà. Nếu nó chạy tốt thì coi như khởi tạo I2C đã thành công, sau đó tính tiếp!
                            Chào!
                            Mình đã có đọc chương trình của pác rồi nhưng có những cái mình chẳng hiểu kỹ tới!
                            ví dụ như các thanh ghi 'cờ':
                            FLAGS DATA 20H
                            LASTREAD BIT FLAGS.0
                            ACK BIT FLAGS.5
                            BUS_FLT BIT FLAGS.6
                            _2W_BUSY BIT FLAGS.7
                            mình chỉ thấy Pác STEB và CLR chứ chả so sánh để có một cái điều kiện j hết!
                            Pác có thể nói kỹ hơn về các chức năng của các thanh ghi này dc ko?
                            pác đã mô phỏng trên Proteus chưa? nếu có rồi thì gởi cho mình một bản với!
                            pác làm gởi nhanh cho mình nhé!
                            thanks!
                            Giúp nhau cùng tiến bộ....
                            Học học..... vì tất cả......

                            Comment


                            • #29
                              Đây là tài liệu của bác Phan_it bên dientuvietnam.com (hàm khởi tạo cho LCD bị sai một tý và một số chỗ nữa)
                              tham khảo rất hay, và còn nhiều nữa.
                              Attached Files

                              Comment


                              • #30
                                Nguyên văn bởi nhhlp2003 Xem bài viết
                                Đây là tài liệu của bác Phan_it bên dientuvietnam.com (hàm khởi tạo cho LCD bị sai một tý và một số chỗ nữa)
                                tham khảo rất hay, và còn nhiều nữa.
                                cho mình hỏi may thanh ghi nay nằm ở đâu vậy?? và tách dụng của nó để làm gì vậy?
                                MCON EQU 0C6H
                                PCON EQU 087H
                                TA EQU 0C7H

                                cho mình hỏi mấy dòng in chữ màu đỏ này có nghĩa là gì vậy?

                                START:
                                MOV TA,#0AAH ; Timed
                                MOV TA,#55H ; access.

                                MOV PCON,#0 ; Reset watchdog timer.
                                MOV MCON,#0F8H ; Turn off CE2 for
                                ; memory access.

                                MOV SP,#70H ; Position stack above
                                ; buffer.

                                và mấy thanh ghi trong các bản DB để làm j vậy:
                                CR EQU 0DH
                                LF EQU 0AH


                                mình cảm ơn bạn nhiều nhé!
                                Giúp nhau cùng tiến bộ....
                                Học học..... vì tất cả......

                                Comment

                                Về tác giả

                                Collapse

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

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

                                Collapse

                                Đang tải...
                                X