Making 24 hour clock

t06afre

Joined May 11, 2009
5,934
Have you looked at the datasheet what that says about timer0. I just read it and it is not hard to follow that part of the datasheet
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
708
Counter mode is selected by setting the T0CS bit (OPTION_REG<5>). In this mode, the Timer0 module will increment either on every rising or falling edge of pin RA2/AN1/T0CKI/INT/C1OUT. The incrementing edge is determined by the source edge (T0SE) control bit (OPTION_REG<4>). Clearing the T0SE bit selects the rising edge.
 

t06afre

Joined May 11, 2009
5,934
You just read the TMR0 register. As any other register
you can something like this
char rain[4];
main
{ utoa(rain, TMR0, 10);
}
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
708
have found out it it, but now the counter is counting 1-10 each press on button, ( before i moved if from interrupt down to main. )

And now the clock is blinking each second, but it's still 00:00, no minutes count in,
the Main program just seems to be skipped.

Rich (BB code):
#include <htc.h>
//#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
__CONFIG (FCMEN_ON & IESO_OFF & BOREN_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON & WDTE_OFF & FOSC_INTRCIO);
#define LED RC0
#define set_hour RC4
#define set_minut RC5
#define set_week RC6
#define set_time RC3
#define _XTAL_FREQ  4000000
//global defs
volatile unsigned char week_day;
volatile unsigned char hour, minut, sec, mm;
volatile bit timer_tick, minut_tick, set_time_flag, regn_tick;
volatile bit blink;
const char * const day_of_week_names[] = {"Mandag ",
                                          "Tirsdag",
                                          "Onsdag ",
                                          "Torsdag",
                                          "Fredag ",
                                          "Lordag ",
                 "Sondag " 
                                         };

char timestr[3], regn[4];
static void interrupt
isr(void)   // Here is interrupt function - the name is unimportant.
   {
 if(TMR1IF) 
  {// Was this a timer overflow?
      TMR1IF=0;//Clear interrupt flag, ready for next
   TMR1H=0x80;
        //If we set TMR1 to start at 0x8000 (32768), the TMR1 will overflow every 1 second
     timer_tick=1;
 blink=!blink;
           LED=blink; 
          
  sec++;
  if (sec==60)
 {
 minut_tick=1;
sec=0;
}
  }//we are done here
 }
void setup(void)
{   TRISA0=0;
    TRISC=0b01111000;//RC0-RC2 out,RC3-RC6 in,RC7 out
    TRISB=0; //All port B output
 GIE = 0;  // Global interrupt disable just in case
 ANSEL=0;
 ANSELH=0;//turn off all analog functions
//timer1 settings
 TMR1H=0x80;
 TMR1L=0;
 //T1CON=0b00000110;//used during debug
    T1CON=0b00001110;
 // See datasheet REGISTER 6-1: T1CON: TIMER 1 CONTROL REGISTER
 // bit order T1GINV TMR1GE T1CKPS1 T1CKPS0 T1OSCEN !T1SYNC TMR1CS TMR1ON
  //Timer1 Interrupt prepare
   TMR1IE=1;// PIE1 register
   PEIE=1; //INTCON register
   PIR1=0; // Clear all bits PERIPHERAL INTERRUPT REQUEST REGISTER 1
   //todo now in order to generate interrupt GEI=1 and TMR1ON=1
//timer0 settings.
INTCON=0b00110000;
 //setup LCD
    lcd_init();
 lcd_goto(0); // select first line
 //set the globals
     week_day=5;
minut=0;
sec=0;
hour=0;
minut_tick=0;
blink=0;
    //other misc settings
timer_tick=0;//clear the tick
    }
void lcd_format_and_send(void)
{   
lcd_goto(0x08);
utoa(timestr, hour, 10);
 if (hour<10)lcd_puts("0");
lcd_puts(timestr);
lcd_puts(":");
utoa(timestr, minut, 10);
 if (minut<10)lcd_puts("0");
lcd_puts(timestr);
 lcd_goto(0x47); // Select second line
 for (unsigned char i=0;i<7;i++) lcd_putch(day_of_week_names[week_day]);
lcd_goto(0x00);
}
 
