Questo succede perchè il timer viene chiamato "circa" ogni 50 ms, ma potrebbe essere chiamato una volta dopo 48, una volta dopo 44, una volta dopo 49 ms ... e questo accumularsi di piccoli errori porta al grande errore ...
Non ho capito quale sia lo scopo del tuo programma ma potresti mostrare, all'interno del timer, la differenza tra l'orario attuale e quello di partenza .... quello sarebbe sempre preciso ...