This may just be a typo in your post, but the line where you enable the Timer Compare interrupt says:
TIMSK0 != (1 << OCIE0A);
... when it should say ...
TIMSK0 |= (1 << OCIE0A);
It's subtle, but if that's what your code actually was, then you were comparing TIMSK0 to a constant rather than assigning to it (and therefore never actually enabling the interrupt).
On a sidenote, you can more concisely write:
TIMSK0 |= _BV(OCIE0A);
... instead of ..
TIMSK0 |= (1 << OCIE0A);
in avr-libc, if you're into that sort of thing :-).
This doesn't answer your question, but might make the code a little easier for you to debug. The case statements are really long and may not be the best way to explain what you are doing with your outputs. I make no guarantees that the code is operational (I have not run it at all), but this should get you thinking about file size and readability.
Your singleminutes case statement has a truth table like this:
// | out
// in| 0 1 2 3 4
// ---------------
// 0 | 0 0 0 0 0
// 1 | 0 1 0 0 0
// 2 | 0 1 1 0 0
// 3 | 0 1 1 1 0
// 4 | 0 1 1 1 1
which might be better represented with output-centric code like this:
if (singleminutes >= 1)
PPEins = 1;
else
PPEins = 0;
if (singleminutes >= 2)
PPZwei = 1;
else
PPZwei = 0;
if (singleminutes >= 3)
PPDrei = 1;
else
PPDrei = 0;
if (singleminutes >= 4)
PPVier = 1;
else
PPVier = 0;
The nfminutes is a little more complicated, but here is the Truth Table:
// | MHUhr PMFuenf PMZehn PMViertel PMZwanzig PMVor PMNach PMHalb | |
// --|--------------------------------------------------------------|--------|-----
// 0 | 1 0 0 0 0 0 0 0 | 1000 0 | 000
// 1 | 0 1 0 0 0 0 1 0 | 0100 0 | 010
// 2 | 0 0 1 0 0 0 1 0 | 0010 0 | 010
// 3 | 0 0 0 1 0 0 1 0 | 0001 0 | 010
// 4 | 0 0 0 0 1 0 1 0 | 0000 1 | 010
// 5 | 0 1 0 0 0 1 0 1 | 0000 0 | 101
// 6 | 0 0 0 0 0 0 0 1 | 0000 0 | 001
// 7 | 0 1 0 0 0 0 1 1 | 0100 0 | 011
// 8 | 0 0 0 0 1 1 0 0 | 0000 1 | 100
// 9 | 0 0 0 1 0 1 0 0 | 0001 0 | 100
//10 | 0 0 1 0 0 1 0 0 | 0010 0 | 100
//11 | 0 1 0 0 0 1 0 0 | 0100 0 | 100
and again some output-centric code:
// MHUhr PMFuenf PMZehn PMViertel PMZwanzig
if( nfminutes == 0 )
MHUhr = 1;
else
MHUhr = 0;
if(( nfminutes == 1 ) || (nfminutes == 5) || (nfminutes == 7) || (nfminutes == 11))
PMFuenf = 1;
else
PMFuenf = 0;
if(( nfminutes == 2 ) || (nfminutes == 10) )
PMZehn = 1;
else
PMZehn = 0;
if(( nfminutes == 3 ) || (nfminutes == 9) )
PMViertel = 1;
else
PMViertel = 0;
if(( nfminutes == 4 ) || (nfminutes == 8) )
PMZwanzig = 1;
else
PMZwanzig = 0;
// PMVor PMNach PMHalb
if( ((nfminutes >= 1 ) && (nfminutes <= 4 )) || (nfminutes == 7))
PMNach = 1;
else
PMNach = 0;
if( (nfminutes >= 5) && (nfminutes <= 7 )
PMHalb = 1;
else
PMHalb = 0;
if(nfminutes >=8)
PMVor = 1;
else
PMVor = 0;
The code above might do well with some #defines too
#define UHR 0
#define PHUENF_NACH 1
#define ZEHN_NACH 2
...
if(nfminutes == UHR)
Again for hours. Truth Table:
| 12 1 2 3 4 5 6 7 8 9 10 11
//----|------------------------------------
// 0 | 1 0 0 0 0 0 0 0 0 0 0 0
// 1 | 0 1 0 0 0 0 0 0 0 0 0 0
// 2 | 0 0 1 0 0 0 0 0 0 0 0 0
// 3 | 0 0 0 1 0 0 0 0 0 0 0 0
// 4 | 0 0 0 0 1 0 0 0 0 0 0 0
// 5 | 0 0 0 0 0 1 0 0 0 0 0 0
// 6 | 0 0 0 0 0 0 1 0 0 0 0 0
// 7 | 0 0 0 0 0 0 0 1 0 0 0 0
// 8 | 0 0 0 0 0 0 0 0 1 0 0 0
// 9 | 0 0 0 0 0 0 0 0 0 1 0 0
// 10 | 0 0 0 0 0 0 0 0 0 0 1 0
// 11 | 0 0 0 0 0 0 0 0 0 0 0 1
and code. Slightly different structure with all outputs being cleared, then only the correct output turned on.
// one-hot, clear all will not cause a glitch
PHZwoelf = 0;
PHEins = 0;
PHZwei = 0;
PHDrei = 0;
PHVier = 0;
PHFuenf = 0;
PHSechs = 0;
PHSieben = 0;
PHAcht = 0;
PHNeun = 0;
PHZehn = 0;
PHElf = 0;
if( hours == 0 )
PHZwoelf = 1;
if( hours == 1 )
PHEins = 1;
if( hours == 2 )
PHZwei = 1;
if( hours == 3 )
PHDrei = 1;
if( hours == 4 )
PHVier = 1;
if( hours == 5 )
PHFuenf = 1;
if( hours == 6 )
PHSechs = 1;
if( hours == 7 )
PHSieben = 1;
if( hours == 8 )
PHAcht = 1;
if( hours == 9 )
PHNeun = 1;
if( hours == 10 )
PHZehn = 1;
if( hours == 11 )
PHElf = 1;
All this also allows you to do your input calculations together before your case statements.
// update single minutes
int singleminutes = (int) (unbcd(tm.min)%5); // 1, 2, 3, 4
// update 5 minutes
int nfminutes = (int) (unbcd(tm.min)/5); // Fuenf Nach, Zehn Nach, ...
// update hours
int hours = (int) (unbcd(tm.hour)%12); // 12, 1, 2, 3, 4...
if(nfminutes>=5) hours++; // 7:25 = Fuenf Vor Halb Acht (8)
Best Answer
If I understand right, then when you comment the first (larger) bit out and uncomment the second bit it toggles at 0.7MHz?
The interrupt flag is not cleared so it will immediately jump back to the ISR. The second bit is not in an if statement so it will always be executed. So it will keep setting the pin in the interrupt_at_high_vector and clearing it in high_isr. You need to make sure the flag is always cleared (if it is not cleared automatically)
What are you wanting it to do?