Urgent! Please help me with this code

Discussion on projects that are created by users and posted on mikroElektronika website.
Post Reply
Author
Message
internetuser2k11
Posts: 258
Joined: 12 Apr 2012 02:39

Urgent! Please help me with this code

#1 Post by internetuser2k11 » 26 Nov 2012 07:03

Hello!

Somebody please help me with this code. Pressing set button will cycle through weekday, day, month, year, hour, minute, alarm day, alarm, month, alarm, year, alarm hour, alarm minute.

inc and dec buttons increment or decrements the values. Ok sets the time and runs the clock.

The problem is I don't know what format the values should be written to ds1307 using I2Cx_Wr() function. Should I use a Dec2Bcd conversion to convert my values and write it to ds1307.

The problem is shown in the attached image.

Code: Select all


#ifndef DS1307
        #define DS1307 0xD0
#endif

#define SET RA0_bit
#define INC RA1_bit
#define DEC RA2_bit
#define OK RA3_bit

// LCD module connections
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections

unsigned char num, flag, set_time_flag;
char b, x, i, sec, min1, hr, week_day, day, mn, year;
char *txt, tnum[4], time_format[3], sihr[17];
char colon[] = ":";
int cnt, ihr, error, am_pm = 0;
bit set_flag, inc_flag, dec_flag, ok_flag, do_once_hr, do_once_min, do_once_sec, do_once_day, do_once_mn, do_once_year;
bit dec_do_once_hr, dec_do_once_min, dec_do_once_sec, dec_do_once_day, dec_do_once_mn, dec_do_once_year;
bit inc_do_once_hr, inc_do_once_min, inc_do_once_sec, inc_do_once_day, inc_do_once_mn, inc_do_once_year;
bit alarm_flag, alarm_set_flag;
unsigned char set_cnt, inc_cnt, dec_cnt = 0;
unsigned char ssec, smin, shr, sweek_day, sday, smn, syear;
unsigned char asec, amin, ahr, aweek_day, aday, amn, ayear;


void Zero_Fill(char *value) {
        if (value[1] == 0) {
                value[1] = value[0];
                value[0] = 48;
                value[2] = 0;
        }
}

void Write_Time() {
        I2C1_Start();          // issue start signal
        I2C1_Wr(DS1307);       // address DS1307
        I2C1_Wr(0);            // start from word at address (REG0)
        I2C1_Wr(0x80);         // write $80 to REG0. (pause counter + 0 sec)
        I2C1_Wr(smin);         // write 11 to minutes word to (REG1)
        I2C1_Wr(shr);          // write 17 to hours word (24-hours mode)(REG2)
        I2C1_Wr(sweek_day);    // write 6 - Friday (REG3)
        I2C1_Wr(sday);         // write 23 to date word (REG4)
        I2C1_Wr(smn);          // write 11 (Nov) to month word (REG5)
        I2C1_Wr(syear);        // write 12 to year word (REG6)
        I2C1_Stop();           // issue stop signal

        I2C1_Start();          // issue start signal
        I2C1_Wr(DS1307);       // address DS1307
        I2C1_Wr(0);            // start from word at address 0
        I2C1_Wr(0);            // write 0 to REG0 (enable counting + 0 sec)
        I2C1_Stop();           // issue stop signal
}

void Read_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
        I2C1_Start();
        I2C1_Wr(DS1307);
        I2C1_Wr(0);
        I2C1_Repeated_Start();
        I2C1_Wr(0xD1);
        *sec = I2C1_Rd(1);
        *min = I2C1_Rd(1);
        *hr = I2C1_Rd(1);
        *week_day = I2C1_Rd(1);
        *day = I2C1_Rd(1);
        *mn = I2C1_Rd(1);
        *year = I2C1_Rd(0);
        I2C1_Stop();

        I2C1_Start();
        I2C1_Wr(DS1307);
        I2C1_Wr(0);
        I2C1_Repeated_Start();
        I2C1_Wr(0xD1);
        ssec =I2C1_Rd(1);
        smin =I2C1_Rd(1);
        shr =I2C1_Rd(1);
        sweek_day =I2C1_Rd(1);
        sday =I2C1_Rd(1);
        smn =I2C1_Rd(1);
        syear =I2C1_Rd(0);
        I2C1_Stop();

}

