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