RTC PCF8583 with p18f4520 in C compiler

Status
Not open for further replies.

Mr.Cat

New Member
Hi,
I am doing final year project of Real time clock using pcf8583 on p18f4520 in C language. Now I can display Time and Date on LCD display. But I don't know how to set the time and date using push buttons. This is my C source code for RTC. Can anyone help me to edit my code?
Thanks

--------------------------------------------
unsigned char sec, min1, hr, day, mn, year;
char *txt, tnum[4];


void Zero_Fill(char *value) { // fill text repesentation (pointer)
if (value[1] == 0) { // with leading zero
value[1] = value[0];
value[0] = 48;
value[2] = 0;
}
}//~


//--------------------- Reads time and date information from RTC (PCF8583)
void Read_Time(char *sec, char *min, char *hr, char *day, char *mn, char *year) {

I2C_Start(); // Start Signal
I2C_Wr(0xA0); // Address PCF8583, See PCF 8583 datasheet
I2C_Wr(2); // Start from address 2
I2C_Repeated_Start(); // Repeated start signal
I2C_Wr(0xA1); // Address PCF8583 for reading R/W=1
*sec =I2C_Rd(1); // Read seconds byte
//while (I2C_Is_Idle() == 0) ;
*min =I2C_Rd(1); // Read minutes byte
//while (I2C_Is_Idle() == 0) ;
*hr =I2C_Rd(1); // Read hours byte
//while (I2C_Is_Idle() == 0) ;
*day =I2C_Rd(1); // Read year/day byte
//while (I2C_Is_Idle() == 0) ;
*mn =I2C_Rd(0); // Read weekday/month byte
//while (I2C_Is_Idle() == 0) ;
I2C_Stop(); // Issue stop signal \

}//~

void rtc_write() {

I2C_Init(10000); // initialize full master mode
I2C_Start(); // issue start signal
I2C_Wr(0xA0); // address PCF8583
I2C_Wr(0); // start from word at address 0 (configuration word)
I2C_Wr(0x80); // write $80 to config. (pause counter...)
I2C_Wr(0); // write 0 to cents word
I2C_Wr(0); // write 0 to seconds word
I2C_Wr(0x59); // write $59 to minutes word
I2C_Wr(0x23); // write $23 to hours word
I2C_Wr(0x31); // write $31 to year/date word
I2C_Wr(0x12); // write $12 to weekday/month
I2C_Stop(); // issue stop signal

I2C_Start(); // issue start signal
I2C_Wr(0xA0); // address PCF8583
I2C_Wr(0); // start from word at address 0
I2C_Wr(0); // write 0 to config word (enable counting)
I2C_Stop(); // issue stop signal

}
//-------------------- Formats date and time
void Transform_Time(char *sec, char *min, char *hr, char *day, char *mn, char *year) {
*sec = ((*sec & 0xF0) >> 4)*10 + (*sec & 0x0F);
*min = ((*min & 0xF0) >> 4)*10 + (*min & 0x0F);
*hr = ((*hr & 0xF0) >> 4)*10 + (*hr & 0x0F);
*year = (*day & 0xC0) >> 6;
*day = ((*day & 0x30) >> 4)*10 + (*day & 0x0F);
*mn = ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F);
}//~

//-------------------- Output values to LCD
void Display_Time(char sec, char min, char hr, char day, char mn, char year) {


ByteToStr(day,tnum);
txt = rtrim(tnum);
Zero_Fill(txt);
LCD_Out(1,6,txt);
ByteToStr(mn,tnum);
txt = rtrim(tnum);
Zero_Fill(txt);
LCD_Out(1,9,txt);
LCD_Chr(1,15,48+year);
ByteToStr(hr,tnum);
txt = rtrim(tnum);
Zero_Fill(txt);
LCD_Out(2,6,txt);
ByteToStr(min,tnum);
txt = rtrim(tnum);
Zero_Fill(txt);
LCD_Out(2,9,txt);
ByteToStr(sec,tnum);
txt = rtrim(tnum);
Zero_Fill(txt);
LCD_Out(2,12,txt);
}//~