void Transform_Time(char  *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
        *sec  =  ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F);
        *min  =  ((*min & 0xF0) >> 4)*10 + (*min & 0x0F);
        *hr   =  ((*hr & 0x30) >> 4)*10 + (*hr & 0x0F);
        *week_day =(*week_day & 0x07);
        *day  =  ((*day & 0xF0) >> 4)*10 + (*day & 0x0F);
        *mn   =  ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F);
        *year =  ((*year & 0xF0)>>4)*10+(*year & 0x0F);
}

void Display_Time(char sec, char min, char hr, char week_day, char day, char mn, char year) {
        if(alarm_flag == 0) {
        switch(week_day){
                case 1: txt="Sun"; break;
                case 2: txt="Mon"; break;
                case 3: txt="Tue"; break;
                case 4: txt="Wed"; break;
                case 5: txt="Thu"; break;
                case 6: txt="Fri"; break;
                case 7: txt="Sat"; break;
        }
        Lcd_Out(1,1,txt);
        Lcd_Chr(1,5,(day / 10)   + 48);    // Print tens digit of day variable
        Lcd_Chr(1,6, (day % 10)   + 48);    // Print oness digit of day variable
        Lcd_Chr(1,7,'/');
        Lcd_Chr(1,8,(mn / 10) + 48);
        Lcd_Chr(1,9,(mn % 10) + 48);
        Lcd_Chr(1,10,'/');
        Lcd_Out(1,11,"2");
        Lcd_Out(1,12,"0");
        Lcd_Chr(1,13, (year / 10)  + 48);          // Print year vaiable + 8 (start from year 2008)
        Lcd_Chr(1,14, (year % 10)  + 48);

        /*
        if(hr >= 12) {
           Lcd_Out(2,2,"PM");
           am_pm = 1;
        }
        else if(hr < 12) {
           Lcd_Out(2,2,"AM");
           am_pm = 0;
        }
        */

        Lcd_Chr(2,5,(hr / 10)  + 48);
        Lcd_Chr(2,6,(hr % 10)  + 48);
        Lcd_Out(2,7,":");
        Lcd_Chr(2,8,(min / 10) + 48);
        Lcd_Chr(2,9,(min % 10) + 48);
        Lcd_Out(2,10,":");
        Lcd_Chr(2,11,(sec / 10) + 48);
        Lcd_Chr(2,12,(sec % 10) + 48);
        }
}

void Display_Alarm_Time(char asec, char amin, char ahr, char aweek_day, char aday, char amn, char ayear) {
        if(alarm_flag == 1) {
              Lcd_Out(1,1,"ALR");
              Lcd_Chr(1,5,(aday / 10)   + 48);    // Print tens digit of day variable
              Lcd_Chr(1,6, (aday % 10)   + 48);    // Print oness digit of day variable
              Lcd_Chr(1,7,'/');
              Lcd_Chr(1,8,(amn / 10) + 48);
              Lcd_Chr(1,9,(amn % 10) + 48);
              Lcd_Chr(1,10,'/');
              Lcd_Out(1,11,"2");
              Lcd_Out(1,12,"0");
              Lcd_Chr(1,13, (ayear / 10)  + 48);          // Print year vaiable + 8 (start from year 2008)
              Lcd_Chr(1,14, (ayear % 10)  + 48);
              Lcd_Chr(2,5,(ahr / 10)  + 48);
              Lcd_Chr(2,6,(ahr % 10)  + 48);
              Lcd_Out(2,7,":");
              Lcd_Chr(2,8,(amin / 10) + 48);
              Lcd_Chr(2,9,(amin % 10) + 48);
              Lcd_Out(2,10,":");
              Lcd_Chr(2,11,(asec / 10) + 48);
              Lcd_Chr(2,12,(asec % 10) + 48);
        }
}


