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 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
}
}