//------------------ Performs project-wide init
void Init_Main() {

LCD_Init(&PORTD); // initialize LCD on portd
I2C_Init(100000); // initialize I2C
txt = "Date-"; // prepare and output static text on LCD
LCD_Out(1,1,txt);
LCD_Chr(1,8,'/');
LCD_Chr(1,11,'/');
txt = "Time-";
LCD_Out(2,1,txt);
LCD_Chr(2,8,':');
LCD_Chr(2,11,':');
txt = "201";
LCD_Out(1,12,txt);
LCD_Cmd(LCD_CURSOR_OFF); // cursor off
}//~

//----------------- Main procedure

void main() {
char oldstate = 0;
ADCON1 = 0x0F; // configure AN pins as digital
TRISA = 0xFF; // set PORTB to be input
TRISD = 0; // set PORTD to be output
PORTD = 0xFF; // initialize PORTD

LCD_Cmd(LCD_CURSOR_OFF); // cursor off
rtc_write();
Init_Main();


while (1) // perform initialization
{
Read_Time(&sec,&min1,&hr,&day,&mn,&year); // read time from RTC(PCF8583)
Transform_Time(&sec,&min1,&hr,&day,&mn,&year); // format date and time
Display_Time(sec, min1, hr, day, mn, year); // prepare and display on LCD

{
if (Button(&PORTA, 1, 1, 1)) // If the button connected to RA0 is pressed
oldstate = 1;
if (oldstate && Button(&PORTA, 0, 1, 0)) {
Delay_ms(10);
Lcd_Cmd(LCD_BLINK_CURSOR_ON);
LCD_Out(2,7,LCD_BLINK_CURSOR_ON);
oldstate = 0;
}
{

if (Button(&PORTA, 1, 1, 1))
oldstate = 1;
if (oldstate && Button(&PORTA, 1, 0, 0)) { // If the pressed button is connected to RA1
Delay_ms(10);
Lcd_Cmd(LCD_BLINK_CURSOR_ON);
LCD_Out(2,10,LCD_BLINK_CURSOR_ON);
//Lcd_Cmd(LCD_MOVE_CURSOR_RIGHT);
oldstate = 0;
}

{
if (Button(&PORTE, 0, 1, 1)) // Cursor ON at First Row, RE0
oldstate = 1;
if (oldstate && Button(&PORTE, 0, 1, 0)) {
Delay_ms(10);
Lcd_Cmd(LCD_BLINK_CURSOR_ON);
LCD_Out(1,7,LCD_BLINK_CURSOR_ON);
//Lcd_Cmd(LCD_FIRST_ROW);
oldstate = 0;
}

{
if (Button(&PORTE, 0, 1, 1)) // Cursor ON at Second Row, RE1
oldstate = 1;
if (oldstate && Button(&PORTE, 1, 0, 0)) {
Delay_ms(10);
Lcd_Cmd(LCD_BLINK_CURSOR_ON);
LCD_Out(1,10,LCD_BLINK_CURSOR_ON);
//Lcd_Cmd(LCD_SECOND_ROW);
oldstate = 0;
}

{
if (Button(&PORTC, 0, 1, 1)) // Cursor OFF Button at RC0
oldstate = 1;
if (oldstate && Button(&PORTC, 0, 1, 0)) {
Delay_ms(10);
Lcd_Cmd(LCD_CURSOR_OFF);
oldstate = 0;
}

}
}
}

}

} Delay_ms(1000); // delay 1s
}
}
 
I did a project a while ago that read and wrote to a PCF8583P using an 18F4620. I'm not sure what compiler you're using but here's the code. It was wriiten for MikroC. If you use the most current version of their compiler you may have some porting issues. I don't remember if this was the final or best working version but you should be able to get some ideas. Good luck.
 

Attachments

  • RTC_18F4620.c
    30.1 KB · Views: 513
Hello vne147,
Thank you for your help. Now I am trying to understand your program and I just take out the part what I need.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…