void main() {

     TRISA = 0b00001111;
     PORTA = 0b00000000;
     TRISB = 0b00000000;
     PORTB = 0b00000000;
     ADCON0 = 0b00000000;
     ADCON1 = 0b10000111;

     Lcd_Init();
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Cmd(_LCD_CURSOR_OFF);
     Lcd_Out(1,4,"RTC DS1307");
     Delay_ms(3000);
     I2C1_Init(100000);
     Lcd_Cmd(_LCD_CLEAR);

     set_time_flag = 0;
     ok_flag = 1;
     alarm_flag = 0;
     alarm_set_flag = 0;
     ssec = 0x00;
     smin = 0x00;
     shr = 0x00;
     sweek_day = 0x01;
     sday = 0x00;
     smn = 0x00;
     syear = 0x00;
     asec = 0x00;
     amin = 0x00;
     ahr = 0x00;
     aday = 0x00;
     amn = 0x00;
     ayear = 0x00;
     
     Uart1_Init(9600);
     
     while(1) {
     
         if(set_time_flag == 1) {
                Write_Time();
                ok_flag = 0;
                Read_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);
         }
         
         if((SET == 1) && (INC == 0) && (DEC == 0) &&(OK == 0)) {
               Delay_ms(100);
               if((SET == 1) && (INC == 0) && (DEC == 0) && (OK == 0)) {
                       set_flag = 1;
                       set_time_flag = 1;
                       set_cnt++;
                       if(set_cnt > 11) {
                                  set_cnt = 1;
                                  alarm_flag = 0;
                       }
                       else if(set_cnt == 7) alarm_flag = 1;
               }
         }
         else if((INC == 1) && (DEC == 0) && (SET == 0) && (OK == 0) && (set_flag == 1)) {
                    Delay_ms(100);
                    if((INC == 1) && (DEC == 0) && (SET == 0) && (OK == 0) && (set_flag == 1)) {
                            inc_flag = 1;
                            if(alarm_flag == 0) {
                            switch(set_cnt) {
                               case 0:
                                    break;
                               case 1:
                                    sweek_day++;
                                    if(sweek_day > 7) sweek_day = 1;
                                    break;
                               case 2:
                                    sday++;
                                    if((sday == 16) || (sday == 32)) {
                                        sday = sday + 6;
                                    }
                                    else if(sday > 43) {
                                            sday = 1;
                                    }
                                    break;
                               case 3:
                                    smn++;
                                    if(smn > 12) smn = 1;
                                    break;
                               case 4:
                                    syear++;
                                    if((syear == 16) || (syear == 32) || (syear == 48) || (syear == 64) || (syear == 80) || (syear == 96)
                                              || (syear == 112) || (syear == 128) || (syear == 144)) {
                                        syear = syear + 6;
                                    }
                                    if(syear > 153) {
                                             syear = 0;
                                    }
                                    break;
                               case 5:
                                    shr++;
                                    if(shr == 16) {
                                        shr = shr + 6;
                                    }
                                    if(shr > 29) {
                                           shr = 0;
                                    }
                                    break;
                               case 6:
                                    smin++;
                                    if((smin == 16) || (smin == 32) || (smin == 48) || (smin == 64) || (smin == 80)) {
                                        smin = smin + 6;
                                    }
                                    if(smin > 89) {
                                            smin = 0;
                                    }
                                    break;
                               default:
                                     break;

                            };
                            }
                            else if(alarm_flag == 1) {
                                  switch(set_cnt) {
                               case 7:
                                    aday++;
                                    if(aday > 31) aday = 1;
                                    break;;
                               case 8:
                                    amn++;
                                    if(amn > 12) amn = 1;
                                    break;
                               case 9:
                                    ayear++;
                                    if(ayear > 99) ayear = 0;
                                    break;
                               case 10:
                                    ahr++;
                                    if(ahr > 23) ahr = 0;
                                    break;
                               case 11:
                                    amin++;
                                    if(amin > 59) amin = 0;
                                    break;
                               default:
                                     break;
                            };
                            }
                    }
         }
         else if((DEC == 1) && (SET == 0) && (INC == 0) && (OK == 0) && (set_flag == 1)) {
                    Delay_ms(100);
                    if((DEC == 1) && (SET == 0) && (INC == 0) && (OK == 0) && (set_flag == 1)) {
                            dec_flag = 1;
                            if(alarm_flag == 0) {
                            switch(set_cnt) {
                               case 0:
                                    break;
                               case 1:
                                    sweek_day--;
                                    if(sweek_day < 1) sweek_day = 7;
                                    break;
                               case 2:
                                    sday--;
                                    if(sday > 43) sday = 43;
                                    if((sday == 31) || (sday == 15)) {
                                         sday = sday - 6;
                                    }
                                    break;
                               case 3:
                                    smn--;
                                    if(smn > 12) smn = 12;
                                    if(smn < 1) smn = 12;
                                    break;
                               case 4:
                                    syear--;
                                    if(syear > 153) {
                                             syear = 153;
                                    }
                                    if((syear == 143) || (syear == 127) || (syear == 111) || (syear == 95) || (syear == 79) || (syear == 63)
                                              || (syear == 47) || (syear == 47) || (syear == 31) || (syear == 15)) {
                                         syear = syear - 6;
                                    }
                                    break;
                               case 5:
                                    shr--;
                                    if(shr > 29) {
                                           shr = 29;
                                    }
                                    if(shr == 15) {
                                         shr = shr - 6;
                                    }
                                    break;
                               case 6:
                                    smin--;
                                    if(smin > 89) {
                                            smin = 89;
                                    }
                                    if((smin == 79) && (smin == 63) && (smin == 47) || (smin == 31) || (smin == 15)) {
                                         smin = smin - 6;
                                    }
                                    break;
                               default:
                                     break;

                            };
                            }
                            else if(alarm_flag == 1) {
                                 switch(set_cnt) {
                                  case 7:
                                    aday--;
                                    if(aday > 31) aday = 31;
                                    if(aday < 1) aday = 31;
                                    break;
                               case 8:
                                    amn--;
                                    if(amn > 12) amn = 12;
                                    if(amn < 1) amn = 12;
                                    break;
                               case 9:
                                    ayear--;
                                    if(ayear > 99) ayear = 99;
                                    if(ayear < 0) ayear = 99;
                                    break;
                               case 10:
                                    ahr--;
                                    if(ahr > 23) ahr = 23;
                                    if(ahr < 0) ahr = 23;
                                    break;
                               case 11:
                                    amin--;
                                    if(amin > 59) amin = 59;
                                    if(amin < 0) amin = 59;
                                    break;
                               default:
                                     break;
                            };
                            }
                    }
         }
         else if((OK == 1) && (SET == 0) && (INC == 0) && (DEC == 0) && (set_flag == 1)) {
              Delay_ms(100);
              if((OK == 1) && (SET == 0) && (INC == 0) && (DEC == 0) && (set_flag == 1)) {
              set_flag = 0;
              set_time_flag = 0;
              ok_flag = 1;
              alarm_flag = 0;
              alarm_set_flag = 1;
              set_cnt = 0;
              }
         }
         
         if(ok_flag == 1) {
                Read_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);
         }
         
         if(alarm_flag == 0) {
                 Transform_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);
                 Display_Time(sec, min1, hr, week_day, day, mn, year);
                 if(alarm_set_flag == 1) {
                          if((day == aday) && (mn == amn) && (year == ayear) && (hr == ahr) && (min1 == amin)) {
                                 PORTB.F0 = 1;
                          }
                 }
         }

         if(alarm_flag == 1) {
                Display_Alarm_Time(asec, amin, ahr, aweek_day, aday, amn, ayear);
         }

     }
}

