Thông báo

Collapse
No announcement yet.

vài thắc mắc về ds1307 mong được giải đáp

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

  • vài thắc mắc về ds1307 mong được giải đáp

    Em đã có làm 1 vài project với 89c51, gần đây mới bắt tay làm cái đồng hồ. Qua nghiên cứu thì có thấy mọi người sử dụng con ds1307. Xem qua nhiều hướng dẫn và những sản phẩm của mọi người cũng hơi hiểu 1 tý, nhưng vẫn còn 1 vài thắc mắc mong mọi người giải đáp giúp. Về phần cứng không có gì đặc biệt, chủ yếu là phần mềm :
    1. em thường thấy phần code của mọi người có nhiều file : ds1307.c, main.c, hienthi.c không hiểu là các file này được sử dụng để include vào rồi nạp vào 89c51 hay là sử dụng ở nhiều nơi khác nhau.
    2. nếu các file trên thực ra trong 1 file main.c thì file main.c cần những đoạn code nào để có thể hoạt động?
    3. dữ liệu nhận được từ ds1307 có dạng nào? thông qua biến nào?

    VD 1 project đơn giản như sau :
    mạch như hvẽ
    yêu cầu : tính theo phút, nếu phút 1 -> 10 sáng led1, 11->20 sáng led2, ..., 51->60 sáng led6

    các anh viết hộ hàm main(nhận dữ liệu và lệnh điều kiện và bật led).


    Xin chân thành cảm ơn !!!
    Attached Files

  • #2
    hjk, nhiều người xem mà hok ai chịu giúp

    Tình hình là em cũng đã làm được phần nào rồi.
    mạch như trên
    Code đã chạy, nhưng em chưa bít sử dụng các biến như thế nào để đọc được dữ liệu, mong mọi người giải đáp
    Phần đọc, ghi, set time thì không có gì. Em gặp vấn đề về cách lấy giá trị của biến ra để sử dụng

    Giá trị được lưu vào mảng unsigned char RTC_ARR[7];. Nhưng khi lấy P2=BCD2HEX(RTC_ARR[0]); thì không thấy có hiện tượng gì xảy ra (đoạn cuối cùng phần code)

    Code như sau :
    Code:
    #include<reg8252.h>
    #include<stdio.h>
    #include<intrins.h>
    unsigned char  RTC_ARR[7];  // second,minute,.....,year
    unsigned char p;
    unsigned char i;
    const unsigned char * DayStr[7]  =     {{"Sun"},{"Mon"},{"Tue"},{"Wen"},{"The"},{"Fri"},{"Sat"}};
    const unsigned char * MonthStr[12]    ={{"Jan"},{"Feb"},{"Mar"},{"Apr"},{"May"},{"Jun"},{"Jul"},{"Aug"},{"Sep"},{"Oct"},{"Nov"},{"Dec"}};
    sbit SDA  =  P0^1;
    sbit SCL  =  P0^0;
    #define ACK		1
    #define NO_ACK	0
    #define SLAVE	0xD0
    #define WRITE   0x00
    #define READ    0x01
    #define ERR_ACK 0x01
    
    void DelayMs(unsigned int count) 
    { 
        unsigned int i;		       	
        while(count) 
    	{
            i = 115; 
    		while(i>0) i--;
            count--;
        }
    }
    
    unsigned char BCD2HEX(unsigned int bcd)
    {
    	unsigned char temp;
    	temp=((bcd>>8)*100)|((bcd>>4)*10)|(bcd&0x0f);
    	return temp;
    	
    }
    
    // start I2C
    void Start(void)
    {
        SDA = 1;
    	SCL = 1;
    	_nop_();_nop_();
    	SDA = 0;
    	_nop_();_nop_();
    	SCL = 0;
    	_nop_();_nop_();
    }
    
    // stop I2C
    void Stop(void)
    {
    	SDA = 0;	    	
    	_nop_();_nop_();
    	SCL = 1;
    	_nop_();_nop_();
    	SDA = 1;	
    }
    
    // Write I2C
    void WriteI2C(unsigned char Data)
    {    
    
    	for (i=0;i<8;i++)
    	{
            SDA = (Data & 0x80) ? 1:0;
    		SCL=1;SCL=0;
    		Data<<=1;
    	}
      	SCL = 1; 
    	_nop_();_nop_();
    	SCL = 0;
    }
    
    // Read I2C
    unsigned char ReadI2C(bit ACK_Bit)
    {
        unsigned char Data=0;
        SDA = 1;	
    	for (i=0;i<8;i++)
    	{
    		SCL   = 1;		
    		Data<<= 1;
    		Data  = (Data | SDA);		
    		SCL   = 0;
    		_nop_();
    	}
        
     	if (ACK_Bit == 1)
    	SDA = 0; // Send ACK		
    	else		
    	SDA = 1; // Send NO ACK				
    
    	_nop_();_nop_();
    	SCL = 1;		
    	_nop_();_nop_();
    	SCL = 0;
    	
    	return Data;
    }
    
    void ReadRTC(unsigned char * buff)
    {
    	Start();
    	WriteI2C(0xD0);
    	WriteI2C(0x00);
    
    	Start();
    	WriteI2C(0xD1);	
    	*(buff+0)=ReadI2C(ACK);	// Second
    	*(buff+1)=ReadI2C(ACK);	// Minute
    	*(buff+2)=ReadI2C(ACK);	// hour
    	*(buff+3)=ReadI2C(ACK);	// Day
    	*(buff+4)=ReadI2C(ACK);	// date
    	*(buff+5)=ReadI2C(ACK);	// month
    	*(buff+6)=ReadI2C(NO_ACK);	// year
    	Stop();		
    }
    
    void WriteRTC(unsigned char *buff)
    {
    	Start();
    	WriteI2C(0xD0);
    	WriteI2C(0x00);	
    	WriteI2C(*(buff+0));	
    	WriteI2C(*(buff+1));
    	WriteI2C(*(buff+2));
    	WriteI2C(*(buff+3));
    	WriteI2C(*(buff+4));
    	WriteI2C(*(buff+5));
    	WriteI2C(*(buff+6));	
    	Stop();	
    }
    
    // Main program
    void main(void)
    {
    	ReadRTC(&RTC_ARR[0]);        
    	RTC_ARR[0] = RTC_ARR[0] & 0x7F;	// enable oscillator (bit 7=0)
    	RTC_ARR[1] = 0x59;	// minute = 59
    	RTC_ARR[2] = 0x23;	// hour = 05 ,24-hour mode(bit 6=0)
    	RTC_ARR[3] = 0x04;	// Day = 1 or sunday
    	RTC_ARR[4] = 0x31;	// Date = 30
    	RTC_ARR[5] = 0x10;	// month = August
    	RTC_ARR[6] = 0x05;	// year = 05 or 2005  
    	WriteRTC(&RTC_ARR[0]);	// Set RTC
    
    	while(1)
    	{
    		ReadRTC(&RTC_ARR[0]);        
    		putchar(0x0C);  // clear Hyper terminal
    
    		P2=BCD2HEX(RTC_ARR[0]);
    
    		DelayMs(1000);	// delay about 1 second
    	}
    }

    Comment


    • #3

      nếu t k nhầm , đây là 1 code trong DS1307 driver từ trang www.GetMicro.com
      nguyên bản của nó là
      Code:
      //---------------------------------------
      // DS1307 driver
      // www.GetMicro.com
      //---------------------------------------
      #include<reg8252.h>
      #include<delay.h>
      #include<intrins.h>
      
      #define ACK		1
      #define NO_ACK	0
      #define SLAVE	0xD0
      #define WRITE   0x00
      #define READ    0x01
      #define ERR_ACK 0x01
      
      
      unsigned char i;
      
      const unsigned char * DayStr[7]  =     {{"Sun"},
      				   						{"Mon"},
      				   						{"Tue"},
      				   						{"Wen"},
      				   						{"The"},
      				   						{"Fri"},
      				   						{"Sat"}};
      
      
      const unsigned char * MonthStr[12]    ={{"Jan"},
      										{"Feb"},
      										{"Mar"},
      										{"Apr"},
      										{"May"},
      										{"Jun"},
      										{"Jul"},
      										{"Aug"},
      										{"Sep"},
      										{"Oct"},
      										{"Nov"},
      										{"Dec"}};
      
      
      sbit SDA  =  P2^1;	// connect to SDA pin (Data)
      sbit SCL  =  P2^0;	// connect to SCL pin (Clock)
      
      
      
      //-------------------------------
      // Convert BCD 1 byte to HEX 1 byte
      //-------------------------------
      unsigned char BCD2HEX(unsigned int bcd)
      {
      	unsigned char temp;
      	temp=((bcd>>8)*100)|((bcd>>4)*10)|(bcd&0x0f);
      	return temp;
      	
      }
      
      //-------------------------------
      // start I2C
      //-------------------------------
      void Start(void)
      {
          SDA = 1;
      	SCL = 1;
      	_nop_();_nop_();
      	SDA = 0;
      	_nop_();_nop_();
      	SCL = 0;
      	_nop_();_nop_();
      }
      
      //-------------------------------
      // stop I2C
      //-------------------------------
      void Stop(void)
      {
      	SDA = 0;	    	
      	_nop_();_nop_();
      	SCL = 1;
      	_nop_();_nop_();
      	SDA = 1;	
      }
      
      //-------------------------------
      // Write I2C
      //-------------------------------
      void WriteI2C(unsigned char Data)
      {    
      
      	for (i=0;i<8;i++)
      	{
              SDA = (Data & 0x80) ? 1:0;
      		SCL=1;SCL=0;
      		Data<<=1;
      	}
      
        	SCL = 1; 
      	_nop_();_nop_();
      	SCL = 0;
      
      }
      
      //-------------------------------
      // Read I2C
      //-------------------------------
      unsigned char ReadI2C(bit ACK_Bit)
      {
          
          unsigned char Data=0;
      
          SDA = 1;	
      	for (i=0;i<8;i++)
      	{
      		SCL   = 1;		
      		Data<<= 1;
      		Data  = (Data | SDA);		
      		SCL   = 0;
      		_nop_();
      	}
          
       	if (ACK_Bit == 1)
      	SDA = 0; // Send ACK		
      	else		
      	SDA = 1; // Send NO ACK				
      
      	_nop_();_nop_();
      	SCL = 1;		
      	_nop_();_nop_();
      	SCL = 0;
      	
      	return Data;
      }
      
      //-------------------------------
      // Read 1 byte form I2C
      //-------------------------------
      unsigned char ReadBYTE(unsigned char Addr)
      {
         	unsigned char Data;
      	Start();
      	WriteI2C(0xD0);
      	WriteI2C(Addr);
      	Start();
      	WriteI2C(0xD1);
      	Data = ReadI2C(NO_ACK);
      	Stop();
         	return(Data);
      }
      
      //-------------------------------
      // Write 1 byte to I2C
      //-------------------------------
      void WriteBYTE(unsigned char Addr,unsigned char Data)
      {
      	Start();
      	WriteI2C(0xD0);
      	WriteI2C(Addr);
      	WriteI2C(Data);
      	Stop();	
      }
      
      //-------------------------------
      // Read RTC (all real time)
      //-------------------------------
      void ReadRTC(unsigned char * buff)
      {
      	
      	
      	Start();
      	WriteI2C(0xD0);
      	WriteI2C(0x00);
      
      	Start();
      	WriteI2C(0xD1);	
      	*(buff+0)=ReadI2C(ACK);	// Second
      	*(buff+1)=ReadI2C(ACK);	// Minute
      	*(buff+2)=ReadI2C(ACK);	// hour
      	*(buff+3)=ReadI2C(ACK);	// Day
      	*(buff+4)=ReadI2C(ACK);	// date
      	*(buff+5)=ReadI2C(ACK);	// month
      	*(buff+6)=ReadI2C(NO_ACK);	// year
      	Stop();		
      }
      
      //-------------------------------
      // Write RTC
      //-------------------------------
      void WriteRTC(unsigned char *buff)
      {
      
      	Start();
      	WriteI2C(0xD0);
      	WriteI2C(0x00);	
      	WriteI2C(*(buff+0));	
      	WriteI2C(*(buff+1));
      	WriteI2C(*(buff+2));
      	WriteI2C(*(buff+3));
      	WriteI2C(*(buff+4));
      	WriteI2C(*(buff+5));
      	WriteI2C(*(buff+6));	
      	Stop();	
      }
      
      //-------------------------------
      // Convert date (BCD) to string of Day
      // 1=Sanday
      // 2=Monday
      // And so on
      //------------------------------- 
      char * Int2Day(unsigned char day)
      {
      	return DayStr[day-1];
      }
      
      //-------------------------------
      // Convert month (BCD) to string of Month
      // 0x01=January
      // 0x02=February
      // ...........
      // 0x12 = December
      // And so on
      //------------------------------- 
      char * Int2Month(unsigned char month)
      {
        return MonthStr[BCD2HEX(month)-1];
      }

      con DS1307 này khi t làm cũng khá chật vật , nó k khó nhưng vì data ghi vào con này và nhận về phải là BCD nên cứ lộn tùng phèo những BCD và HEX . Khi nhận ra đc vấn đề thì t tự viết code , đơn giản như sau :
      Code:
      //============= RTC DS1307 ==================
      void start(void)
      { SCL=0;SDA=1;SCL=1;SCL=1;
        SDA=0;SCL=0;}
      void stop(void)
      { SCL=0;SDA=0;SCL=1;SDA=1;}
      bit write_data(unsigned char chr)
      { unsigned char temp,ack;
        for(temp=0;temp<8;temp++)
          { SDA = (chr& 0x80) ? 1:0;
            SCL=1;
            SCL=0;
            chr=chr<<1;
          };
        SDA=1;SCL=1;ack=SDA;
        SCL=0;
        return(ack);
      }
      unsigned char convertBCD(unsigned char _data)
      { unsigned char temp;
        temp=(_data/10<<4)|(_data%10&0x0F);
        return temp;
      }
      unsigned char read_data(void)
      { unsigned char temp1,temp2=0;
        for(temp1=0;temp1<8;temp1++)
          { SCL=1;
            temp2=temp2<<1;
            temp2=temp2|((unsigned char)(SDA));
            SCL=0;
          };
        return(temp2);
      }
      void write_RTC(unsigned char address, unsigned char _data)
      { bit status;
        start();
        write_data(0xD0);
        write_data(address);
        write_data(_data);
        stop();
        start();
        status=write_data(0xD0);
        while(status)	 //status = 1 (NACK)
             { start();
              status=write_data(0xd0);
             };
      }
      unsigned char read_RTC(unsigned char address)
      { unsigned char k;
        start();
        write_data(0xD0);
        write_data(address);
        start();
        write_data(0xD1);
        k=read_data();
        stop();
        return ((k>>4)*10+(k&0x0F));
      }
      void init_RTC()
      { write_RTC(0x07,0x10); 
        write_RTC(0x00,0x00); //0s
        write_RTC(0x01,0x01); // phut	: 01
        write_RTC(0x02,0x22);// h : 22
        write_RTC(0x04,0x25);// ngay : 25
        write_RTC(0x05,0x06);// thang : 6
        write_RTC(0x06,0x09);// nam : 2009
      }
      
      void external_INT0() interrupt 0
      { IE0=0; // xoa co ngat
        if(first==0)
        	{giay =read_RTC(0x00);
        	 phut =read_RTC(0x01);
           gio  =read_RTC(0x02);
        	 ngay =read_RTC(0x04);
        	 thang=read_RTC(0x05);
        	 nam  =read_RTC(0x06);
        	 alarm1=read_RTC(0x08);
      	 alarm2=read_RTC(0x09);
      	 first=1;
          }
        else 
          {giay=read_RTC(0x00);
           if(alarm_fag==1)alarm2=read_RTC(0x09);
      	 if(giay==0)
      	 	{phut=read_RTC(0x01);
      		 if(alarm_fag==1)alarm1=read_RTC(0x08);
      		 if(phut==0)
      		    {gio=read_RTC(0x02);
      			 if(gio==0)
      			 	{ngay=read_RTC(0x04);
      			     if(ngay==1)
      				   {thang=read_RTC(0x05);
      					if(thang==1)nam=read_RTC(0x06);
      				   }
      				}
      			}
      		}
      	}
      
      }


      Comment


      • #4
        thx bạn đã quan tâm.
        Lúc chiều ngồi mò mẫm cũng làm đc rùi, tại nó có cái putchar(0x0C); // clear Hyper terminal đâm ra nó xóa hết buffer, chả hiểu nữa, bỏ đi thì đc. Mình viết thêm cái chuyển từ BCD sang DEC nữa, dùng cho tiện, dùng 10 chữ số quen rồi

        Nhg mà mô phỏng xong, đi mua kon ds1307 thì ng ta giả nhời "hem cóa"

        Mình ở Hải Phòng, bác nào bik ở đâu của HP có bán ds1307 và thạch anh 32.768 thì chỉ mình với

        Comment

        Về tác giả

        Collapse

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

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

        Collapse

        Đang tải...
        X