Rev Author Line No. Line
1213 mija 1 /* mija 2008
2 demo for LCD NOKIA5110 and MCP9800 and GPS modul
3  
4 CPU ATMEGA644P
5 fcpu = 1MHz
6  
7 !! define PIN,PORT,DDR for IOpin !!
8 */
9  
10  
11 //************************************************************************
12 // defines
13  
14 #define KEY_TIME_DEAD 5 //cca 50ms 8*5
15 //#define KEY_TIME_START_REPEAT 100 //cca 1s
16 //#define KEY_TIME_REPEAT 20 //cca 240ms
17 #define KEY_TIME_FIRST 50
18  
19 #define TEMP_TIME_REPEAT 100
20  
21 #define OFF_TIME 200
22  
23 #define REFRESH_TIME 100
24  
25 #define STATUS_REFRESH_TIME 100
26  
27 #define CLOCK1S 100
28 #define CLOCK2S 200
29 #define CLOCK5S 255;
30 #define CLOCK50MS 5
31  
32 #define DEBUG
33  
34 //************************************************************************
35 //including
36  
37 #include <avr/io.h>
38 #include <stdlib.h>
39 #include <avr/pgmspace.h>
40 #include <avr/interrupt.h>
41 #include <avr/sleep.h>
42 #include <util/delay.h>
43 #include <stdio.h>
44 #include <math.h>
45 //#include "ascii_table.h"
46 #include "lcd.h" //define PINs LCD
47 #include "GPS.h" //define PINs GPS,TL,LED,REF,I2C
48 #include "nmea_scan.h"
49  
50 //************************************************************************
51 // pomocne
52 #define WIDTH_CHAR_SIGNALL 8
53 prog_uint8_t CHAR_SIGNALL[WIDTH_CHAR_SIGNALL]={127,12,30,51,51,30,12,127};
54  
55 #define WIDTH_CHAR_SIGNALL_D 8
56 prog_uint8_t CHAR_SIGNALL_D[WIDTH_CHAR_SIGNALL_D]={127,12,30,63,63,30,12,127};
57  
58 #define WIDTH_CHAR_SIGNALL_2D 7
59 prog_uint8_t CHAR_SIGNALL_2D[WIDTH_CHAR_SIGNALL_2D]={1,2,4,127,4,2,1};
60  
61 #define WIDTH_CHAR_SIGNALL_3D 7
62 prog_uint8_t CHAR_SIGNALL_3D[WIDTH_CHAR_SIGNALL_3D]={124,68,71,69,125,17,31};
63  
64 #define WIDTH_CHAR_LIGHT 5
65 prog_uint8_t CHAR_LIGHT[WIDTH_CHAR_LIGHT]={127,65,95,95,127};
66  
67  
68  
69 //***********************************************************************
70 // global variables
71 extern uint8_t video_buf[504];
72 extern uint8_t *offset_text;
73  
74 uint8_t id_mod;
75 char scan_buf[MAX_NMEA_LOAD];
76 POINT_T now,max,min;
77 DATA_GPS gps;
78 DATA_GPS *pgps;
79  
80 enum {ID_TIME,ID_LOCATION,ID_COURSE,ID_ALL_POSITION,ID_ALL_SERVICE,ID_SERVICE,ID_TEMP,ID_SATELITES,ID_NORTH,ID_NAV};
81  
82  
83 //static int lcd_put(char c, FILE *stream);
84 static FILE mystdout = FDEV_SETUP_STREAM(lcd_put, NULL,_FDEV_SETUP_WRITE);
85 //static int lcd_put2(char c, FILE *stream);
86 static FILE mystdout2 = FDEV_SETUP_STREAM(lcd_put2, NULL,_FDEV_SETUP_WRITE);
87  
88 //************************************************************************
89 // general cpu init
90  
91 void general_cpu_init(void)
92 {
93 //*** IO_PIN ***
94 TL1_INIT;
95 TL1_PULLUP;
96 TL2_INIT;
97 TL2_PULLUP;
98 TL3_INIT;
99 TL3_PULLUP;
100  
101 RX_INIT;
102 RX_PULLUP;
103  
104 GPS_INIT;
105 GPS_OFF;
106  
107 REF_INIT;
108 REF_OFF;
109  
110 nSCLK_INIT;
111 nSDIN_INIT;
112 nDC_INIT;
113 nCS_INIT;
114 nRESET_INIT;
115  
116 SCL_INIT;
117 SDA_FLOAT;
118  
119 LED_INIT;
120 LED_OFF;
121  
122 //*** EXTERNAL PIN INTERRUPTS
123 EICRA = _BV(ISC21); //pin INT2 - TL2
124 EIMSK = _BV(INT2); //pin INT2 - TL2
125 //PCICR = _BV(PCIE1); //pin change TL1,TL2,TL3
126 //PCMSK1 = _BV(PCINT10) | _BV(PCINT11) |_BV(PCINT12); //pin change TL1,TL2,TL3
127  
128 //*** TIMER1 *** tik for TL fosc/8 /1024(TCNT1) cca 8ms
129 TCNT1 = 0;
130 OCR1A = 1024;
131 TCCR1A = _BV(WGM11) | _BV(WGM10);
132 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11) ; // TIMER1 fast PWM
133 TIMSK1 = _BV(TOIE1);
134  
135 //*** TIMER2 *** RTC
136 ASSR = _BV(AS2);
137 TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
138 TIMSK2 = _BV(TOIE2);
139  
140 //*** SLEEP ***
141 SMCR = _BV(SM1) | _BV(SM0) | _BV(SE);
142  
143 //*** WDT ***
144 //WDTCSR = _BV(WDCE) | _BV(WDE);
145 //WDTCSR = _BV(WDIE) | _BV(WDP3) | _BV(WDP0);
146  
147 //*** USART0 *** RX PD0, TX PD1, GPS
148 UBRR0 = 12;
149 //UCSR0A =
150 UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
151  
152 //*** USART1 *** RX PD2, TX PD3 PC
153 UBRR1 = 12;
154 //UCSR0A =
155 UCSR1B = _BV(RXCIE1) | _BV(RXEN0) | _BV(TXEN1);
156  
157 //*** ADC ***
158 ADMUX = _BV(REFS1) | _BV(MUX0);
159 ADCSRA = _BV(ADPS1) | _BV(ADPS0);
160  
161 }
162  
163 //************************************************************************
164 // interrupts + RTC / clock 8s ... TIMER2 /
165  
166 volatile uint8_t RTC_flag;
167 volatile uint8_t sRTC,mRTC,hRTC,dRTC,mdRTC,yRTC;
168  
169 uint8_t modulo(uint8_t h,uint8_t m) //pomocna fce pro modulo x
170 {
171 if (h<m) return (h);
172 return(h-m);
173 }
174  
175 void set_date(void) //citac datumu
176 {
177 dRTC++;
178 switch (mdRTC)
179 {
180 case 1:
181 case 3:
182 case 5:
183 case 7:
184 case 8:
185 case 10:
186 case 12: if(dRTC>=32) {dRTC=1;mdRTC++;if(mdRTC==13) {mdRTC =1;yRTC=modulo(yRTC++,100);}} break;
187 case 4:
188 case 6:
189 case 9:
190 case 11: if(dRTC>=31) {dRTC=1;mdRTC++;} break;
191 case 2: if (dRTC >= 30) {dRTC=1;mdRTC++;break;}
192 if (dRTC ==29) {if (!(yRTC & 0x03)) break;dRTC=1;mdRTC++;}
193 }
194 }
195  
196  
197 volatile uint8_t timer1_ovf;
198  
199 ISR(TIMER1_OVF_vect)
200 {
201 timer1_ovf ++;
202 }
203  
204  
205 ISR(TIMER2_OVF_vect)
206 {
207 sRTC += 8;
208 if (sRTC >= 60)
209 {
210 sRTC=modulo(sRTC,60); //1min
211 if (++mRTC>=60)
212 {
213 mRTC=0; //1hod
214 if (++hRTC>=24)
215 {
216 hRTC=0;
217 set_date(); //1den
218 }
219 }
220 }
221 }
222  
223 char rx_buf[MAX_RX_BUF];
224 volatile uint8_t rx_shift;
225  
226 ISR(USART0_RX_vect)
227 {
228 if (++rx_shift >= MAX_RX_BUF) rx_shift =0;
229 rx_buf[rx_shift]=UDR0;
230 UDR1 = UDR0;
231 }
232  
233 ISR(USART1_RX_vect)
234 {
235 UDR0 = UDR1;
236 }
237  
238 EMPTY_INTERRUPT(INT0_vect)
239 EMPTY_INTERRUPT(INT2_vect)
240 EMPTY_INTERRUPT(PCINT1_vect)
241 EMPTY_INTERRUPT(WDT_vect)
242  
243 //************************************************************************
244 // delay_ms functions /define fcpu /
245  
246 void delay_ms(uint16_t time)
247 {
248 while(time--) _delay_ms(1);
249 }
250 //************************************************************************
251 // static navigation
252  
253 void gps_put(char c)
254 {
255 while ( !( UCSR0A & _BV(UDRE0)) );
256 UDR0 = c;
257 }
258  
259 void set_static_navigation(uint8_t static_nav)
260 {
261 char chsum[3];
262 char SWITCH_TO_SIRF[]="$PSRF100,0,4800,8,1,0" ;
263 uint8_t SET_STATIC_NAV[10]={0xa0,0xA2,0x00,0x02,0x8f,0x00,0x00,0x8f,0xB0,0xB3};
264 uint8_t SWITCH_TO_NMEA[10]={0xa0,0xA2,0x00,0x02,0x87,0x02,0x00,0x89,0xB0,0xB3};
265 uint8_t chksum;
266 uint8_t i;
267  
268 chksum=0;
269 for (i=0;i<21;i++)
270 {
271 gps_put(SWITCH_TO_SIRF[i]);
272 chksum +=SWITCH_TO_SIRF[i];
273 }
274 gps_put('*');
275 sprintf(chsum,"%02X",chksum);
276 gps_put(chsum[0]);
277 gps_put(chsum[1]);
278 gps_put('\r');
279 gps_put('\n');
280  
281 if (static_nav)
282 {
283 }
284 else
285 {
286 for (i=0;i<10;i++) gps_put(SET_STATIC_NAV[i]);
287 }
288 //for (i=0;i<10;i++) gps_put(SWITCH_TO_NMEA[i]);
289 }
290  
291 //************************************************************************
292 // key + timer1_ovf
293  
294  
295 volatile uint8_t key_press;
296 volatile uint8_t key_flag;
297 volatile uint8_t timer_key;
298 volatile uint8_t timer_temp;
299 volatile uint8_t timer_off;
300 volatile uint8_t timer_refresh;
301 volatile uint8_t timer_status;
302  
303 void timer1_tik(void)
304 {
305 uint8_t key_temp;
306  
307 timer1_ovf--;
308 {
309 if (timer_status) timer_status--;
310 if (timer_refresh) timer_refresh--;
311 if (timer_off) timer_off--;
312 if (timer_temp) timer_temp--;
313 if (timer_key) timer_key--;
314 else
315 {
316 if (!TL1_INPUT) key_temp = _BV(KEY1); else key_temp = 0;
317 if (!TL2_INPUT) key_temp |= _BV(KEY2); else key_temp &= ~(_BV(KEY2));
318 if (!TL3_INPUT) key_temp |= _BV(KEY3); else key_temp &= ~(_BV(KEY3));
319 if (key_temp != key_press)
320 {
321 timer_key = KEY_TIME_DEAD;
322 key_press = key_temp;
323 if (!key_flag) key_flag = key_press;
324 timer_off= OFF_TIME;
325 }
326 }
327 }
328 }
329  
330 uint8_t key_read(void)
331 {
332 uint8_t key_send;
333  
334 key_send = key_flag;
335 key_flag = 0;
336 return key_send;
337 }
338  
339 //************************************************************************
340 // SW I2C /define SDA, SCL; tested for fosc 1Mhz/
341  
342 void I2C_start(void)
343 {
344 SDA_OUT;
345 SDA_L;
346 SCL_L;
347 }
348  
349 void I2C_stop(void)
350 {
351 SCL_H;
352 SDA_OUT;
353 SDA_H;
354 SDA_FLOAT;
355 }
356  
357 void I2C_write(uint8_t data)
358 {
359 uint8_t a;
360  
361 SDA_OUT;
362 for(a=0;a<8;a++)
363 {
364 SCL_L;
365 if (data & 0x80) SDA_H;
366 else SDA_L;
367 SCL_H;
368 data <<= 1;
369 }
370 SCL_L;
371 SDA_FLOAT;
372 SCL_H;
373 SCL_L;
374 }
375  
376 uint8_t I2C_read(uint8_t ack)
377 {
378 uint8_t a;
379 uint8_t data;
380  
381 SDA_IN;
382 data=0;
383 for(a=0;a<8;a++)
384 {
385 SCL_H;
386 if (SDA_INPUT) data |=1;
387 SCL_L;
388 if (a != 7)data <<= 1;
389 }
390  
391 if (ack) {SDA_OUT;SDA_L;}
392 else SDA_FLOAT;
393 SCL_H;
394 SCL_L;
395 SDA_FLOAT;
396 return data;
397 }
398  
399 //************************************************************************
400 // temperature sensor MCP9800 of MICROCHIP
401  
402 void start_MCP9800(void)
403 {
404 I2C_start();
405 I2C_write(0x90);
406 I2C_write(0x1); // configuration pointer MCP9800
407 //I2C_write(0xE1); // 12bit + only 1 convert and then sleep
408 I2C_write(0x81); // 9bit + only 1 convert and then sleep
409 I2C_stop();
410 I2C_start();
411 I2C_write(0x90);
412 I2C_write(0x0); // temperature pointer
413 I2C_stop();
414 }
415  
416 uint16_t read_temp(void)
417 {
418 uint16_t temp;
419  
420 I2C_start();
421 I2C_write(0x91);
422 temp = I2C_read(1) << 8;
423 temp |= I2C_read(0);
424 I2C_stop();
425 return temp;
426 }
427  
428 //************************************************************************
429 // templota
430  
431 void print_temp(int16_t teplota)
432 {
433 printf("%d.%01dC",((teplota>>8) & 0x807F) | (teplota & 0x8000),5*((teplota>>7)& 0x1));
434 }
435  
436 void print_time(TIME_T time)
437 {
438 uint8_t temp;
439  
440 temp = time.hour/10;
441 if (temp == 0) lcd_put(' ',0);
442 else lcd_put(temp + 0x30,0);
443 lcd_put(time.hour%10 + 0x30,0);
444 //put_lcd(':');
445 *(offset_text++) = 0x36;
446 offset_text++;
447 lcd_put(time.min/10 + 0x30,0);
448 lcd_put(time.min%10 + 0x30,0);
449 //put_lcd(':');
450 //put_lcd(sRTC/10 + 0x30);
451 //put_lcd(sRTC%10 + 0x30);
452 }
453  
454 void print_date(DATE_T date)
455 {
456 uint8_t temp;
457  
458 temp = date.day/10;
459 if (temp == 0) lcd_put(' ',0);
460 else lcd_put(temp + 0x30,0);
461 lcd_put(date.day%10 + 0x30,0);
462 //put_lcd('/');
463 *(offset_text++) = 0x60;
464 offset_text++;
465 temp = date.mon/10;
466 if (temp != 0) lcd_put(temp + 0x30,0);
467 lcd_put(date.mon%10 + 0x30,0);
468 if (temp == 0)
469 {
470 *(offset_text++) = 0x60;
471 offset_text++;
472 }
473 //put_lcd('/');
474 //put_lcd(yRTC/10 + 0x30);
475 //put_lcd(yRTC%10 + 0x30);
476 }
477  
478 TIME_T actual_time(void)
479 {
480 TIME_T time;
481  
482 time.sec=sRTC;
483 time.min=mRTC;
484 time.hour=hRTC;
485 return time;
486 }
487  
488 DATE_T actual_date(void)
489 {
490 DATE_T date;
491  
492 date.day=dRTC;
493 date.mon=mdRTC;
494 date.year=yRTC;
495 return date;
496 }
497  
498 //*********************************************************************
499 //status
500  
501 void status(void)
502 {
503 uint8_t a,b;
504 uint8_t *ptr;
505  
506 start_MCP9800();
507 REF_ON;
508 ADC_ON;
509 ADCSRA |= _BV(ADSC);
510 while (!(ADCSRA & _BV(ADIF)));
511  
512 gotoxy(1,1);
513 printf("%0.1fV %2d",1024.0*25/ADC/10,read_temp()>>8);
514 offset_text = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT - 2*CHAR_WIDTH - WIDTH_CHAR_SIGNALL_3D - WIDTH_CHAR_SIGNALL - 2;
515 if (gps.fix_position)
516 {
517 switch (gps.fix_position)
518 {
519 case 1: ptr= CHAR_SIGNALL;b=WIDTH_CHAR_SIGNALL;break;
520 case 2: ptr= CHAR_SIGNALL_D;b=WIDTH_CHAR_SIGNALL_D;break;
521 case 0:
522 default:ptr= CHAR_SIGNALL;b=0;
523 }
524 for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
525  
526 ptr= CHAR_SIGNALL_3D;b=WIDTH_CHAR_SIGNALL_3D;offset_text++;
527 if (gps.mode2 == '3')
528 for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
529 offset_text++;
530 }
531 offset_text = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT-2*CHAR_WIDTH;
532 printf("%d",gps.satelites_used);
533 if (LED_INPUT)
534 {
535 ptr= CHAR_LIGHT;b=WIDTH_CHAR_LIGHT;
536 offset_text = video_buf + LCD_WIDTH - WIDTH_CHAR_LIGHT;
537 for (a=0;a<b;a++) *(offset_text++) =pgm_read_byte(ptr++);
538 }
539  
540 }
541  
542 //************************************************************************
543 // mod
544  
545 void displ_time(void)
546 {
547 GPS_ON;
548 if (!timer_refresh)
549 {
550 timer_refresh = CLOCK1S;
551 buffer_clr();
552 status();
553 gotoxy(1,2);
554 printf("time & date");
555 gotoxy(1,3);
556 fprintf(&mystdout2," %2d:%02d:%02d",gps.hour+2,gps.minute,gps.second);
557 gotoxy(1,5);
558 fprintf(&mystdout2," %2d.%02d.20%02d",gps.day,gps.month,gps.year);
559 lcd_refresh();
560 }
561 }
562  
563 void displ_location(void)
564 {
565 if (!timer_refresh)
566 {
567 timer_refresh = CLOCK1S;
568 buffer_clr();
569 status();
570 gotoxy(1,2);
571 printf("location");
572 gotoxy(1,3);
573 //gps.latitude = 14.5;
574 fprintf(&mystdout2,"%c %3d%.4f'",gps.ns_indicator,(uint8_t)gps.latitude,(gps.latitude - 1.0*(uint8_t)gps.latitude)*60);
575 gotoxy(1,5);
576 //gps.longitude = 48.25;
577 fprintf(&mystdout2,"%c %3d%.4f'",gps.we_indicator,(uint8_t)gps.longitude,(gps.longitude - 1.0*(uint8_t)gps.longitude)*60);
578 lcd_refresh();
579 }
580 }
581  
582 void displ_speed(void)
583 {
584 if (!timer_refresh)
585 {
586 timer_refresh = CLOCK1S;
587 buffer_clr();
588 status();
589 gotoxy(1,2);
590 printf("speed");
591 gotoxy(1,4);
592 fprintf(&mystdout2," %3.1f km/h",gps.speed);
593 lcd_refresh();
594 }
595 }
596  
597 void displ_course(void)
598 {
599 if (!timer_refresh)
600 {
601 timer_refresh = CLOCK1S;
602 buffer_clr();
603 status();
604 //gotoxy(1,2);
605 //printf("course");
606 gotoxy(1,3);
607 fprintf(&mystdout2," %3.1f km/h",gps.speed);
608 gotoxy(6,5);
609 fprintf(&mystdout2,"%3.0f",gps.course);
610 lcd_refresh();
611 }
612 }
613  
614 void displ_satelites(void)
615 {
616 #define WIDTH_REC 60
617  
618 uint8_t a,x,y,b;
619 static uint8_t d = 0;
620 static uint8_t c = 0;
621 double elevace,azimut;
622  
623 if (!timer_refresh)
624 {
625 timer_refresh = CLOCK1S;
626 if (c--) return;
627 c=3;
628 buffer_clr();
629 //status();
630 #ifdef DEBUG
631 if(gps.gsv_satelites_view > 12)
632 {
633 printf("error view satelites");
634 lcd_refresh();
635 c=20;
636 return;
637 }
638 #endif
639 if (++d >= gps.gsv_satelites_view) d = 0;
640 gotoxy(12,1);
641 printf("%d",gps.gsv_satelites_view);
642 gotoxy(12,2);
643 printf("%d",gps.satelit_detail[d].id);
644 gotoxy(12,3);
645 printf("%d",gps.satelit_detail[d].azimut);
646 gotoxy(12,4);
647 printf("%d",gps.satelit_detail[d].elevation);
648 gotoxy(12,5);
649 printf("%d",gps.satelit_detail[d].SNR);
650 gotoxy(12,6);
651  
652 for (a=0;a<gps.gsv_satelites_view;a++)
653 {
654 azimut = (double)gps.satelit_detail[a].azimut;
655 elevace = (double)gps.satelit_detail[a].elevation;
656  
657 x=(uint8_t)((WIDTH_REC-4)/2.0/90.0*(90.0-elevace)*sin(M_PI/180*azimut) + WIDTH_REC/2.0);
658 y=(uint8_t)((LCD_HEIGHT-4)/2.0/90.0*(90.0-elevace)*cos(M_PI/180*azimut) + LCD_HEIGHT/2.0);
659 if (gps.satelit_detail[a].SNR)
660 {
661 lcd_plot(x-1,y);lcd_plot(x+1,y);lcd_plot(x,y-1);lcd_plot(x,y+1);
662 for (b=0;b<gps.satelites_used;b++)
663 if (gps.satelit_detail[a].id == gps.satelite_id[b])
664 lcd_plot(x,y);
665 }
666 else lcd_plot(x,y);
667  
668 if (d == a)
669 {
670 lcd_line(x-2,y-2,x-2,y+2);
671 lcd_line(x+2,y+2,x+2,y-2);
672 lcd_line(x+2,y+2,x-2,y+2);
673 lcd_line(x-2,y-2,x+2,y-2);
674 }
675 }
676  
677 lcd_line(0,0,WIDTH_REC,0);
678 lcd_line(0,LCD_HEIGHT-1,WIDTH_REC,LCD_HEIGHT-1);
679 lcd_line(0,0,0,LCD_HEIGHT-1);
680 lcd_line(WIDTH_REC,0,WIDTH_REC,LCD_HEIGHT-1);
681  
682 lcd_refresh();
683 }
684 }
685  
686 void displ_all_position()
687 {
688 if (!timer_refresh)
689 {
690 timer_refresh = CLOCK1S;
691 buffer_clr();
692 status();
693  
694 gotoxy(1,2);
695 printf("%c %3d%.4f'",gps.ns_indicator,(uint8_t)gps.latitude,(gps.latitude - 1.0*(uint8_t)gps.latitude)*60);
696 gotoxy(1,3);
697 printf("%c %3d%.4f'",gps.we_indicator,(uint8_t)gps.longitude,(gps.longitude - 1.0*(uint8_t)gps.longitude)*60);
698 gotoxy(1,4);
699 printf("alt%4.0fm V%2.1f",gps.altitude,gps.VDOP);
700 gotoxy(1,5);
701 printf("geo%4.0fm H%2.1f",gps.geoid,gps.HDOP);
702 gotoxy(1,6);
703 printf("%3.0fkm/h %3.0f",gps.speed,gps.course);
704 lcd_refresh();
705 }
706 }
707  
708 void displ_nav(void)
709 {
710 uint8_t a;
711 double lon,lat,temp;
712 double course;
713 uint8_t x,y,xl,yl,xp,yp;
714  
715 if (!timer_refresh)
716 {
717 timer_refresh = CLOCK1S;
718 buffer_clr();
719 status();
720  
721 const float gc_lat=48*60+57.7647,gc_lon=14*60+28.0836; // DOMA
722  
723 lon=(gc_lon-gps.longitude*60)*1214;
724 lat=(gc_lat-gps.latitude*60)*1854;
725 temp = sqrt((lon*lon) + (lat*lat));
726  
727 gotoxy(9,3);
728 if (temp < 10000)
729 {
730 if (temp<1000) fprintf(&mystdout2,"%.1f ",temp);
731 else
732 {
733 fprintf(&mystdout2,"%.3f ",temp/1000);
734 gotoxy(12,5);
735 printf("k");
736 }
737 gotoxy(13,5);
738 printf("m");
739 }
740 else
741 {
742 temp=temp/1000;
743 if (temp < 1000)
744 {
745 if (temp < 100)
746 {
747 fprintf(&mystdout2,"%.2f ",temp);
748 }
749 else
750 {
751 fprintf(&mystdout2,"%.1f ",temp);
752 }
753 }
754 else fprintf(&mystdout2,"%5.0f ",temp);
755 gotoxy(12,5);
756 printf("km");
757 }
758  
759 if (lat==0) lat=0.001;
760 lon=M_PI/2.0-(atan2(lat,lon));
761 if (lon<0) lon+=2*M_PI;
762 if (lon>(2*M_PI)) lon-=2*M_PI;
763 //printf(lcd_putc,"BE%2.0g*",lon);
764 lat=M_PI/180*gps.course;
765 lon=lon-lat;
766 if (lon<0) lon+=2*M_PI;
767 if (lon>2*M_PI) lon-=2*M_PI;
768 //printf(lcd_putc,"HE%2.0g*AZ%2.0g* ",lon,lat);
769  
770 #define WIDTH_REC_NAV 43
771 #define LCD_HEIGHT_NAV 35
772  
773 course = lon;
774 x=(uint8_t)(WIDTH_REC_NAV/2.0*sin(course) +WIDTH_REC_NAV/2);
775 y=(uint8_t)((LCD_HEIGHT_NAV)/2.0*cos(course) +(LCD_HEIGHT_NAV)/2);
776  
777 xl=(uint8_t)(WIDTH_REC_NAV/2.0*sin((course-2.62))+WIDTH_REC_NAV/2 );
778 yl=(uint8_t)((LCD_HEIGHT_NAV)/2.0*cos((course-2.62))+(LCD_HEIGHT_NAV)/2 );
779  
780 xp=(uint8_t)(WIDTH_REC_NAV/2.0*sin((course+2.62))+WIDTH_REC_NAV/2 );
781 yp=(uint8_t)((LCD_HEIGHT_NAV)/2.0*cos((course+2.62)) +(LCD_HEIGHT_NAV)/2);
782  
783 //xs=(uint8_t)((WIDTH_REC_NORTH-26)/2.0*sin(M_PI/180*(course+180.0))+WIDTH_REC_NORTH/2 );
784 //ys=(uint8_t)(((LCD_HEIGHT_NORTH-20))/2.0*cos(M_PI/180*(course+180.0)) +(LCD_HEIGHT_NORTH)/2);
785  
786 lcd_line( x,y,xl,yl);
787 lcd_line( x,y,xp,yp);
788 //lcd_line( xp,yp,xl,yl);
789 lcd_line(xl,yl,WIDTH_REC_NAV/2,(LCD_HEIGHT_NAV)/2);
790 lcd_line(xp,yp,WIDTH_REC_NAV/2,(LCD_HEIGHT_NAV)/2);
791  
792 //lcd_line(xl,yl,xs,ys);
793 //lcd_line(xp,yp,xs,ys);
794 lcd_refresh();
795 }
796 }
797  
798 void displ_service(char *buf)
799 {
800 uint8_t a;
801  
802 if (!timer_refresh)
803 {
804 timer_refresh = CLOCK1S;
805 buffer_clr();
806 for (a = 0; a<80; a++) putchar(*(buf++));
807 lcd_refresh();
808 }
809 }
810  
811 void displ_north(void)
812 {
813 //uint8_t a;
814 uint8_t x,y;
815 uint8_t xp,yp;
816 uint8_t xl,yl;
817 //uint8_t xs,ys;
818 double course;
819  
820 if (!timer_refresh)
821 {
822 timer_refresh = CLOCK1S;
823 buffer_clr();
824 status();
825 gotoxy(9,3);
826 fprintf(&mystdout2,"%3.1f",gps.speed);
827 gotoxy(10,5);
828 printf("km/h");
829  
830 #define WIDTH_REC_NORTH 43
831 #define LCD_HEIGHT_NORTH 35
832  
833 course = 360-gps.course;
834 x=(uint8_t)(WIDTH_REC_NORTH/2.0*sin(M_PI/180*course) +WIDTH_REC_NORTH/2);
835 y=(uint8_t)((LCD_HEIGHT_NORTH)/2.0*cos(M_PI/180*course) +(LCD_HEIGHT_NORTH)/2);
836  
837 xl=(uint8_t)(WIDTH_REC_NORTH/2.0*sin(M_PI/180*(course-150.0))+WIDTH_REC_NORTH/2 );
838 yl=(uint8_t)((LCD_HEIGHT_NORTH)/2.0*cos(M_PI/180*(course-150.0))+(LCD_HEIGHT_NORTH)/2 );
839  
840 xp=(uint8_t)(WIDTH_REC_NORTH/2.0*sin(M_PI/180*(course+150.0))+WIDTH_REC_NORTH/2 );
841 yp=(uint8_t)((LCD_HEIGHT_NORTH)/2.0*cos(M_PI/180*(course+150.0)) +(LCD_HEIGHT_NORTH)/2);
842  
843 //xs=(uint8_t)((WIDTH_REC_NORTH-26)/2.0*sin(M_PI/180*(course+180.0))+WIDTH_REC_NORTH/2 );
844 //ys=(uint8_t)(((LCD_HEIGHT_NORTH-20))/2.0*cos(M_PI/180*(course+180.0)) +(LCD_HEIGHT_NORTH)/2);
845  
846 lcd_line( x,y,xl,yl);
847 lcd_line( x,y,xp,yp);
848 //lcd_line( xp,yp,xl,yl);
849 lcd_line(xl,yl,WIDTH_REC_NORTH/2,(LCD_HEIGHT_NORTH)/2);
850 lcd_line(xp,yp,WIDTH_REC_NORTH/2,(LCD_HEIGHT_NORTH)/2);
851  
852 //lcd_line(xl,yl,xs,ys);
853 //lcd_line(xp,yp,xs,ys);
854 lcd_refresh();
855 }
856 }
857  
858 void displ_all_service(void)
859 {
860 uint8_t a;
861  
862 if (!timer_refresh)
863 {
864 timer_refresh = CLOCK1S;
865 buffer_clr();
866 status();
867  
868 gotoxy(1,2);
869 printf("d=%d %ds",gps.diff_id,gps.age_diff_corr);
870 gotoxy(1,3);
871 printf("%c st=%cD ",gps.mode1,gps.mode2);
872 switch (gps.fix_position)
873 {
874 case 0: printf("nofix");break;
875 case 1: printf("SPSfix");break;
876 case 2: printf(" Dfix");break;
877 default: printf("nopref");
878 }
879 gotoxy(1,4);
880 printf("GSV %d %d %d",gps.gsv_num_msg,gps.gsv_msg,gps.gsv_satelites_view);
881 gotoxy(1,5);
882 for(a=0;a<6;a++)
883 {
884 printf("%2d",gps.satelite_id[a]);
885 offset_text+=2;
886 }
887 gotoxy(1,6);
888 for(a=6;a<12;a++)
889 {
890 printf("%2d",gps.satelite_id[a]);
891 if (a != 11) offset_text+=2;
892 }
893 lcd_refresh();
894 }
895 }
896  
897 void displ_temp()
898 {
899 //GPS_OFF;
900 //ADC_OFF;
901 //REF_OFF;
902  
903 if(!timer_temp)
904 {
905 timer_temp = TEMP_TIME_REPEAT;
906 now.temperature=read_temp();
907 now.time=actual_time();
908 now.date=actual_date();
909  
910 buffer_clr();
911 gotoxy(1,1);
912 stdout = &mystdout2;
913 print_temp(now.temperature);
914 stdout = &mystdout;
915 gotoxy(11,1);
916 offset_text-= 2;
917 print_time(now.time);
918 gotoxy(11,2);
919 offset_text-= 2;
920 print_date(now.date);
921 gotoxy(1,4);
922 if (now.temperature > max.temperature) max=now;
923 print_temp(max.temperature);
924 gotoxy(11,4);
925 offset_text-= 2;
926 print_date(max.date);
927 gotoxy(6,3);
928 printf("max");
929 gotoxy(11,3);
930 offset_text-= 2;
931 print_time(max.time);
932 gotoxy(1,6);
933 if (now.temperature < min.temperature) min=now;
934 print_temp(min.temperature);
935 gotoxy(11,6);
936 offset_text-= 2;
937 print_date(min.date);
938 gotoxy(6,5);
939 printf("min");
940 gotoxy(11,5);
941 offset_text-= 2;
942 print_time(min.time);
943 lcd_refresh();
944 start_MCP9800();
945 }
946 }
947  
948 void displ_start(void)
949 {
950 buffer_clr();
951 gotoxy(6,3);
952 fprintf(&mystdout2,"GPS");
953 lcd_refresh();
954 delay_ms(1000);
955 id_mod = ID_TEMP;
956  
957 }
958  
959 void all_off(void)
960 {
961 if (!timer_refresh)
962 {
963 buffer_clr();
964 gotoxy(6,3);
965 fprintf(&mystdout2,"OFF");
966 lcd_refresh();
967 timer_refresh = CLOCK1S;
968 return;
969 }
970 if (timer_refresh < CLOCK50MS)
971 {
972 timer_refresh = 0;
973 LED_OFF;
974 GPS_OFF;
975 REF_OFF;
976 N5110_send_command(POWER_DOWN);
977  
978 while (TL2_INPUT)
979 sleep_cpu();
980  
981 LCD_N5110_INIT();
982 id_mod = ID_START;
983 }
984 }
985  
986 //************************************************************************
987 // spol key
988  
989 uint8_t key(uint8_t mod)
990 {
991 if(key_press)
992 {
993 if (!timer_off)
994 {
995 if (key_read() == _BV(KEY2))
996 {
997 timer_refresh = 0;
998 timer_key = CLOCK2S;
999 key_read();
1000 return ID_OFF;
1001 }
1002 }
1003 }
1004 else
1005 {
1006 if (key_flag == _BV(KEY1))
1007 {
1008 timer_key = KEY_TIME_FIRST;
1009 key_read();
1010 timer_refresh = 0;
1011 ++mod;
1012 }
1013 if (key_flag == _BV(KEY2))
1014 {
1015 if (LED_INPUT) LED_OFF;
1016 else LED_ON;
1017 timer_key = KEY_TIME_FIRST;
1018 key_read();
1019 }
1020 if (key_flag == _BV(KEY3))
1021 {
1022 max.temperature=0x8000;
1023 min.temperature=0x7FFF;
1024 if (GPS_INPUT && (gps.status == 'A'))
1025 {
1026 sRTC=gps.second;
1027 mRTC=gps.minute;
1028 hRTC=gps.hour+2;
1029  
1030 dRTC=gps.day;
1031 mdRTC=gps.month;
1032 yRTC=gps.year;
1033 }
1034  
1035 timer_key = KEY_TIME_FIRST;
1036 key_read();
1037 }
1038 }
1039 return mod;
1040 }
1041  
1042 //************************************************************************
1043 // main
1044  
1045 int main(void)
1046 {
1047 uint8_t temp;
1048  
1049 pgps = &gps;
1050 max.temperature=0x8000;
1051 min.temperature=0x7FFF;
1052 id_mod = ID_NORTH;
1053  
1054 general_cpu_init();
1055 //GPS_ON;
1056 LCD_N5110_INIT();
1057  
1058 //set_static_navigation(0);
1059  
1060 sRTC=0;
1061 mRTC=15;
1062 hRTC=17;
1063  
1064 dRTC=25;
1065 mdRTC=7;
1066 yRTC=8;
1067  
1068 stdout = &mystdout;
1069 sei();
1070  
1071 for (;;)
1072 {
1073 switch(id_mod)
1074 {
1075 case ID_TIME: displ_time(); break;
1076 case ID_LOCATION: id_mod++;break;displ_location();break;
1077 //case ID_SPEED: displ_speed(); break;
1078 case ID_SATELITES: displ_satelites();break;
1079 case ID_COURSE: id_mod++;break;displ_course(); break;
1080 case ID_ALL_POSITION:displ_all_position(); break;
1081 case ID_ALL_SERVICE:displ_all_service();break;
1082 case ID_SERVICE: id_mod++; break;displ_service(scan_buf);break;
1083 case ID_TEMP: displ_temp(); break;
1084 case ID_OFF: all_off(); break;
1085 case ID_START: displ_start(); break;
1086 case ID_NAV: displ_nav();break;
1087 case ID_NORTH: displ_north();break;
1088 default : id_mod = 0;
1089 }
1090  
1091 id_mod = key(id_mod);
1092  
1093 while(timer1_ovf)timer1_tik();
1094  
1095 switch (load_nmea(rx_shift,rx_buf,scan_buf))
1096 {
1097 case RETURN_GGA: nmea_gga(scan_buf,pgps);break;
1098 case RETURN_GSA: nmea_gsa(scan_buf,pgps);break;
1099 case RETURN_GSV: nmea_gsv(scan_buf,pgps);break;
1100 case RETURN_RMC: nmea_rmc(scan_buf,pgps);break;
1101 case RETURN_VTG: nmea_vtg(scan_buf,pgps);break;
1102 }
1103 }
1104 return 0;
1105 }
1106