Attachments
rtc error.jpg
rtc error.jpg (69.12 KiB) Viewed 5631 times
PIC16F877 DS1307 RTC.rar
(104.71 KiB) Downloaded 158 times

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Urgent! Please help me with this code

#2 Post by Dany » 26 Nov 2012 12:02

The problem is I don't know what format the values should be written to ds1307 using I2Cx_Wr() function. Should I use a Dec2Bcd conversion to convert my values and write it to ds1307.
Yes, all value read from or written to the Ds1307 are in BCD format, so you will always have to convert them after reading or before writing.
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

internetuser2k11
Posts: 258
Joined: 12 Apr 2012 02:39

Re: Urgent! Please help me with this code

#3 Post by internetuser2k11 » 26 Nov 2012 12:20

Dany wrote:
The problem is I don't know what format the values should be written to ds1307 using I2Cx_Wr() function. Should I use a Dec2Bcd conversion to convert my values and write it to ds1307.
Yes, all value read from or written to the Ds1307 are in BCD format, so you will always have to convert them after reading or before writing.
Can you please tell me how to convert decimal to bcd?

I tried these methods but they are not working.

Code: Select all

               s_sec = (((ssec / 10) << 4) & 0xF0) + ((ssec-(ssec / 10) * 10) & 0x0F);
               s_min = (((smin / 10) << 4) & 0xF0) + ((smin-(smin / 10) * 10) & 0x0F);
               s_hr = (((shr / 10) << 4) & 0xF0) + ((shr-(shr / 10) * 10) & 0x0F);
               s_day = (((sday / 10) << 4) & 0x30) + ((sday-(sday / 10) * 10) & 0x0F);
               s_mn = (((smn / 10) << 4) & 0x10) + ((smn-(smn / 10) * 10) & 0x0F);
               s_year = (((syear / 10) << 4) & 0xC0) + ((syear-(syear / 10) * 10) & 0x0F);

