timer.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * =====================================================================================
  3. *
  4. * ________ .__ __ ________ ____ ________
  5. * \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
  6. * / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
  7. * / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
  8. * \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
  9. * \__> \/ \/ \/ \/ \/
  10. *
  11. * www.optixx.org
  12. *
  13. *
  14. * Version: 1.0
  15. * Created: 07/21/2009 03:32:16 PM
  16. * Author: david@optixx.org
  17. *
  18. * =====================================================================================
  19. */
  20. #include <stdint.h>
  21. #include <stdio.h>
  22. #include <avr/io.h>
  23. #include <avr/io.h>
  24. #include <avr/interrupt.h> /* for sei() */
  25. #include "debug.h"
  26. #ifndef OCR1A
  27. #define OCR1A OCR1 // 2313 support
  28. #endif
  29. #ifndef WGM12
  30. #define WGM12 CTC1 // 2313 support
  31. #endif
  32. //#define XTAL 11059201L // nominal value
  33. #define XTAL 20000000UL
  34. #define DEBOUNCE 500L // debounce clock (256Hz = 4msec)
  35. #define uint8_t unsigned char
  36. #define uint unsigned int
  37. uint16_t prescaler;
  38. uint16_t volatile second; // count seconds
  39. ISR (SIG_OUTPUT_COMPARE1A)
  40. {
  41. #if XTAL % DEBOUNCE // bei rest
  42. OCR1A = 20000000UL / DEBOUNCE - 1; // compare DEBOUNCE - 1 times
  43. #endif
  44. if( --prescaler == 0 ){
  45. prescaler = (uint16_t)DEBOUNCE;
  46. second++; // exact one second over
  47. #if XTAL % DEBOUNCE // handle remainder
  48. OCR1A = XTAL / DEBOUNCE + XTAL % DEBOUNCE - 1; // compare once per second
  49. #endif
  50. }
  51. }
  52. void timer_start( void )
  53. {
  54. TCCR1B = (1<<WGM12) | (1<<CS10); // divide by 1
  55. // clear on compare
  56. OCR1A = XTAL / DEBOUNCE - 1UL; // Output Compare Register
  57. TCNT1 = 0; // Timmer startet mit 0
  58. second = 0;
  59. prescaler = (uint16_t)DEBOUNCE; //software teiler
  60. TIMSK1 = 1<<OCIE1A; // beim Vergleichswertes Compare Match
  61. // Interrupt (SIG_OUTPUT_COMPARE1A)
  62. sei();
  63. }
  64. double timer_stop(void)
  65. {
  66. double t = ((double)(DEBOUNCE - prescaler) / DEBOUNCE ) + second;
  67. return t;
  68. }