/Designs/GPSnavigator/SW/PIC16F876A/GPS_LCD_876_A2.c
0,0 → 1,218
//*****************************************************************************
//*** GPS CZ,no terminal,no time,no position,no math atan2,no save
//*** yes - arrow, distanc, load GCPOINT from PC
 
#include "GPS_LCD_876_A2.h"
#include <math.h>
#include <stdlib.h>
 
//*****************************************************************************
//*** defines ***
 
#define LCD_CS PIN_B0
#define LCD_DATA PIN_B1
#define LCD_CLK PIN_B2
#define LCD_A0 PIN_B3
#define LCD_RESET PIN_B4
#include "LCD_ALCATEL.C"
 
#define ARROW_UR 0x1
#define ARROW_UL 0x0
#define ARROWR "\xf\x3\x5\x9\x10\x10\x10"
#define ARROWL "\x1e\x18\x14\x12\x1\x1\x1"
 
#define TAN22 0.4142
#define TAN67 2.4241
 
#define MAX_GC_POINT 2
 
//*****************************************************************************
//*** functions ***
 
void NMEA_part_scan(int8 *point);
void NMEA_GPRMC(void);
void read_ee_gc(int8 numgc);
int8 atan2_my(float x,float y);
void calc_distanc_azimut(void);
void PC_part_scan(int8 *point);
void terminal(void);
void main(void);
 
//*****************************************************************************
//*** global variables ***
 
int8 sel;
int8 azimut;
float lon,lat;
float gc_lon,gc_lat;
int8 la[10];
int8 lo[11];
 
//*****************************************************************************
 
void NMEA_part_scan(int8 *point)
{
int8 a;
a=0;
while (a!=',') {a=fgetc(GPS);*(point++)=a;}
*(--point)=0x00;
}
 
//$GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598,,*10
void NMEA_GPRMC(void)
{
int8 status;
int8 n_s;
int8 e_w;
int8 course[7];
 
while (fgetc(GPS)!='$'); //$
while (fgetc(GPS)!=','); //GPRMC,
while (fgetc(GPS)!=',');//NMEA_part_scan(&time[0]); //UTC,
status=fgetc(GPS);fgetc(GPS); //status,
NMEA_part_scan(&la[0]); //latitude,
n_s=fgetc(GPS);fgetc(GPS); //N/S,
NMEA_part_scan(&lo[0]); //longtitude,
e_w=fgetc(GPS);fgetc(GPS); //E/W,
while (fgetc(GPS)!=','); //NMEA_part_scan(&speed[0]); //speed,
NMEA_part_scan(&course[0]);//while (fgetc(GPS)!=','); //course,
//NMEA_part_scan(&date[0]); //date,
 
LCD_gotoxy(8,1);
LCD_putc(status);
 
lat=600.0*(la[0]-0x30)+60.0*(la[1]-0x30)+atof(&la[2]);
lon=600.0+60.0*(lo[2]-0x30)+atof(&lo[3]);
azimut=atol(course)/360*8;
}
 
void read_ee_gc(int8 numgc)
{
int8 a,b;
int8 *point;
 
a=(13*numgc) + 1; //5*char + 4byte float LAT + 4byte float LON
LCD_gotoxy(1,1);
LCD_putc('G');LCD_putc('P');
for(b=0;b<5;b++)LCD_putc(read_eeprom(a++));
point=&gc_lat;
for (b=0;b<4;b++) *(point++)=read_eeprom(a++);
point=&gc_lon;
for (b=0;b<4;b++) *(point++)=read_eeprom(a++);
}
 
int8 atan2_my(float x,float y)
{
float z;
int8 arg;
if (y==0) z=abs(x)/0.0001;
else z=abs(x)/abs(y);
if (z < TAN22) arg=0;
else
{
if (z < TAN67) arg=2;
else arg=3;
}
if (x>=0 && y<=0) return (4-arg);
if (x<0 && y<=0) return (4+arg);
if (x<0 && y>0) return (8-arg);
return arg;
}
 