Code: Select all

               s_sec = (ssec/10*16) + (ssec%10);
               s_min = (smin/10*16) + (smin%10);
               s_hr = (shr/10*16) + (shr%10);
               s_week_day = sweek_day;
               s_day = (sday/10*16) + (sday%10);
               s_mn = (smn/10*16) + (smn%10);
               s_year = (syear/10*16) + (syear%10);

Code: Select all


s_sec = (((ssec / 10) << 4) | (ssec % 10));
s_min = (((smin / 10) << 4) | (smin % 10));
s_hr  = (((shr / 10) << 4) | (shr % 10));
s_day = (((sday / 10) << 4) | (sday % 10));
s_mn  = (((smn / 10) << 4) | (smn % 10));
s_year = (((syear / 10) << 4) | (syear % 10));

Code: Select all


s_sec = (ssec / 10) << 4 + (ssec % 10);
               s_min = (smin / 10) << 4 + (smin % 10);
               s_hr  = (shr / 10) << 4 + (shr % 10);
               s_week_day = (sweek_day / 10) << 4 + (sweek_day % 10);
               s_day = (sday / 10) << 4 + (sday % 10);
               s_mn = (smn / 10) << 4 + (smn % 10);
               s_year = (syear / 10) << 4 + (syear % 10);

Last edited by internetuser2k11 on 26 Nov 2012 17:05, edited 1 time in total.

User avatar
dejan.odabasic
mikroElektronika team
Posts: 2649
Joined: 30 Apr 2012 14:20

Re: Urgent! Please help me with this code

#4 Post by dejan.odabasic » 26 Nov 2012 14:40

Hello,

Please take a look at OSD click example project.
There you can see how to convert - write time/date to DS1307 registers.

Best regards.

internetuser2k11
Posts: 258
Joined: 12 Apr 2012 02:39

Re: Urgent! Please help me with this code

#5 Post by internetuser2k11 » 26 Nov 2012 15:02

dejan.odabasic wrote:Hello,

Please take a look at OSD click example project.
There you can see how to convert - write time/date to DS1307 registers.

Best regards.

OK. Thank you. It is not mentioned how to write time / date to ds1307. I need the Decimal to BCD conversion thing.

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Urgent! Please help me with this code

#6 Post by Dany » 26 Nov 2012 19:15

I need the Decimal to BCD conversion thing.
In the "Conversions" library the routines Dec2BCD and Dec2BCD16 are available for that purpose.
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

internetuser2k11
Posts: 258
Joined: 12 Apr 2012 02:39

Re: Urgent! Please help me with this code

#7 Post by internetuser2k11 » 26 Nov 2012 20:17

Dany wrote:
I need the Decimal to BCD conversion thing.
In the "Conversions" library the routines Dec2BCD and Dec2BCD16 are available for that purpose.
But that is not working with my code posted above. Please give me Dec2Bcd and Dec2Hex codes.

