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 | }
|