speed.c


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