Please check this simulation. What is wrong with the code.
Attachments
PIC16F877 DS1307 RTC.rar
(107.49 KiB) Downloaded 160 times
Last edited by internetuser2k11 on 26 Nov 2012 20:35, edited 1 time in total.

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Urgent! Please help me with this code

#8 Post by Dany » 26 Nov 2012 20:35

But that is not working with my code posted above. Please give me Dec2Bcd and Dec2Hex codes.
:?: I did not find the place in your code where you use the Dec2BCD or Dec2BCD16 mE library routines, so why do you say they do not work?! You do not need the codes, the library routines exist already, you can use them as such.


See the Conversions library from mikroC help:
Dec2Bcd

Prototype unsigned short Dec2Bcd(unsigned short decnum);

Returns Converted BCD value.

Description Converts input unsigned short integer number to its appropriate BCD representation.

Parameters : decnum: unsigned short integer number to be converted

Requires Nothing.

Example
unsigned short a, b;
...
a = 22;
b = Dec2Bcd(a); // b equals 34
Should do the job! :D :D
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

internetuser2k11
Posts: 258
Joined: 12 Apr 2012 02:39

Re: Urgent! Please help me with this code

#9 Post by internetuser2k11 » 26 Nov 2012 20:39

Please check my last post. it is updated. I have attached my project files. In that I use Dec2Bcd function and ten write values to ds 1307.

Press set button to enter set mode and select weekday. successive press of set button cycles through day, month, tear, hour, minute, alarm day, alarm month, alarm year, alarm hour, alarm minute, alarm second, and back to time set.

press inc or dec to increment or decrement the values. see the values on lcd and also proteus clock window.

User avatar
dejan.odabasic
mikroElektronika team
Posts: 2649
Joined: 30 Apr 2012 14:20

Re: Urgent! Please help me with this code

#10 Post by dejan.odabasic » 27 Nov 2012 08:42

Hello,

Please stop opening multiple topic with same questions.

You can find code that you are looking for in OSD click example.

Best regards.

internetuser2k11
Posts: 258
Joined: 12 Apr 2012 02:39

Re: Urgent! Please help me with this code

#11 Post by internetuser2k11 » 27 Nov 2012 12:30

Hi! dejan.odabasic

Here is the code you mentioned. Please show me where is the rtc_write routine or decimal to bcd conversion routine.

Code: Select all


/*
 * Project name:
      OSD click
 * Copyright:
      (c) mikroElektronika, 2012.
 * Revision History:
      20122211:
      - Initial release (DO);
 * Description:
      This is a simple demonstration how OSD click can be used.
      It displayes the current time and date tracked by RTC2 click board.
      Time and date can be adjusted from OSD menu which is acitvated on button press (RD0).
      Two more buttons (RRD1 and RD2) are used for menu navigation and forht button
      is used for confirmation actin (RD3).

      It also shows how you can implement the status bar for example: Volume control.
 * Test configuration:
     MCU:             PIC18F45K22
                      http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf
     Dev. Board:      EasyPIC v7
                      http://www.mikroe.com/easypic/
     Oscillator:      HS-PLL, 8.000 MHz Crystal, 32.000 MHz MCU Clock
     Ext. Modules:    OSD click - ac:OSD
                      http://www.mikroe.com/click/osd/
                      RTC2 click - ac:RTC2
                      http://www.mikroe.com/click/rtc2/
     SW:              mikroC PRO for PIC
                      http://www.mikroe.com/mikroc/pic/
 * NOTES:
      - Place OSD click board in the mikroBUS socket 1.
      - Place RTC2click board in the mikroBUS socket 2.
      - Set pull-down on ports RD0, RD1, RD2, RD3
      - Place J17(BUTTON PRESS LEVEL) in Vcc position.
*/
#include "OSD_driver.h"
#include "OSD_menu.h"
#include "RTC2_driver.h"
#include "Custom_Chars.h"

// RTC vars
// Global date/time variables
unsigned char hours;
unsigned char minutes;
unsigned char seconds;
unsigned char day;
unsigned char week;
unsigned char month;
unsigned char year;

