`#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.