Tacho.c


1
/*
2
 * Tacho.c
3
 *
4
 * Created: 18.04.2012 21:55:02
5
 *  Author: Philipp
6
 */ 
7
#define F_CPU 8000000UL
8
9
#ifndef TRUE
10
#define TRUE 1
11
#endif
12
#ifndef FALSE
13
#define FALSE 0
14
#endif
15
16
#include <util/delay.h>
17
18
#include "Tacho.h"
19
20
#define TIMER_FREQUENCY 1000000
21
#define MEASURE_ITERATIONS 2
22
#define REIFENUMFANG 85
23
#define MAX_SPEED 70
24
#define MIN_CYCLES TIMER_FREQUENCY/(((MAX_SPEED*100000)/REIFENUMFANG)/3600)
25
26
volatile uint8_t timerOverflows = 0;
27
volatile uint16_t timerStart = 0;
28
volatile uint16_t timerEnd = 0;
29
volatile uint8_t workFlag = FALSE;
30
volatile uint8_t ersteFlanke = TRUE;
31
32
ISR(TIMER1_CAPT_vect) {
33
  // Solange der aktelle Zustand noch nicht ausgegeben ist am LCD, braucht man ihn auch nicht neu berechnen ...
34
  if(workFlag)
35
    return;
36
  workFlag = TRUE;
37
  if(ersteFlanke) {
38
    timerStart = ICR1;
39
    timerOverflows = 0;
40
    ersteFlanke = FALSE;
41
    workFlag = FALSE;
42
  } else {
43
    timerEnd = ICR1;
44
    // Entprellung, alles was mehr als 70km/h wäre (bei Reifenumfang von 85cm)
45
    if((timerOverflows*0xFFFF + timerEnd - timerStart) > MIN_CYCLES) {
46
      ersteFlanke = TRUE;
47
    }  
48
  }
49
}
50
51
ISR(TIMER1_OVF_vect) {
52
  if(!workFlag)
53
    timerOverflows++;
54
}
55
56
void printInt(uint32_t zahl, uint8_t row) {
57
  char buffer[15];
58
  ultoa(zahl, buffer, 10);
59
  LCDSetBrush(LCD_COLOR_BLUE);
60
  LCDFillRect(0, row*8, 128, 8); // Clear row 1
61
  LCDSetBrush(LCD_COLOR_WHITE);
62
  LCDPrintText(buffer, 0, row*8);
63
}
64
65
int main(void)
66
{  
67
  // Initialize the LCD
68
  LCDInit();
69
  
70
  // Show Logo
71
  //LCDShowBitmap(35, 0, Logo);
72
  
73
  // Set PB0 input, disabled Pull-Up
74
  DDRB &= ~(0x01 << PB0);
75
  PORTB &= ~(0x01 << PB0);
76
  
77
  // Initialize Timer1 for mensuring rpm
78
  TCCR1A = 0x00;
79
  
80
  // Noise-Canceler active
81
  // Prescaler = 8 => 1 MHz
82
  // ICP-> Rising-Edge
83
  TCCR1B = (0x01 << ICNC1) | (0x01 << ICES1) | (0x01 << CS11);
84
  
85
  // Enable interrupts
86
  // Input Capture Interrupt Enable
87
  // Overflow Interrupt Enable
88
  TIMSK = (0x01 << TICIE1) | (0x01 << TOIE1);
89
  
90
  uint32_t freqSum = 0;
91
  uint8_t freq = 0;
92
  uint8_t iteration = 0;
93
  
94
  sei();
95
  
96
  // Main-Loop
97
  while(1) {
98
    if(timerOverflows > 30) // 30 Overflows => ca. 2 Sekunden
99
      freq = 0;
100
    cli();
101
    printInt(workFlag, 5);
102
    if(workFlag) {
103
      if(iteration < MEASURE_ITERATIONS) {
104
        freqSum += TIMER_FREQUENCY / (timerOverflows*0xFFFF + timerEnd - timerStart);
105
        iteration++;
106
      } else {
107
        freq = freqSum / MEASURE_ITERATIONS;
108
        iteration = 0;
109
        freqSum = 0;
110
      }
111
      workFlag = FALSE;    
112
    }
113
    printInt(ersteFlanke, 0);
114
    printInt(timerOverflows, 1);
115
    printInt(timerStart, 2);
116
    printInt(timerEnd, 3);
117
    printInt(freq, 4);
118
    sei();
119
    _delay_ms(250);
120
  }
121
}