In Deinem ersten Listing wird sek in der 1-Phase von blink ständig, d.h. bei jedem Durchlauf der while-Schleife inkrementiert. Da die Schleife mit einigen 100 kHz läuft, dauert es keine Millisekunde, bis sek die 120 überschritten hat, sobald blink auf 1 ist.

In Deinem zweiten Listing wird sek erst bei jedem 1000sten Timer0 Compare Interrupt inkrementiert, also alle 1000 ms, was ja auch richtig ist.

MfG Mark

PS: nur die Variablen, die sowohl im Hauptprogramm als auch in ISRs verwendet werden, müssen volatile sein. In allen anderen Fällen ist es nur Verschwendung von Laufzeit.