Speedometer.c


1
/*****************************************************
2
Project : SPEEDOMETER
3
Version : 1.0                     
4
Comments: Peter Reinisch
5
6
7
Chip type           : ATmega8515
8
Program type        : Application
9
Clock frequency     : 8.000000 MHz 64MS
10
Memory model        : Small
11
External SRAM size  : 0
12
Data Stack size     : 128
13
14
Compiled with CodeVisionAVR C cross-compiler.
15
*****************************************************/
16
#include <mega8515.h>
17
18
// Alphanumeric LCD Module functions
19
#include <alcd.h>
20
21
// Standard library functions (itoa, ftoa etc.)
22
#include <stdlib.h>
23
24
// Delay functions
25
#include <delay.h> 
26
27
// Nicknames for port pins
28
#define PLUS_KEY PINC.0
29
#define MINUS_KEY PINC.1
30
#define ENTER_KEY PINC.2
31
#define DIA_KEY PINC.3
32
#define SPEED_PORT PORTC.7
33
34
// Nicknames for delays, Etc.
35
#define DEBOUNCE_DELAY 80
36
#define REFRESH_DELAY 200
37
#define SPEED_MULTIPLIER 292
38
#define PULSE_TURN 12
39
40
// Global variables
41
unsigned char circ=0;           // Calculated circumference
42
unsigned int dcm=0;             // Distance covered in cm (modul 100m)
43
unsigned long speed=0;          // Calculated speed
44
unsigned int trip=0;            // Trip distance (0.1 Km)
45
unsigned long distance=0;       // Total distance (0.1 Km)
46
unsigned char overflow=0;       // Timer1 overflow; for long delays
47
unsigned long count=0;          // Current Timer1 count
48
unsigned long lastcount=0;      // Last Timer1 count
49
50
// Some messages
51
flash char msg_saving[]="Saving Data...";
52
flash char msg_circ[]="Circumference:";
53
flash char msg_dia[]="Enter Circum";
54
flash char msg_cm[]=" cm";
55
56
// Temporary variables
57
char tempstr[10];
58
59
// EEPROM saved variables
60
// Note that these variables are not written periodically.
61
// The diameter is written only when the diameter is changed from the menu.
62
// The odometer reading is saved only when the main power to the system is cut-off.
63
eeprom unsigned long int save_odometer=0;
64
eeprom unsigned long int save_trip=0;
65
eeprom unsigned char save_circ=0;
66
eeprom unsigned long int save_dcm=0;
67
68
// Timer 0 overflow interrupt service routine
69
// Current speed of the vehicle if no input pulse
70
// arrives within the expected period.
71
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
72
{
73
        count=overflow*65536+TCNT1;
74
        if(count>lastcount)
75
        {
76
                speed=(unsigned int) ((circ/PULSE_TURN)*SPEED_MULTIPLIER)/count;
77
        }   
78
}
79
80
// Timer 1 overflow interrupt service routine
81
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
82
{
83
        overflow++;
84
}
85
86
// External Interrupt 0 service routine
87
// A pulse is recieved & this function gets called..
88
interrupt [EXT_INT0] void ext_int0_isr(void)
89
{
90
        // Increment dcm modul 10000 (0.1 Km)
91
        dcm=dcm+(circ/PULSE_TURN);
92
        if(dcm>10000)
93
        {
94
                dcm=dcm-10000;
95
                // For every 10000 cm, trip and distance are incremented by 1 (0.1 Km)
96
                trip++;
97
                distance++;
98
        }
99
        count=overflow*65536+TCNT1;
100
        lastcount=count;  // Save the current count (for automatic damping of speed by Timer0)
101
        
102
        // Reset the timer
103
        TCNT1=0;
104
        overflow=0;
105
        
106
        speed=(unsigned int)((circ/PULSE_TURN)*SPEED_MULTIPLIER)/count;
107
}
108
109
// External Interrupt 1 service routine
110
// This interrupt is triggered automatically only
111
// when the main power to the circuit is removed (turning off the vehicle).
112
interrupt [EXT_INT1] void ext_int1_isr(void)
113
{
114
        // Save odometer reading in EEPROM
115
        save_odometer=distance;
116
        save_trip=trip;
117
        save_dcm=dcm;
118
        lcd_clear();
119
        lcd_putsf(msg_saving);  // "Saving Data..."
120
        delay_ms(1000);
121
}
122
123
void main(void)
124
{
125
126
// Input/Output Ports initialization
127
// Port A initialization
128
PORTA=0x00;
129
DDRA=0x00;
130
131
// Port B initialization
132
PORTB=0x00;
133
DDRB=0x00;
134
135
// Port C initialization
136
PORTC=0x00;
137
DDRC=0x80;
138
139
// Port D initialization
140
PORTD=0x00;
141
DDRD=0x00;
142
143
// Port E initialization
144
PORTE=0x00;
145
DDRE=0x00;
146
147
// Timer/Counter 0 initialization
148
// Clock source: System Clock
149
// Clock value: 7.813 kHz
150
// Mode: Normal top=FFh
151
// OC0 output: Disconnected
152
TCCR0=0x05;
153
TCNT0=0x00;
154
OCR0=0x00;
155
156
// Timer/Counter 1 initialization
157
// Clock source: System Clock
158
// Clock value: 7.813 kHz
159
// Mode: Normal top=FFFFh
160
// OC1A output: Discon.
161
// OC1B output: Discon.
162
// Noise Canceler: Off
163
// Input Capture on Falling Edge
164
// Timer 1 Overflow Interrupt: On
165
// Input Capture Interrupt: Off
166
// Compare A Match Interrupt: Off
167
// Compare B Match Interrupt: Off
168
TCCR1A=0x00;
169
TCCR1B=0x05;
170
TCNT1H=0x00;
171
TCNT1L=0x00;
172
ICR1H=0x00;
173
ICR1L=0x00;
174
OCR1AH=0x00;
175
OCR1AL=0x00;
176
OCR1BH=0x00;
177
OCR1BL=0x00;
178
179
// External Interrupt(s) initialization
180
// INT0: On     ; Input Pulses
181
// INT0 Mode: Falling Edge
182
// INT1: On     ; Save the current odometer reading
183
// INT1 Mode: Falling Edge
184
// INT2: Off    ; Not used
185
GICR|=0xC0;
186
MCUCR=0x0A;
187
EMCUCR=0x00;
188
GIFR=0xC0;
189
190
// Timer(s)/Counter(s) Interrupt(s) initialization
191
TIMSK=0x82;
192
193
// Analog Comparator initialization
194
// Analog Comparator: Off
195
// Analog Comparator Input Capture by Timer/Counter 1: Off
196
ACSR=0x80;
197
198
// LCD module initialization
199
// Connections are specified in the
200
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
201
// RS - PORTA Bit 0
202
// RD - PORTA Bit 2
203
// EN - PORTA Bit 1
204
// D4 - PORTA Bit 4
205
// D5 - PORTA Bit 5
206
// D6 - PORTA Bit 6
207
// D7 - PORTA Bit 7
208
// Characters/line: 16/2
209
lcd_init(16);
210
211
//Read saved odometer reading
212
distance=save_odometer;
213
trip=save_trip;
214
dcm=save_dcm;
215
216
//Read saved diameter
217
circ=save_circ;
218
lcd_putsf(msg_circ);            // "Circumference:"
219
itoa(circ, tempstr);
220
lcd_gotoxy(3,1);
221
lcd_puts(tempstr);
222
lcd_putsf(msg_cm);              // " cm"
223
delay_ms(1000);
224
225
// Global enable interrupts
226
#asm("sei")
227
228
while(1)
229
{
230
        lcd_clear();
231
        if(speed<1)
232
                speed=0;
233
                
234
        // Convert speed to string
235
        ftoa(speed, 0, tempstr);
236
        // Display it on the screen
237
        lcd_gotoxy(0,0);
238
        lcd_puts(tempstr);
239
        lcd_putsf("Km/h");
240
        
241
        
242
        // Convert trip distance (in Km) to string
243
        ftoa((float)trip/10, 1, tempstr);
244
        // Display it on the screen
245
        lcd_gotoxy(0,1);
246
        lcd_puts(tempstr);
247
        //lcd_putsf("Km");
248
        
249
        // Convert total distance (in Km) to string
250
        ftoa((float)distance/10, 1, tempstr);
251
        // Display it on the screen
252
        lcd_gotoxy(8,1);
253
        lcd_puts(tempstr);
254
        delay_ms(REFRESH_DELAY);
255
        
256
        // If the Trip Rest switch is pressed for more then 500ms, clear the trip meter
257
        if(ENTER_KEY==0)
258
        {
259
                delay_ms(500);
260
                if(ENTER_KEY==0)
261
                {
262
                        trip=0;
263
                }
264
        }
265
        
266
        // If the Change Diamter key is pressed for more than a second,
267
        if(DIA_KEY==0)
268
        {
269
                delay_ms(1000);
270
                if(DIA_KEY==0)
271
                {
272
                        while (1)
273
                        {
274
                                lcd_clear();
275
                                lcd_putsf(msg_dia);
276
                                itoa(circ,tempstr);
277
                                lcd_gotoxy(3,1);
278
                                lcd_puts(tempstr);
279
                                lcd_putsf(msg_cm);
280
                                
281
                                if(PLUS_KEY==0 && circ<250)
282
                                {
283
                                        delay_ms(DEBOUNCE_DELAY);
284
                                        if(PLUS_KEY==0)
285
                                                circ=circ+1;
286
                                } else
287
                                if(MINUS_KEY==0 && circ>1)
288
                                {
289
                                        delay_ms(DEBOUNCE_DELAY);
290
                                        if(MINUS_KEY==0)
291
                                                circ=circ-1;
292
                                } else
293
                                if(ENTER_KEY==0)
294
                                {
295
                                        delay_ms(DEBOUNCE_DELAY);
296
                                        if(ENTER_KEY==0)
297
                                        {               
298
                                                lcd_clear();
299
                                                lcd_putsf(msg_circ);    // "Circumference:"
300
                                                itoa(circ, tempstr);
301
                                                lcd_gotoxy(3,1);
302
                                                lcd_puts(tempstr);
303
                                                lcd_putsf(msg_cm);      // " cm"
304
                                                // Save in EEPROM
305
                                                save_circ=circ;
306
                                                delay_ms(1000);
307
                                                break;
308
                                        }               
309
                                }      
310
                                else
311
                                        delay_ms(DEBOUNCE_DELAY);
312
                        };
313
                }
314
        }
315
316
};
317
        
318
}