void midnat (void)
{
week_day++;
if (week_day==7) week_day=0;
lcd_format_and_send();
}
void ur (void)
{
  
  minut++;
  if (minut>=60)
{   minut=0;
   hour++;
   if (hour>=24)
  { hour=0;
   
   midnat();
   }
}
 lcd_format_and_send();
}
void stil_ur (void)
{
 GIE = 0;  // Global interrupt disable as we are setting the time
 TMR1ON=0;       //timer1 off
 sec=0;
 TMR1H=0x80;
 TMR1L=0;
 LED=1;
 set_time_flag=1;
  do
   { 
    if (!set_hour)
                 {
                         hour++;
                  if (hour==24) hour=0;
                   lcd_format_and_send();
                  __delay_ms(200); 
                } 
    if (!set_minut)
               {
      minut++;
      if (minut==60) minut=0;
      lcd_format_and_send();
                   __delay_ms(200); 
               }    
    if (!set_week)
               {
      week_day++;
                  if (week_day==7) week_day=0;
                  lcd_format_and_send();
                 __delay_ms(200); 
                }    
         
    } while (!set_time);
 GIE = 1;  // Global interrupt enable
 TMR1ON=1;       //timer1 on
    set_time_flag=0;
}
 
void main (void) //hovedprogram
 { setup();
timestr[2]='\0';
lcd_format_and_send();
      GIE=1;
   TMR1ON=1;
TMR0=0;
       while (1)
         {
            if (minut_tick)
       { 
    ur();
    minut_tick=0; 
    }  // end if (minut_tick)
if (!set_time)
{
stil_ur();
}
lcd_goto(0x00);
lcd_puts("    ");
lcd_goto(0x00);
utoa(regn, TMR0, 10);
lcd_puts(regn);
lcd_goto(0x00);
}
}
 // flere hvis.....
 //end while endless loop
//End main     
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
708
when routine to wite to lcd (rain), is in interrupr for 1 sec, it works pretty ok.
but when routine is in "main" it totaly fu...ks up.
 

t06afre

Joined May 11, 2009
5,934
Do you have any data for the rain counter like links to producer data-sheet etc. Perhaps you can post some pictures of it.
 

t06afre

Joined May 11, 2009
5,934
I know the principal of a rain counter like yours. If it is that kind that empty it self. But depending on how the switch is placed. Will it be normally open or closed between each count. And I also think I made a bummer of using timer0 as counter. Looking once more on the datasheet. I found out that the then timer0 used as counter. The prescaler has a minimum setting of 1:2. I think we have to go for creating an external edge triggered interrupt. For each rain count. By some luck RA2 is also used for this purpose. Se section 14.3.1 and 2.2.2.3 in the datasheet. Note the gray note in section 2.2.2.3
In the static void interrupt isr(void) function. You must add another if statement. Something like this
Rich (BB code):
 if (INTF)
    {
        INTF=0;
        rain_count_flag=1
     }
And then in main function take care of things like with the timer_tick function.
 
Last edited:

Thread Starter

FroceMaster

Joined Jan 28, 2012
708
I think we have to go for creating an external edge triggered interrupt. For each rain count. By some luck RA2 is also used for this purpose. Se section 14.3.1 and 2.2.2.3 in the datasheet. Note the gray note in section 2.2.2.3
Can't find these sections in my datasheet
 

Thread Starter

FroceMaster

Joined Jan 28, 2012
708
not the datasheet you send me link on.
not sure what u want .

Note: Interrupt flag bits are set when an interrupt condition occurs, regardless of the state of its corresponding enable bit or the global enable bit, GIE of the INTCON register. User software should ensure the appropriate interrupt flag bits are clear prior to enabling an interrupt.
 

t06afre

Joined May 11, 2009
5,934
not the datasheet you send me link on.
not sure what u want .

Note: Interrupt flag bits are set when an interrupt condition occurs, regardless of the state of its corresponding enable bit or the global enable bit, GIE of the INTCON register. User software should ensure the appropriate interrupt flag bits are clear prior to enabling an interrupt.
Yes any problem with that? With interrupt flag they mean like the INTF flag(bit) in the INTCON register
 
Top