// OSD vars
const char header[30]={' ',' ','O','S','D',' ','c','l','i','c','k',' ', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',':',' ',' ',':',' ',' ',' ',' '};
const char footer[30]={' ','w','w','w','.','m','i','k','r','o','e','.','c','o','m',' ',' ',' ',' ',' ','.',' ',' ','.','2','0',' ',' ','.',' '};

//Menu vars
const char OSmenu[8][20]={
{ 8 , 9 , 9 ,' ','S','E','R','V','I','C','E',' ','M','E','N','U',' ', 9 , 9 , 10},
{ 11,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', 11},
{ 11,' ','>',' ','S','e','t',' ','t','i','m','e',' ',' ',' ',' ',' ',' ',' ', 11},
{ 11,' ',' ',' ','S','e','t',' ','d','a','t','e',' ',' ',' ',' ',' ',' ',' ', 11},
{ 11,' ',' ',' ','S','e','t',' ','v','o','l','u','m','e',' ',' ',' ',' ',' ', 11},
{ 11,' ',' ',' ','I','n','v','e','r','t',' ','O','S','D',' ',' ',' ',' ',' ', 11},
{ 11,' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', 11},
{ 12, 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 13}
};

// Array of character addresses in MAX7456
const char OSDchr[256]={  0xF2,  0xF1,  0xF0,  0xEF, 0xEE,  0xED, 0xF3,            // 0-6 progress bar
  0xFB,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,      // 7-33
  0x48, 0,0,0,0, 0x46,0x3F,0x40, 0,0, 0x45,0x49,0x41,0x47,                         // 34; 35-38; 39-41; 42-43; 44-47
  0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x44, 0x43, 0x4A,    // 48-60
  0, 0x4B, 0x42, 0x4C,                                                             // 61; 62-64
  0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,    // 65-77  A-M
  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,    // 78-90  N-Z
  0, 0, 0, 0, 0, 0,                                                                // 91-96
  0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31,    // 97-109   a-m
  0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E     // 110-122  n-z
};

void Time_To_OSD(){
  /* Decode the valuse from RTC2 registers */
  seconds  =  ((seconds & 0x70) >> 4)*10 + (seconds & 0x0F);
  minutes  =  ((minutes & 0xF0) >> 4)*10 + (minutes & 0x0F);
  hours    =  ((hours & 0x30) >> 4)*10 + (hours & 0x0F);
  day      =  ((day & 0xF0) >> 4)*10 + (day & 0x0F);
  month    =  ((month & 0x10) >> 4)*10 + (month & 0x0F);
  year     =  ((year & 0xF0)>>4)*10+(year & 0x0F);

  // Wite DATE on OSD
  MAX7456_Write(14,  18, OSDchr[(day / 10) + 48]);
  MAX7456_Write(14,  19, OSDchr[(day % 10) + 48]);

  MAX7456_Write(14, 21, OSDchr[(month / 10) + 48]);
  MAX7456_Write(14, 22, OSDchr[(month % 10) + 48]);

  MAX7456_Write(14, 26, OSDchr[(year / 10)  + 48]);
  MAX7456_Write(14, 27, OSDchr[(year % 10)  + 48]);

  // Write TIME on OSD
  MAX7456_Write(1, 20, OSDchr[(hours / 10)   + 48]);
  MAX7456_Write(1, 21, OSDchr[(hours % 10)   + 48]);

  MAX7456_Write(1, 23, OSDchr[(minutes / 10) + 48]);
  MAX7456_Write(1, 24, OSDchr[(minutes % 10) + 48]);

  MAX7456_Write(1, 26, OSDchr[(seconds / 10) + 48]);
  MAX7456_Write(1, 27, OSDchr[(seconds % 10) + 48]);
}

void PinSetup(){
  // Configure all MCU pins as digital
  ANSELA = 0;
  ANSELD = 0;
  ANSELB = 0;
  ANSELC = 0;
  ANSELE = 0;
  SLRCON = 0;            // Set output slew rate on all ports at standard rate

  // Input/output configuration of MCU pins.
  TRISA.RA2 = 1;
  TRISC.RC0 = 1;
  TRISB.RB0 = 1;
  TRISC.RC4 = 1;
  TRISB.RB7 = 1;
  TRISC.RC3 = 0;
  TRISC.RC5 = 0;
  TRISE.RE0 = 0;
  TRISE.RE1 = 0;

  PORTE.RE0 = 1;
  PORTE.RE1 = 1;

/* Button inputs */ 
// Show/Hide menu
  LATD.B0  = 0;
  TRISD.B0 = 1;
// Down/Right Control
  LATD.B1  = 0;
  TRISD.B1 = 1;
// Up/Left Control
  LATD.B2  = 0;
  TRISD.B2 = 1;
// Confirm/Enter
  LATD.B3  = 0;
  TRISD.B3 = 1;
}
// Funcion Writes complete line to OSD, like header and footer
void WriteLnOSD(short line, const char array[]){
short i;
  for (i = 0; i < 30; i++ ){
    if(array[i] != ' ')
      MAX7456_Write(line, i, OSDchr[array[i]]);
  }
}

// Refreshe
void RefreshOSD(){
  WriteLnOSD( 1, header);
  WriteLnOSD(14, footer);
  // I2C need to be initialized for reading the RTC2 click
  I2C1_Init(100000);
  Read_Time(&hours, &minutes, &seconds, &day, &week, &month, &year);
/*
 * Since I2C and SPI lines are on same MCU pins, in order to addres to MAX7456
 * you need to re-initialize SPI after I2Cinit and vice versa.
 * That's whay there are multiple I2C and SPI initializations in the code.
 */
  SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4,
                     _SPI_DATA_SAMPLE_MIDDLE,
                     _SPI_CLK_IDLE_LOW,
                     _SPI_LOW_2_HIGH);
  Time_To_OSD();
}

void main() {
  PinSetup();                                       // Initial MCU setup
  SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4,
                     _SPI_DATA_SAMPLE_MIDDLE,
                     _SPI_CLK_IDLE_LOW,
                     _SPI_LOW_2_HIGH);
/* Uncomment the lines below in order to place custom chars in MAX7456 ROM */
/* These functions need to be called/programmed only once*/
//   MAX7456_InsertCustomChar(0xAA, CustomC1);      //Write character required
//   MAX7456_InsertCustomChar(0xA9, CustomC2);      //          for menu frame
//   MAX7456_InsertCustomChar(0xAB, CustomC3);
//   MAX7456_InsertCustomChar(0xAC, CustomC4);
//   MAX7456_InsertCustomChar(0xAD, CustomC5);
//   MAX7456_InsertCustomChar(0xAE, CustomC6);
  MAX7456_init();                                   // Initialze OSD chip
  ClearOSD(0,0,16,30);                              //Clears complete display
    
  while (1) {                 // Endless loop
    RefreshOSD();             // Referesh the header, footer, time and date
    BtnHandller();            // Check if/which button is pressed
    BlinkEfect();             // Add the blinking effect to time and date setup
  }
}


User avatar
dejan.odabasic
mikroElektronika team
Posts: 2649
Joined: 30 Apr 2012 14:20

Re: Urgent! Please help me with this code

#12 Post by dejan.odabasic » 27 Nov 2012 12:43

Hello,

This is not complete OSD example project.
Function which write time to OSD can be found in OSD_menu.c file.
UpdateRTC_Time and UpdateRTC_Date functions.

Best regards.

internetuser2k11
Posts: 258
Joined: 12 Apr 2012 02:39

Re: Urgent! Please help me with this code

#13 Post by internetuser2k11 » 27 Nov 2012 13:10

Code in the OSD_menu.c is what I have posted.

User avatar
dejan.odabasic
mikroElektronika team
Posts: 2649
Joined: 30 Apr 2012 14:20

Re: Urgent! Please help me with this code

#14 Post by dejan.odabasic » 27 Nov 2012 13:22

Hello,

You have posted the code of OSD_main.c file, functions are in ODS_menu.c.

Best regards.

internetuser2k11
Posts: 258
Joined: 12 Apr 2012 02:39

Re: Urgent! Please help me with this code

#15 Post by internetuser2k11 » 27 Nov 2012 13:31

OK. Thank you. I got it.

Post Reply

Return to “User Projects”