Thông báo

Collapse
No announcement yet.

Xử lý dữ liệu BCD trong DS1307

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

  • Xử lý dữ liệu BCD trong DS1307

    Hiện tôi đang làm một cái real time clock sử dụng con DS1307. Tôi đang gặp khó khăn khi xử lý dữ liệu lấy ra từ IC này. Không biết sau khi đã lấy dữ liệu ra rồi làm thế nào để gửi nó ra LCD đúng được? Tôi viết bằng mikroC. Tôi thấy mọi người bảo viết bằng assembly thì chỉ việc cộng 30h vào các thanh ghi khi gửi ra LCD là nó hiện ra số . Nhưng tôi viết bằng mikroC nên không biết là việc chuyển đổi BCD này như thế nào? Dưới đây là đoạn code tôi viêt:
    void READ_RTC() {
    I2C_Start();
    I2C_Wr(0xD1);
    *second = I2C_Rd(0x00);
    *minute = I2C_Rd(0x01);
    *hour = I2C_Rd(0x02);
    *day = I2C_Rd(0x03);
    *date = I2C_Rd(0x04);
    *month = I2C_Rd(0x05);
    *year = I2C_Rd(0x06);
    I2C_Stop();
    }

    /* XU LY DU LIEU RTC */
    void TRANSFORM_RTC() {
    switch (*day) {
    case 01: day_txt = "SUN";
    case 02: day_txt = "MON";
    case 03: day_txt = "TUE";
    case 04: day_txt = "WED";
    case 05: day_txt = "THU";
    case 06: day_txt = "FRI";
    default: day_txt = "SAT";
    }
    ....
    Mong mọi người chỉ giáo.
    Thanks!
    The road ahead

  • #2
    Đây là code đọc ngày tháng từ DS1307, hiển thị lên LCD(4bit mode)

    file i2c.h

    Code:
    void I2C_Init()		//Ham khoi tao I2C
    {
    	//Khoi tao chan SCL,SDA thanh INPUT
      	TRISC3=1;           
     	TRISC4=1;
    	//I2C o che do Master
      	SSPCON = 0x38;      //=0b00111000
      	/*
      	SSPEN = 1;
        I2C Master mode, clock = FOSC/(4 * (SSPADD + 1))
      	*/
     	SSPCON2 = 0x00;
    
    	SSPADD = 0x0C;	//400kHz - 20Mhz XTAL
    
     	STAT_CKE=1;     
     	STAT_SMP=1;     
    
     	PSPIF=0;      
     	BCLIF=0;      
    }
    //=====================================
    void I2C_NotBusy() //Cho den khi module I2C khong ban
    {
     	while (( SSPCON2 & 0x1F ) | STAT_RW ) {}; 
    }
    //=====================================
    void I2C_Start()  //Gui SEN de bat dau
    {
     	I2C_NotBusy();
     	SEN=1;
     	while(SEN);
    }
    //=====================================
    void I2C_RStart() //Gui RSEN
    {
     	I2C_NotBusy();
     	RSEN=1;
     	while(RSEN);
    }
    //=====================================
    void I2C_Stop()
    {
     	I2C_NotBusy();
     	PEN=1;
     	while(PEN);
    }
    //=====================================
    unsigned char I2C_Read(unsigned char ACK)  //Ham doc
    {
     unsigned char Data;
    
     I2C_NotBusy();
     RCEN=1;
     I2C_NotBusy();
     while(!STAT_BF);
     Data = SSPBUF; //Nhan du lieu
     I2C_NotBusy();
     if (ACK) ACKDT=0;
     else	ACKDT=1;
     ACKEN=1; 
     while(ACKEN);              
     return(Data);
    }
    //=====================================
    unsigned char I2C_Write( unsigned char WriteData)
    {
     	I2C_NotBusy();
     	SSPBUF = WriteData;
     	return (! ACKSTAT ); // 1 neu ghi thanh cong
    }

    Comment


    • #3
      file ds1307.h

      Code:
      //=======================================
      void RTC_Setup(char Reg,char Value)
      {
      	SEN = 1;					
      	while(SEN);					
      	ACKDT = 0;					
      		
      	SSPIF = 0;												
      	SSPBUF = 0xD0;				// Dia chi cua ds1307 la 0xD0
      	while(!SSPIF);				
      	SSPIF = 0;					
      		
      	SSPBUF = Reg;				// Thanh ghi cua ds1307
      	while(!SSPIF);				 
      	SSPIF = 0;					 
      
      	SSPBUF = Value;				// Ghi du lieu
      	while(!SSPIF);				
      	SSPIF = 0;					
      
      	PEN = 1;					
      	while(PEN);	
      }
      //========================================
      void RTC_Read(unsigned char *Buffer)	//Doc 8 bytes
      {
      	char i;
      	
      	I2C_Start();					
      	ACKDT = 0;					
      		
      	SSPIF = 0;												
      	SSPBUF = 0xD0;		//Dia chi ds1307
      	while(!SSPIF);		
      	SSPIF = 0;			
      		
      	SSPBUF = 0;
      	while(!SSPIF);
      	SSPIF = 0;		
      
      	I2C_RStart();					
      	
      	SSPIF = 0;
      	SSPBUF = 0xD1;	
      	while(!SSPIF);	
      	SSPIF = 0;		
      	
      	for(i=0;i<7;i++) //Doc 8 byte
      		{
      			Buffer[i]=I2C_Read(1);
      		}
      	Buffer[7] = I2C_Read(0); //Bytes cuoi	
       	I2C_Stop();
      }

      Comment


      • #4
        file main.c

        Code:
        #include <pic.h>
        #include "i2c.h"
        #include "LCD.h"
        #include "ds1307.h"
        
        __CONFIG(UNPROTECT & WDTDIS & HS & PWRTEN & BOREN & LVPDIS & DUNPROT & DEBUGDIS);
        
        //==========================================
        void delay1ms(unsigned int ms)
        	{
        		unsigned int count;
        		
        		T1CON = 0x00;
        		TMR1ON = 1;	
        		for (count=0;count<ms;count++)
        			{
        				CLRWDT();
        				TMR1ON = 0;
        				TMR1L = 0x54;
        				TMR1H = 0x0EC;
        				TMR1ON = 1;
        				while (!TMR1IF);
        				TMR1IF = 0;
        			}
        	}	
        //=========================================
        void Init()
        {
        	LCD_Init();
        	I2C_Init();
        }
        //==========================================
        void Update()
        {
        	unsigned char Time[8];
        	unsigned char rtensec,rsec,rtenmin,rmin,rtenhour,rhour,rday,rtendate,rdate,rmonth,rtenyear,ryear;
        	
        	RTC_Read(Time);
        	
        	rsec=(Time[0]&0x0f);				// seconds
        	rtensec=(Time[0]>>4);
        	rmin=(Time[1]&0x0f);				// minutes
        	rtenmin=(Time[1]>>4);
        	rhour=(Time[2]&0x0f);				// hours
        	rtenhour=(Time[2]>>4);
        
        	rday=(Time[3]&0x0f);				// weekday
        
        	rdate=(Time[4]&0x0f);				// date
        	rtendate=(Time[4]>>4);
        	rmonth=Time[5];						// month
        	ryear=(Time[6]&0x0f);				// year
        	rtenyear=(Time[6]>>4);
        	
        	if (rday==1){			
        		LCD_WriteString("Mon ");
        		}
        	else if (rday==2){		
        		LCD_WriteString("Tue ");
        		}
        	else if (rday==3){		
        		LCD_WriteString("Wed ");
        		}
        	else if (rday==4){		
        		LCD_WriteString("Thu ");
        		}
        	else if (rday==5){		
        		LCD_WriteString("Fri ");
        		}
        	else if (rday==6){		
        		LCD_WriteString("Sat ");
        		}
        	else if (rday==7){		
        		LCD_WriteString("Sun ");
        		}
        	
        	LCD_PutChar(rtenhour|0x30);
        	LCD_PutChar(rhour|0x30);
        	LCD_PutChar(':');
        	LCD_PutChar(rtenmin|0x30);
        	LCD_PutChar(rmin|0x30);
        	LCD_PutChar('.');
        	LCD_PutChar(rtensec|0x30);
        	LCD_PutChar(rsec|0x30);
        	
        	LCD_Gotoxy(1,2); //Cot 1, dong 2
        	
        	if (rmonth==0x01){			// january
        		LCD_WriteString("Jan ");
        					}
        	else if (rmonth==0x02){		// february
        		LCD_WriteString("Febr ");
        					}
        	else if (rmonth==0x03){		// march
        		LCD_WriteString("March ");
        					}
        	else if (rmonth==0x04){		// april
        		LCD_WriteString("April ");
        					}
        	else if (rmonth==0x05){		// may
        		LCD_WriteString("May ");
        					}
        	else if (rmonth==0x06){		// june
        		LCD_WriteString("June ");
        					}
        	else if (rmonth==0x07){		// july
        		LCD_WriteString("July ");
        					}
        	else if (rmonth==0x08){		// august
        		LCD_WriteString("August ");
        					}
        	else if (rmonth==0x09){		// september
        		LCD_WriteString("Sept ");
        					}
        	else if (rmonth==0x10){		// october
        		LCD_WriteString("Oct ");
        					}
        	else if (rmonth==0x11){		// november
        		LCD_WriteString("Nov ");
        					}
        	else if (rmonth==0x12){		// december
        		LCD_WriteString("Dec ");
        					}
        
        	LCD_PutChar(rtendate|0x30);
        	LCD_PutChar(rdate|0x30);
        	LCD_PutChar(' ');
        	LCD_PutChar('2');
        	LCD_PutChar('0');
        	LCD_PutChar(rtenyear|0x30);
        	LCD_PutChar(ryear|0x30);
        	
        }
        //=========================================
        void main()
        {	
        	Init();
        
        	//Thiet lap thoi gian dau cho ds1307
        	//chay lan dau de khoi tao thoi gian cho ds1307
        	//neu co pin thi khong can khoi tao lan sau
        	
        //	RTC_Setup(0,0x00); //Seconds
        //	RTC_Setup(1,0x53); //Minutes
        //	RTC_Setup(2,0x18); //Hours
        //	RTC_Setup(3,0x01); //Day
        //	RTC_Setup(4,0x20); //Date
        //	RTC_Setup(5,0x08); //Month
        //	RTC_Setup(6,0x06); //Year
        
        	while(1)
        		{	
        			LCD_Clear();
        			Update();
        			delay1ms(995); //cap nhat du lieu, co the dung chan SW dua vao RB0
        			CLRWDT();
        		}
        	
        }

        Trình dịch HTPICC cho PIC16, dùng 16F877A, file ds1307 có 2 hàm: setup và read dùng để thiết lập thời gian cho lần chạy đầu tiên và hàm đọc thời gian.

        Comment


        • #5
          bác nào có code ds1307 của CCS ko nhỉ
          SHARE KHO PHIM LỚN

          Comment


          • #6
            em mới thấy code ds1307 bằng assembly của anh mafd_47 thôi chứ chưa thấy bằng ccs bao giờ
            Last edited by namdinhno1; 08-06-2007, 21:50.
            hi

            Comment


            • #7
              Tôi cũng không hiểu được diễn đàn này ra sao nữa, toàn những thằng ăn không nói có, đã thấy bàn toàn những chuyện cao siêu để bây giờ lại quay lại hỏi những chuyện đơn giản như vậy, tôi thấy cần phải kiểm tra lại khả năng của những người điều hành cho đến nhưng người dã tham gia lâu năm cái mà người ta gọi là "thành viên tích cực" nữa, không thì dần sẽ không ai thèm tham gia vào diễn đàn này nứa đâu! nhục quá mấy thằng!

              Comment


              • #8
                Nguyên văn bởi tinhthanthep Xem bài viết
                Hiện tôi đang làm một cái real time clock sử dụng con DS1307. Tôi đang gặp khó khăn khi xử lý dữ liệu lấy ra từ IC này. Không biết sau khi đã lấy dữ liệu ra rồi làm thế nào để gửi nó ra LCD đúng được? Tôi viết bằng mikroC. Tôi thấy mọi người bảo viết bằng assembly thì chỉ việc cộng 30h vào các thanh ghi khi gửi ra LCD là nó hiện ra số . Nhưng tôi viết bằng mikroC nên không biết là việc chuyển đổi BCD này như thế nào? Dưới đây là đoạn code tôi viêt:
                void READ_RTC() {
                I2C_Start();
                I2C_Wr(0xD1);
                *second = I2C_Rd(0x00);
                *minute = I2C_Rd(0x01);
                *hour = I2C_Rd(0x02);
                *day = I2C_Rd(0x03);
                *date = I2C_Rd(0x04);
                *month = I2C_Rd(0x05);
                *year = I2C_Rd(0x06);
                I2C_Stop();
                }

                /* XU LY DU LIEU RTC */
                void TRANSFORM_RTC() {
                switch (*day) {
                case 01: day_txt = "SUN";
                case 02: day_txt = "MON";
                case 03: day_txt = "TUE";
                case 04: day_txt = "WED";
                case 05: day_txt = "THU";
                case 06: day_txt = "FRI";
                default: day_txt = "SAT";
                }
                ....
                Mong mọi người chỉ giáo.
                Thanks!
                Bác dùng VDK gi vậy? Có dùng AVR chưa? Dùng nó thì công việc còn lại chỉ là đọc datasheet thôi. Chúc bác thành công!
                Nỏ biết chữ mần răng ký được??!! Thôi nhé.

                Comment


                • #9
                  Nguyên văn bởi linhleduong Xem bài viết
                  Tôi cũng không hiểu được diễn đàn này ra sao nữa, toàn những thằng ăn không nói có, đã thấy bàn toàn những chuyện cao siêu để bây giờ lại quay lại hỏi những chuyện đơn giản như vậy, tôi thấy cần phải kiểm tra lại khả năng của những người điều hành cho đến nhưng người dã tham gia lâu năm cái mà người ta gọi là "thành viên tích cực" nữa, không thì dần sẽ không ai thèm tham gia vào diễn đàn này nứa đâu! nhục quá mấy thằng!
                  Có gì đâu mà nhục hả bác , không biết thì hỏi , quên thì học lại . Có phải cái gì cũng nhớ được hết cả đâu .

                  Bây giờ tôi còn chẳng nhớ trước đây mình đã quấn cái biến thế như thế nào nữa .

                  Bác biết không , hồi phổ thông tôi đi thi lập trình PASCAL được giải thành phố .
                  Bây giờ tôi cũng chẳng nhớ là nó thế nào .

                  Văn không ôn , võ không luyện nó " yếu công lực " - công lực giảm sút là chuyện thường ngày ở Huyện mà.

                  Đôi khi người ta tự bái phục mình và tự nhủ : Không biết là vì lý do gì mà ngày đó mình đã thành công đến vậy.
                  Module RF chuyên dụng điều khiển, truyền dữ liệu, thiết kế đề tài, dự án điện tử - chuyển giao công nghệ... ĐT: 0904964977 - email: dientuqueduong@yahoo.com

                  Comment


                  • #10
                    RealTime PIC18f4520

                    em xai PIC18f4520 May anh cho em hoi chut xi' ve real time di . e chi mun doc thoi gian co san~ trong realtime ra va viet no vo thi sao ha~ may anh hix hix giup em xi' em xai thu SW_I2C ak' chu hem phai I2C hix hix ....thanks may anh truoc nha ............

                    Comment


                    • #11
                      em dùng píc6f877a để đọc ds1307 lên lcd 4 bit mà khó quá toàn sai dữ liệu thôi, bạn nào có code cho mình tham khảo vơi? thank!

                      Comment

                      Về tác giả

                      Collapse

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

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

                      Collapse

                      Đang tải...
                      X