void calc_distanc_azimut(void)
{
lon=(gc_lon-lon)*1214; // metry (uhly v minutach)
lat=(gc_lat-lat)*1854; // metry (uhly v minutach)
 
lcd_gotoxy(3,2);
printf(LCD_putc,"%5Lum",(int32) sqrt((lon*lon) + (lat*lat)));
 
azimut=atan2_my(lon,lat)-azimut;
if (azimut<0) azimut+=8;
if (azimut>8) azimut-=8;
 
lcd_gotoxy(1,2);
switch (azimut)
{
case 0: LCD_send_data(ASCII_ARROW_UP);break;
case 1: LCD_send_data(ARROW_UR);break;
case 2: LCD_send_data(ASCII_ARROW_R);break;
case 7: LCD_send_data(ARROW_UL);break;
case 6: LCD_send_data(ASCII_ARROW_L);break;
default :LCD_send_data(ASCII_ARROW_DOWN);
}
}
 
void PC_part_scan(int8 *point)
{
int8 a;
a=0;
while (a!=',') {a=fgetc(PC); *(point++)=a;}
*(--point)=0x00;
}
 
// line format: name,float,float,
#INT_RDA
void terminal(void)
{
int8 a,b;
int8 *point;
char name[6];
restart_wdt();
PC_part_scan(name);
PC_part_scan(la);
PC_part_scan(lo);
lat=60*atof(la);
lon=60*atof(lo);
a=read_eeprom(0);
if (a > MAX_GC_POINT) a=0;
write_eeprom(0,a+1);
sel=a-1;
a=(13*a)+1;
for (b=0;b<5;b++) write_eeprom(a++,name[b]);
point=&lat;
for (b=0;b<4;b++) write_eeprom(a++,*(point+b));
point=&lon;
for (b=0;b<4;b++) write_eeprom(a++,*(point+b));
}
 
void main(void)
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_wdt(WDT_2304MS);
 
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
 
output_low(LCD_RESET);
output_high(LCD_CS);
delay_ms(5);
output_high(LCD_RESET);
delay_ms(5);
LCD_send_command(0x80);
printf(LCD_send_data,ARROWL);
LCD_send_command(0x88);
printf(LCD_send_data,ARROWR);
LCD_init();
LCD_cursor_off();
 
sel++;
if (sel > MAX_GC_POINT) sel=0;
read_ee_gc(sel);
 
while (TRUE)
{
restart_wdt();
NMEA_GPRMC();
calc_distanc_azimut();
}
}
 
/Designs/GPSnavigator/SW/PIC16F876A/GPS_LCD_876_A2.h
0,0 → 1,9
#include <16F876A.h>
//#device *=16
 
#FUSES WDT //Watch Dog Timer
 
#FUSES XT,NOPROTECT,NOLVP,NOBROWNOUT
#use delay(clock=4000000)
#use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PC)
#use rs232(baud=4800,parity=N,xmit=PIN_C1,rcv=PIN_B5,bits=8,stream=GPS)
/Designs/GPSnavigator/SW/PIC16F876A/GPS_LCD_876_A2.txt
0,0 → 1,5
Tento SW je funkèní na LCD z mobilního telefonu alcatel.
Zapojení vývodù je jiné než uvádí dokumentace.
Na pøepínání bodù slouží tlaèítko reset.
 
SW je minimalizován tak, aby šel použít PCU s flash 4K.
/Designs/GPSnavigator/SW/PIC16F876A/LCD_ALCATEL.c
0,0 → 1,170
/*
DEMO FILE FOR ALCATEL HT1 LCD
mija 7.1.2008 ver.: 1.0
*/
 
//**************************************************************
 
#ifndef LCD_CS
#define LCD_CS PIN_B0
#define LCD_DATA PIN_B1
#define LCD_CLK PIN_B2
#define LCD_A0 PIN_B3
#define LCD_RESET PIN_B4
#endif
 
BYTE const LCD_INIT_STRING[6] = {0x61,0x3D,0x70,0x42,0x57,0x7B};
 
//datacheet S1D12305
 
//**************************************************************
 
void LCD_init(void);
 
