Speedo_C.c


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