From c36d0f8e4effb9cfd6c1c1b1f792aa4178d55c16 Mon Sep 17 00:00:00 2001 From: John Van Enk Date: Tue, 11 Oct 2011 00:13:13 -0400 Subject: [PATCH] 1 second blink example done with timers now. --- README | 5 --- include/main.h | 14 +++++++++ src/main.c | 83 +++++++++++++++++++++++++++++++++++--------------- 3 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 include/main.h diff --git a/README b/README index 5664d94..70ac22d 100644 --- a/README +++ b/README @@ -1,8 +1,3 @@ -The easy-to-read examples provided on the following site were a big help in setting -this up quickly. The blink program originally used in src/main.c was borrowed from -this page. - http://balau82.wordpress.com/2011/03/29/programming-arduino-uno-in-pure-c/ - Usage: $ rake -T # see all tasks diff --git a/include/main.h b/include/main.h new file mode 100644 index 0000000..bdf0084 --- /dev/null +++ b/include/main.h @@ -0,0 +1,14 @@ +#ifndef __MAIN_H__ +#define __MAIN_H__ + +/* Assuming a clock rate of 16Mhz and a CLK/64 prescaler, + * we will see 250 ticks per millisecond. If we want to + * have the timer overlow ever millisecond, we need to + * initialize the counter to 5 after each tick. */ +#define TIMER_RESET_VAL 5 + +void configure(void); +void task(void); +int main(void); + +#endif /* __MAIN_H__ */ diff --git a/src/main.c b/src/main.c index e50f611..924771f 100644 --- a/src/main.c +++ b/src/main.c @@ -1,30 +1,65 @@ -/* - * This example was borrowed from: - * http://balau82.wordpress.com/2011/03/29/programming-arduino-uno-in-pure-c/ - */ - #include -#include +#include +#include + +#include "main.h" + +int main(void) +{ + configure(); + + while(1) {;} + + return 0; +} + +void configure(void) +{ + /* disable interrupts */ + cli(); + + /* configure TIMER0 to use the CLK/64 prescaler. */ + TCCR0B = _BV(CS00) | _BV(CS01); + + /* enable the TIMER0 overflow interrupt */ + TIMSK0 = _BV(TOIE0); -enum { - BLINK_DELAY_MS = 1000, -}; + /* set the initial timer counter value. */ + TCNT0 = TIMER_RESET_VAL; + + /* confiure PB5 as an output. */ + DDRB |= _BV(DDB5); + + /* turn off surface mount LED on */ + PORTB &= ~_BV(PORTB5); + + /* enable interrupts. */ + sei(); +} + +void task(void) +{ + static uint16_t tick = 0; + + /* toggle every thousand ticks */ + if (tick >= 1000) + { + /* toggle the LED */ + PORTB ^= _BV(PORTB5); + + /* reset the tick */ + tick = 0; + } + + tick++; +} -int main (void) +ISR(TIMER0_OVF_vect) { - /* set pin 5 of PORTB for output*/ - DDRB |= _BV(DDB5); - - while(1) { - /* set pin 5 high to turn led on */ - PORTB |= _BV(PORTB5); - _delay_ms(BLINK_DELAY_MS); - - /* set pin 5 low to turn led off */ - PORTB &= ~_BV(PORTB5); - _delay_ms(BLINK_DELAY_MS); - } - - return 0; + /* preload the timer. */ + TCNT0 = TIMER_RESET_VAL; + + /* call our periodic task. */ + task(); }