void LCD_putc(int8 data);
void LCD_send_command(int8 data);
void LCD_send_data(int8 data);
void LCD_clear();
void LCD_gotoxy(int8 x, int8 y);
void LCD_send(int8 data);
 
void LCD_corsor_off(void);
void LCD_cursor_on(void);
 
void LCD_contrast(int8 contrast);
void LCD_icon(int8 icon,int8 segment);
 
//**************************************************************
 
void LCD_init(void)
{
int8 i;
 
output_low(LCD_RESET);
output_high(LCD_CS);
delay_ms(5);
output_high(LCD_RESET);
delay_ms(5);
for (i=0;i<6;i++) LCD_send_command(LCD_INIT_STRING[i]);
delay_ms(20);
LCD_clear();
}
 
void LCD_putc(int8 data)
{
if (data == '\n') {LCD_send_command(0xC0);return;}
data+=4;
LCD_send_data(data);
}
 
void LCD_send_command(int8 data)
{
output_low(LCD_A0);
LCD_send(data);
output_high(LCD_A0);
}
 
void LCD_send_data(int8 data)
{
output_high(LCD_A0);
LCD_send(data);
}
 
void LCD_clear()
{
int8 a;
 
LCD_send_command(0xB0);
for (a=0;a<=11;a++) LCD_putc(0x20);
LCD_send_command(0xC0);
for (a=0;a<=11;a++) LCD_putc(0x20);
LCD_send_command(0xF0);
for (a=0;a<=11;a++) LCD_send_data(0x0);
LCD_gotoxy(1,1);
}
 
void LCD_gotoxy(int8 x, int8 y)
{
x--;y--;
if ( x>11 || y>1 ) return;
if (y) LCD_send_command(0xC0|x);
else LCD_send_command(0xB0|x);
}
 
void LCD_send(int8 data)
{
int8 a;
 
output_low(LCD_CS);
for (a=0;a<=7;a++)
{
output_low(LCD_CLK);
output_low(LCD_DATA);
if (data & 0x80) output_high(LCD_DATA);
output_high(LCD_CLK);
data<<=1;
}
output_high(LCD_CS);
}
 
void LCD_cursor_off(void)
{
LCD_send_command(0x31);
}
 
void LCD_cursor_on(void)
{
LCD_send_command(0x3D);
}
 
void LCD_contrast(int8 contrast)
{
LCD_send_command(0x70|(0x0F & contrast));
}
 
void LCD_icon(int8 znak,int8 segment)
{
LCD_send_command(znak);
LCD_send_data(segment);
}
 
//**************************************************************
//*** defines for segments icons ***
 
#define LCD_SEGMENT_OFF 0x0
 
#define LCD_BATTERIE 0xF0
#define SEG_BAT_EMP 0x4
#define SEG_BAT_LOW 0xC
#define SEG_BAT_FULL 0xE
#define LCD_PC 0xF2
#define SEG_PC 0x10
#define LCD_OFF_RING 0xF3
#define SEG_RING 0x8
#define LCD_CALL_MISSED 0xF4
#define SEG_MISSED 0x10
#define LCD_CASSETTE 0xF5
#define SEG_CASSETTE 0x8
#define LCD_MESSAGE 0xF6
#define SEG_MESSAGE 0x10
#define SEG_MESS_FULL 0x18
#define LCD_CALL_DIVERT 0xF8
#define SEG_DIVERT 0x4
#define LCD_CLOCK 0xF9
#define SEG_CLOCK 0x8
#define LCD_SIGNALL 0xFB
#define SEG_SIGNALL1 0x2
#define SEG_SIGNALL2 0xA
#define SEG_SIGNALL3 0xE
#define SEG_SIGNALL4 0x1E
 
//**************************************************************
//*** ASCII char ***
 
#define ASCII_CLOCK 0xD0
#define ASCII_ARROW_UP 0xDA
#define ASCII_ARROW_DOWN 0xD7
#define ASCII_ARROW_R 0xD8
#define ASCII_ARROW_L 0xD9
#define ASCII_ARROW_UR 0xE7
#define ASCII_ARROW_DR 0xE8