Skip to content

Instantly share code, notes, and snippets.

@johnhooks
Last active June 30, 2018 14:51
Show Gist options
  • Save johnhooks/a28f544c13b66623453e722684ea3acd to your computer and use it in GitHub Desktop.
Save johnhooks/a28f544c13b66623453e722684ea3acd to your computer and use it in GitHub Desktop.
Use an AVR Timer/Counter for both Fast PWM and a rudimentary clock.
/**
* I want to use a counter/timer for PWM and as a rudimentary
* millisecond clock. If I initiate the counter in Fast PWM mode,
* using a clock speed of 1MHz and a prescale of 8, a millisecond will
* elapse every 125 clock ticks.
*/
typedef uint32_t millis_t;
static volatile millis_t milliseconds = 0; /* 49.71 Days of milliseconds */
static volatile uint16_t microseconds = 0; /* Should never be more than 1000 */
ISR(TIMER0_OVF_vect) {
/* Each overflow will be approximately 2 milliseconds and 6 microseconds */
if (microseconds >= 996) {
microseconds = 2;
milliseconds += 3;
} else {
microseconds += 6;
milliseconds += 2;
}
}
millis_t millis()
{
millis_t ms;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
ms = milliseconds;
}
return ms;
}
void init(void)
{
/* Timer 0A */
TCCR0A |= (1 << WGM00); /* Fast PWM mode, 8-bit */
TCCR0A |= (1 << WGM01); /* Fast PWM mode, pt.2 */
TCCR0B |= (1 << CS01); /* PWM Freq = F_CPU/8/256 */
TCCR0A |= (1 << COM0A1); /* PWM output on OCR0A */
sei();
}
void main(void)
{
init();
while (1) {
/* set OCROA to what ever PWM value I want, while also able to read millis() */
}
return(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment