You can delegate the timekeeping and ramping to the ISR. What you need to pass to it is the 'target' value and 'step size' Step Size could be +ve or -ve depending on which way you want it to move.

the ISR could tick every millisec or maybe more depending on how fast you want to change the output.