Thread: Im doing c programming on 8051 and DS1302(RTC) to show time on LCD,there a problem..

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    21

    Im doing c programming on 8051 and DS1302(RTC) to show time on LCD,there a problem..

    Im doing c programming on 8051 and DS1302(RTC) to show time on LCD,there a problem..
    I have program a c code and modify a header file of DS1302 which i got online.
    I want to print out 23:59:45 on my LCD.
    But the problem is it only print out 23:59:85 on the LCD.
    Other than that,it move from left to right.
    It look something like that >>>>>> "23:59:85"
    >>>>>> "ll23:59:8"
    >>>>>> "5ll23:59:"
    This is only the first 3 pattern of the problem. This continue move from left to right.
    So what can be the problem??
    Is there anything which i need to modify in my header file or the c code???
    There is some part of code of the DS1302 header file which i do not understand.
    I do need help.. Please take a look and help me check too. Thanks


    I will show my c code and the modify header file of DS1302 below.



    Here is the c code

    [tag]
    Code:
    /*******************************************/
    /* define the button name and the lcd pin  */
    /*******************************************/		
    #define E  			P1_2			//LCD E
    #define RW 			P1_1			//LCD RW
    #define RS 			P1_0			//LCD RS
    #define LCD_DATA		P2			//LCD Data port
    SYSTEMTIME CurrentTime;
    
    /************************************/
    /*    Function that going to use    */
    /************************************/
    void delay(unsigned int);  		    //software delay
    void strobe(void);		            //write in data
    void LCD_init(void);		        //LCD initialisation
    void LCD_print(unsigned char);      //print on LCD
    void LCD_command(unsigned char);  	//to set instruction to cursor
    void LCD_TimerDisp();				//Show time
    
    /*****************/
    /* Main function */
    /*****************/
    void main(void)
    {	
    	unsigned char i;
    
    	for(i=0; i<20; i++)
    		delay(500);
    	
    	LCD_init();
    
    	DS1302_SetTime(DS1302_SECOND, 45);
    	DS1302_SetTime(DS1302_MINUTE, 59);
    	DS1302_SetTime(DS1302_HOUR, 23);
    
    	LCD_TimerDisp();
    		
    	while(1)
    	{	
    	}
    }
    
    /************/
    /* Function */
    /************/
    
    void delay(unsigned int y)
    {
    	unsigned int x;
    	for(x=0; x<y; x++);
    }
    
    void strobe()		//write in data
    {
    	E = 1;
    	delay(500);
    	E = 0;
    	delay(500);
    }
    
    void LCD_init()		//LCD initialisation
    {
    	RS = 0;
    	RW = 0;
    	LCD_DATA = 0x38;
    	strobe();
    	LCD_DATA = 0x0c;
    	strobe();
    	LCD_DATA = 0x01;
    	strobe();
    	LCD_DATA = 0x06;
    	strobe();
    }
    
    void LCD_print(unsigned char alpha)  //print on LCD
    {
    	RS = 1;     //data type
    	RW = 0;     //write enable
    	LCD_DATA = alpha; //LCD D0 to D7
    	strobe();
    }
    
    void LCD_command(unsigned char beta)	//to set instruction to cursor
    {
    	RS = 0;     //data type
    	RW = 0;     //write enable
    	LCD_DATA = beta;
    	strobe();
    }
    
    void LCD_TimerDisp()
    {
    
    	unsigned char alphabet;	
    
    	do
    	{
    	DS1302_GetTime(&CurrentTime);
    	DateToStr(&CurrentTime);
    	TimeToStr(&CurrentTime);
    	LCD_command(0x06);
    	for(alphabet=0; alphabet<9; alphabet++)
    	{
    		LCD_print(CurrentTime.TimeString[alphabet]);
    	}
    	delay(300);
    	}while(1);
    }
    [/tag]


    Here is the modify header file of DS1302

    [tag]
    Code:
    /***************************************************************************/ 
    #ifndef _REAL_TIMER_DS1302_2003_7_21_ 
    #define _REAL_TIMER_DS1302_2003_7_21_ 
     
    sbit  DS1302_CLK = P1^7;              //实时时钟时钟线引脚  
    sbit  DS1302_IO  = P1^6;              //实时时钟数据线引脚  
    sbit  DS1302_RST = P1^5;              //实时时钟复位线引脚 
    sbit  ACC0 = ACC^0; 
    sbit  ACC7 = ACC^7; 
     
    typedef struct __SYSTEMTIME__ 
    { 
    	unsigned char Second; 
    	unsigned char Minute; 
    	unsigned char Hour; 
    	unsigned char Week; 
    	unsigned char Day; 
    	unsigned char Month; 
    	unsigned char Year; 
    	unsigned char DateString[9]; 
    	unsigned char TimeString[9]; 
    }SYSTEMTIME;	//定义的时间类型 
     
    #define AM(X)	X 
    #define PM(X)	(X+12)            	  // 转成24小时制 
    #define DS1302_SECOND	0x80 		  
    #define DS1302_SECOND_READ	0x81 
    #define DS1302_MINUTE	0x82
    #define DS1302_MINUTE_READ	0x83 
    #define DS1302_HOUR		0x84
    #define DS1302_HOUR_READ	0x85  
    #define DS1302_WEEK		0x8A 
    #define DS1302_DAY		0x86 
    #define DS1302_MONTH	0x88 
    #define DS1302_YEAR		0x8C 
    #define DS1302_RAM(X)	(0xC0+(X)*2)   	//用于计算 DS1302_RAM 地址的宏
    
    
    void DS1302InputByte(unsigned char d) 	//实时时钟写入一字节(内部函数) 
    {  
        unsigned char i; 
        ACC = d; 
        for(i=8; i>0; i--) 
        { 
            DS1302_IO = ACC0;           	//相当于汇编中的 RRC 
            DS1302_CLK = 1; 
            DS1302_CLK = 0; 
            ACC = ACC >> 1;  
        }  
    } 
     
    unsigned char DS1302OutputByte(void) 	//实时时钟读取一字节(内部函数) 
    {  
        unsigned char i; 
        for(i=8; i>0; i--) 
        { 
            ACC = ACC >>1;         			//相当于汇编中的 RRC  
            ACC7 = DS1302_IO; 
            DS1302_CLK = 1; 
            DS1302_CLK = 0; 
        }  
        return(ACC);  
    } 
     
    void Write1302(unsigned char ucAddr, unsigned char ucDa)	//ucAddr: DS1302地址, ucData: 要写的数据 
    { 
        DS1302_RST = 0; 
        DS1302_CLK = 0; 
        DS1302_RST = 1; 
        DS1302InputByte(ucAddr);       	// 地址,命令  
        DS1302InputByte(ucDa);       	// 写1Byte数据 
        DS1302_CLK = 1; 
        DS1302_RST = 0; 
    }  
     
    unsigned char Read1302(unsigned char ucAddr)	//读取DS1302某地址的数据 
    { 
        unsigned char ucData; 
        DS1302_RST = 0; 
        DS1302_CLK = 0; 
        DS1302_RST = 1; 
        DS1302InputByte(ucAddr|0x01);        // 地址,命令  
        ucData = DS1302OutputByte();         // 读1Byte数据 
        DS1302_CLK = 1; 
        DS1302_RST = 0; 
        return(ucData); 
    } 
     
    void DS1302_SetProtect(bit flag)        //是否写保护 
    { 
    	if(flag) 
    		Write1302(0x8E,0x10); 
    	else 
    		Write1302(0x8E,0x00); 
    } 
     
    void DS1302_SetTime(unsigned char Address, unsigned char Value)        // 设置时间函数 
    { 
    	DS1302_SetProtect(0); 
    	Write1302(Address, ((Value/10)<<4 | (Value%10)));  
    } 
     
    void DS1302_GetTime(SYSTEMTIME *Time) 
    { 
    	unsigned char ReadValue; 
    	ReadValue = Read1302(DS1302_SECOND_READ); 
    	Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); 
    	ReadValue = Read1302(DS1302_MINUTE_READ); 
    	Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); 
    	ReadValue = Read1302(DS1302_HOUR_READ); 
    	Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); 
    	ReadValue = Read1302(DS1302_DAY); 
    	Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);	 
    	ReadValue = Read1302(DS1302_WEEK); 
    	Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); 
    	ReadValue = Read1302(DS1302_MONTH); 
    	Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); 
    	ReadValue = Read1302(DS1302_YEAR); 
    	Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);	 
    } 
     
    void DateToStr(SYSTEMTIME *Time) 
    { 
    	Time->DateString[0] = Time->Year/10 + '0'; 
    	Time->DateString[1] = Time->Year%10 + '0'; 
    	Time->DateString[2] = '-'; 
    	Time->DateString[3] = Time->Month/10 + '0'; 
    	Time->DateString[4] = Time->Month%10 + '0'; 
    	Time->DateString[5] = '-'; 
    	Time->DateString[6] = Time->Day/10 + '0'; 
    	Time->DateString[7] = Time->Day%10 + '0'; 
    	Time->DateString[8] = '\0'; 
    } 
     
    void TimeToStr(SYSTEMTIME *Time) 
    { 
    	Time->TimeString[0] = Time->Hour/10 + '0'; 
    	Time->TimeString[1] = Time->Hour%10 + '0'; 
    	Time->TimeString[2] = ':'; 
    	Time->TimeString[3] = Time->Minute/10 + '0'; 
    	Time->TimeString[4] = Time->Minute%10 + '0'; 
    	Time->TimeString[5] = ':'; 
    	Time->TimeString[6] = Time->Second/10 + '0'; 
    	Time->TimeString[7] = Time->Second%10 + '0'; 
    	Time->DateString[8] = '\0'; 
    } 
    /*  
    void Initial_DS1302(void) 
    { 
    	unsigned char Second=Read1302(DS1302_SECOND); 
    	if(Second&0x80)		   
    		DS1302_SetTime(DS1302_SECOND,0); 
    } 
    
     
    void BurstWrite1302(unsigned char *pWClock)	//往DS1302写入时钟数据(多字节方式) 
    { 
        unsigned char i; 
        Write1302(0x8e,0x00);         	// 控制命令,WP=0,写操作? 
        DS1302_RST = 0; 
        DS1302_CLK = 0; 
        DS1302_RST = 1; 
        DS1302InputByte(0xbe);        	// 0xbe:时钟多字节写命令 
        for (i = 8; i>0; i--)     		//8Byte = 7Byte 时钟数据 + 1Byte 控制 
        { 
            DS1302InputByte(*pWClock); 	// 写1Byte数据 
            pWClock++; 
        } 
        DS1302_CLK = 1; 
        DS1302_RST = 0; 
    }*/
    /******************************************************************************** 
    void BurstRead1302(unsigned char *pRClock)	//读取DS1302时钟数据(时钟多字节方式) 
    { 
        unsigned char i; 
        DS1302_RST = 0; 
        DS1302_CLK = 0; 
        DS1302_RST = 1; 
        DS1302InputByte(0xbf);             	// 0xbf:时钟多字节读命令  
        for (i=8; i>0; i--)  
        { 
           *pRClock = DS1302OutputByte();   // 读1Byte数据  
           pRClock++; 
        } 
        DS1302_CLK = 1; 
        DS1302_RST = 0; 
    } 
     
    void DS1302_TimeStop(bit flag)           // 是否将时钟停止 
    { 
    	unsigned char Data; 
    	Data=Read1302(DS1302_SECOND); 
    	DS1302_SetProtect(0); 
    	if(flag) 
    		Write1302(DS1302_SECOND, Data|0x80); 
    	else 
    		Write1302(DS1302_SECOND, Data&0x7F); 
    } 
    ********************************************************************************/ 
    #endif
    [/tag]

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Your compiler may optimize out your delay function's loop entirely. Also, why do you call delay in a loop, insted of just using delay( 10000 )? Completely not your issue, but I'm not sure why you are doing it that way. Also, the empty infinite loop at the bottom of main, why? Just have it wait for you to hit enter by calling fgetc(stdin) or something.

    You are also not showing us a whole bunch of stuff, because you don't actually have any variable called E anywhere in the code you've given (and yes, I realize it's a macro, but you still are treating it like it's an actual variable some place, no matter what it is called in the end), but you're acting like you do:
    Code:
    void strobe()		//write in data
    {
    	E = 1;
    	delay(500);
    	E = 0;
    	delay(500);
    }
    I'll be surprised if someone is able to sort this out for you with what you've provided.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Apr 2011
    Posts
    21

    Hi,thank for your reply..

    Hi..yeah.

    Code:
     
    void strobe()		//write in data
    {
    	E = 1;
    	delay(500);
    	E = 0;
    	delay(500);
    }
    I was given an original code which allow me to display message to show on LCD.
    But i have modify it so to print time..
    well that code that you mention was already there originally. I did not change or edit it.
    But for the E,i have define it, it is for the LCD?
    So im not quite sure of that.
    yeah.. so is there any suggestion for the current problem that i face??
    Let me know if you need any info of my project. Thx
    Last edited by w31q1an9; 05-03-2011 at 10:20 PM.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    	unsigned char ReadValue; 
    	ReadValue = Read1302(DS1302_SECOND_READ); 
    	Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
    You need to see why Time->Second isn't what you think it should be.


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Apr 2011
    Posts
    21

    Hi,thank for your reply..

    Hi.. yeah..
    well for the code you mention above i am not sure about it.
    Perhaps can you pls further explain it to me if you understand.
    It was because that DS1302 header file was not code by me,i found it on a website.
    There are still some parts which i do not understand.

    Like the sbit ACC0 = ACC^0;
    What is ACC?? why i need to sBIT ACC?
    Well i have study the datasheet for DS1302,but i did not saw anything about ACC if i am right..
    can you or anyone kindly clear my doubts with the understanding of the code of the DS1302 header?
    I also hope that i can solve the current problem im facing..

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    You should check you compiler documentation for information on how to declare the sbit variables. In your LCD setup you are declaring them like
    Code:
    #define E  			P1_2			//LCD E
    and in your RTC setup you have
    Code:
    sbit  DS1302_CLK = P1^7;
    Different compilers use different ways to denote these variables. Keil uses this method
    Code:
    sbit LED = P3^4;
    Tasking uses
    Code:
    #define	HEARTBEAT_LED    P1_3           /* Port 1.3 used for heartbeat LED display */
    Jim

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by jimblumberg View Post
    You should check you compiler documentation for information on how to declare the sbit variables. In your LCD setup you are declaring them like
    Code:
    #define E  			P1_2			//LCD E
    That's not declaring any variable. It's making a macro, associating E with whatever P1_2 is. There is no variable shown in his code called E. (Or even P1_2 for that matter -- at least not one he's shown us.)
    Quote Originally Posted by jimblumberg View Post
    Different compilers use different ways to denote these variables. Keil uses this method
    Code:
    sbit LED = P3^4;
    Tasking uses
    Code:
    #define	HEARTBEAT_LED    P1_3           /* Port 1.3 used for heartbeat LED display */
    Jim
    The second one isn't a variable either, it's another macro. They still have to actually declare P1_3 some place.

    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 05-03-2011, 12:29 AM
  2. Replies: 13
    Last Post: 04-26-2011, 03:02 AM
  3. show the menu only once each time..
    By transgalactic2 in forum C Programming
    Replies: 16
    Last Post: 01-05-2009, 04:37 AM
  4. 8051 microcontrollers
    By ygfperson in forum Tech Board
    Replies: 5
    Last Post: 12-02-2002, 12:29 PM
  5. Show time??
    By sp00k in forum C++ Programming
    Replies: 2
    Last Post: 10-24-2001, 04:21 AM