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]
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
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..