Home > Blockchain >  How to make atmega 128 electronic watch and stopwatch?
How to make atmega 128 electronic watch and stopwatch?

Time:04-28

`#include <mega128.h>

unsigned int   KEYs_NUMs = 0, FLAG_RUNs = 0, TIME_DAYs = 1, TIME_HOUR = 0, TIME_MINs = 0, TIME_SECs = 0, TIME_10ms = 0, TIME_CNTs = 0 ;
unsigned int   TIME_TMR0 = 0, TIME_IMSI, SEGs_NUMs = 0  ;
unsigned int   TIME_S0, TIME_S1, TIME_M0, TIME_M1, TIME_H0, TIME_H1 ; 
unsigned int   IMSI = 0, DAT5 = 0, DAT4 = 0, DAT3 = 0, DAT2 = 0, DAT1 = 0, DAT0 = 0 ;
unsigned int   mode = 0 ;
unsigned char  SEG7[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7C, 0x07, 0x7F, 0x67} ;
unsigned char  FNDs[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7C, 0x07, 0x7F, 0x67} ;

 interrupt [EXT_INT4] void ext_int4_isr(void)
 {
   KEYs_NUMs  = 1 ;
   if(KEYs_NUMs == 1)       { mode = 1 ; }  
   else                     { mode = 0 ; KEYs_NUMs = 0 ; }    
 }

  interrupt [EXT_INT5] void ext_int5_isr(void)
 {
   if(mode == 1)
   {   
     KEYs_NUMs  = 1 ;
     if(KEYs_NUMs == 1)       { FLAG_RUNs = 1 ; }
     else if(KEYs_NUMs == 2)  { FLAG_RUNs = 0 ; }
     else                     { FLAG_RUNs = 1 ; KEYs_NUMs = 1 ; } 
   }
 }

  interrupt [EXT_INT6] void ext_int6_isr(void)
 { 
   if(mode == 1)
   {
     KEYs_NUMs -= 1 ;
     if(KEYs_NUMs == 1)       { TIME_MINs = 0, TIME_SECs = 0, TIME_10ms = 0, TIME_CNTs = 0 ; }
   }
 }

 interrupt [EXT_INT7] void ext_int7_isr(void)
 {
  
 }

 interrupt [TIM0_OVF] void timer0_ovf_isr(void)
 {   
   TCNT0 = 0x06 ;
 // Place your code here 
   TIME_TMR0  = 1 ;  // 1ms
   if(TIME_TMR0 >= 1000)
   {  TIME_TMR0 = 0 ;  TIME_SECs  = 1 ;  }
   if(TIME_SECs > 59)
   {  TIME_SECs = 0 ;  TIME_MINs  = 1 ;  }
   if(TIME_MINs > 59)
   {  TIME_MINs = 0 ;  TIME_HOUR  = 1 ;  }
   if(TIME_HOUR > 23)  
   {  TIME_HOUR = 0 ;  TIME_DAYs  = 1 ;  }
   if(TIME_DAYs > 31)
   {  TIME_DAYs = 1 ;  }
   
   TIME_IMSI = TIME_HOUR ;
   TIME_H1 = TIME_IMSI/10 ;
   TIME_H0 = TIME_IMSI - TIME_H1*10 ;

   TIME_IMSI = TIME_MINs ;
   TIME_M1 = TIME_IMSI/10 ;
   TIME_M0 = TIME_IMSI - TIME_M1*10 ;   

   TIME_IMSI = TIME_SECs ;
   TIME_S1 = TIME_IMSI/10 ;
   TIME_S0 = TIME_IMSI - TIME_S1*10 ;
   
   if(SEGs_NUMs > 6)  { SEGs_NUMs = 0 ;  }
   SEGs_NUMs  = 1 ;
   if(SEGs_NUMs == 1)
   { 
      PORTA.5 = 1 ; PORTA.4 = 1 ; PORTA.3 = 1 ; PORTA.2 = 1 ;  PORTA.1 = 1 ;
      PORTD = SEG7[TIME_S0] ; 
      PORTA.0 = 0 ;
   }
   else if(SEGs_NUMs == 2)
   {
      PORTA.5 = 1 ; PORTA.4 = 1 ; PORTA.3 = 1 ; PORTA.2 = 1 ;  PORTA.0 = 1 ;
      PORTD = SEG7[TIME_S1] ; 
      PORTA.1 = 0 ;   
   }
   else if(SEGs_NUMs == 3)
   {
      PORTA.5 = 1 ; PORTA.4 = 1 ; PORTA.3 = 1 ; PORTA.1 = 1 ;  PORTA.0 = 1 ;
      PORTD = SEG7[TIME_M0] ; 
      PORTA.2 = 0 ;   
   }      
   else if(SEGs_NUMs == 4)
   {
      PORTA.5 = 1 ; PORTA.4 = 1 ; PORTA.2 = 1 ; PORTA.1 = 1 ;  PORTA.0 = 1 ;
      PORTD = SEG7[TIME_M1] ; 
      PORTA.3 = 0 ;   
   }
   else if(SEGs_NUMs == 5)
   {
      PORTA.5 = 1 ; PORTA.3 = 1 ; PORTA.2 = 1 ; PORTA.1 = 1 ;  PORTA.0 = 1 ;
      PORTD = SEG7[TIME_H0] ; 
      PORTA.4 = 0 ;   
   }
   else
   {
      PORTA.4 = 1 ; PORTA.3 = 1 ; PORTA.2 = 1 ; PORTA.1 = 1 ;  PORTA.0 = 1 ;
      PORTD = SEG7[TIME_H1] ; 
      PORTA.5 = 0 ;    
   }
       
   if(TIME_TMR0 < 500)  {  PORTA.7 = 1 ;  }   // LED off
   else                 {  PORTA.7 = 0 ;  }   // LED on  
   
 } 

 void main(void)
 {
   DDRA=(1<<DDA7) | (0<<DDA6) | (1<<DDA5) | (1<<DDA4) | (1<<DDA3) | (1<<DDA2) | (1<<DDA1) | (1<<DDA0);
   PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);
   DDRD=(1<<DDD7) | (1<<DDD6) | (1<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0);
   PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
   ASSR=0<<AS0;
   TCCR0=(0<<WGM00) | (0<<COM01) | (0<<COM00) | (0<<WGM01) | (1<<CS02) | (0<<CS01) | (0<<CS00);
   TCNT0=0x06; OCR0=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
   TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (1<<TOIE0);
   ETIMSK=(0<<TICIE3) | (0<<OCIE3A) | (0<<OCIE3B) | (0<<TOIE3) | (0<<OCIE3C) | (0<<OCIE1C);
// External Interrupt(s) initialization
   EICRA=(0<<ISC31) | (0<<ISC30) | (0<<ISC21) | (0<<ISC20) | (0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
   EICRB=(1<<ISC71) | (0<<ISC70) | (1<<ISC61) | (0<<ISC60) | (1<<ISC51) | (0<<ISC50) | (1<<ISC41) | (0<<ISC40);
   EIMSK=(1<<INT7) | (1<<INT6) | (1<<INT5) | (1<<INT4) | (0<<INT3) | (0<<INT2) | (0<<INT1) | (0<<INT0);
   EIFR=(1<<INTF7) | (1<<INTF6) | (1<<INTF5) | (1<<INTF4) | (0<<INTF3) | (0<<INTF2) | (0<<INTF1) | (0<<INTF0);
// Globally enable interrupts
   #asm("sei")

   while (1)
   { 
     if(mode == 1)
     { 
       if(FLAG_RUNs)  { TIME_CNTs  = 1 ;  }  // 1ms
  
       if(TIME_CNTs > 99 )  { TIME_CNTs = 0 ;  TIME_SECs  = 1 ; }
       if(TIME_SECs > 59 )  { TIME_SECs = 0 ;  TIME_MINs  = 1 ; }
       if(TIME_MINs > 59 )  { TIME_MINs = 0 ;  }
       TIME_10ms = TIME_CNTs/10 ;

       SEGs_NUMs    ; 
       if(SEGs_NUMs > 5)  { SEGs_NUMs  = 0 ; }  

      switch(SEGs_NUMs)
      {
         case 0 :  PORTA.0 = 0 ; PORTA.1 = 1 ; PORTA.2 = 1 ; PORTA.3 = 1 ; PORTA.4 = 1 ; 
                   PORTA.5 = 1 ;
                   PORTD = FNDs[DAT0] ;  break; 
         case 1 :  PORTA.0 = 1 ; PORTA.1 = 0 ; PORTA.2 = 1 ; PORTA.3 = 1 ; PORTA.4 = 1 ; 
                   PORTA.5 = 1 ;
                   PORTD = FNDs[DAT1] ;  break; 
    
         case 2 :  PORTA.0 = 1 ; PORTA.1 = 1 ; PORTA.2 = 0 ; PORTA.3 = 1 ; PORTA.4 = 1 ; 
                   PORTA.5 = 1 ; 
                   PORTD = FNDs[DAT2] ;  break;  
         case 3 :  PORTA.0 = 1 ; PORTA.1 = 1 ; PORTA.2 = 1 ; PORTA.3 = 0 ; PORTA.4 = 1 ; 
                   PORTA.5 = 1 ;
                   PORTD = FNDs[DAT3] ;  break; 
    
         case 4 :  PORTA.0 = 1 ; PORTA.1 = 1 ; PORTA.2 = 1 ; PORTA.3 = 1 ; PORTA.4 = 0 ; 
                   PORTA.5 = 1 ;
                   PORTD = FNDs[DAT4] ;  break;  
         case 5 :  PORTA.0 = 1 ; PORTA.1 = 1 ; PORTA.2 = 1 ; PORTA.3 = 1 ; PORTA.4 = 1 ; 
                   PORTA.5 = 0 ;
                   PORTD = FNDs[DAT5] ;  break;   
      }
         IMSI = TIME_MINs ;
         DAT5 = IMSI/10 ;
         DAT4 = IMSI - DAT5*10 ;
      
         IMSI = TIME_SECs ;
         DAT3 = IMSI/10 ;
         DAT2 = IMSI - DAT3*10 ;
      
         IMSI = TIME_10ms ;
         DAT1 = IMSI/10 ;
         DAT0 = IMSI - DAT1*10 ;
     } 
   }
 }

` I wrote a code to change the mode by pressing the mode button by putting the clock code in the timer interrupt and the stopwatch code in 'while'. If you change the mode, it moves to the stopwatch as much as the elapsed time, and if you start the stopwatch, the counter starts at the minute digit. And when you reset and return to the clock, the clock counts from the beginning. How can I keep the timer running even if I change the mode? And how do I prevent the timer's time from being transferred to the stopwatch?

CodePudding user response:

According to the comments to the question:

interrupt [EXT_INT4] void ext_int4_isr(void)
{
    // just toggle the mode, no need for counting any occurrences...
    mode = !mode; // alternatively mode = 1 - mode

    if(mode)
    {
        // reset the stop watch on having been enabled:
        flagRuns = 0;
        // reset the counter as well!
        // TODO: common function for!
        // should work calling ext_int6_isr directly, too
    }
}

interrupt [EXT_INT5] void ext_int5_isr(void)
{
    // can toggle unconditionally, as the flag is not evaluated if not
    // in stop watch mode and is reset upon ENTERING the mode (this changed
    // compared to your original version!)
    flagRuns = !flagRuns;
}

interrupt [EXT_INT6] void ext_int6_isr(void)
{ 
    if(mode && !flagRuns)
    {
        // reset, common function, see above
    }
}

Most likely you need to declare the variables that are written to and read from across ISR and main routine or across different ISR volatile to avoid caching effects.

  • Related