- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Ce tutoriel permet de se familiariser avec :
La réception des trames GPS et leurs exploitations.
La conversion de l’heure UTC envoyée par le GPS en heure locale en tenant compte des décalages horaires été / hiver.
L’affichage des données sur un LCD 4x20 en liaison I2C avec un PIC et qui indique la date, l'heure locale, la longitude, la latitude, la vitesse et l'azimut).
Matériel :
Une carte Easy Pic 5 équipé d’un PIC 18F2520
Un récepteur GPS GP-735T (Ou un module NEO-6M-001 qui coûte que quelques Euros)
https://www.lextronic.fr/P27906-rcepteur-gps-oem-gp-735t.html
Un afficheur LCD 4x20. + module de conversion I2C – parallèle PCF8574A
1 / Partie GPS
Liaison PIC – GPS
Transmission des données entre le module GPS et le PIC en TTL à 9600 bauds
Une LED sur RA0 indique la réception d'un nouveau paquet de trames.
Lecture des trames avec extraction de la trame GPRMC :
Le GPS envoi un paquet de trames avec en début de chaque trame le caractère $ et en fin de trame les caractères CR LF.
Détail de la trame GPRMC.
Nota : Le champ Déclinaison n’est pas transmis par le module GP-735T
Extraction de la trame GPRMC :
Code : Tout sélectionner
'Lecture des trames GPS avec filtre sur la trame GPRMC___________________________
Deb: Rec = ""
T1 = 0
i = 0
do 'Recherche début trame (caractère $)
loop until ReadChr = 36
i = -1
do 'Extraction Trames
inc(i)
Rec = Rec + char(ReadChr) 'Lecture trame caractère par caractère
if i = 2 then
if Rec[2]="R" then inc(T1) else dec(T1) end if 'Fltrer sur trame RMC
end if
if i = 3 then
if Rec[3]="M" then inc(T1) else dec(T1) end if
end if
if i = 4 then
if Rec[4]="C" then inc(T1) else dec(T1) end if
if T1 <> 3 then goto Deb end if 'GPRMC non trouvé
end if
loop until Rec[i]=chr(10) 'Fin trame
Extraction des champs de la trame GPRMC :
Comme la taille de certains champs est variable, il faut utiliser le séparateur virgule pour extraire les différents champs.
Code : Tout sélectionner
'Extraction des champs de la trame GPRMC________________________________________
Scv = ""
Indv = 0
for Bc1 = 0 to strlen(Rec)
if Rec[Bc1]="*" then Pchs = Bc1 end if 'Position caractère *
if Bc1 > 5 then 'Néglige GPRMC,
if Rec[Bc1] <> "," then
Scv = Scv + Rec[Bc1]
else
if Indv = 0 then Cp.Hr= Scv[0]+Scv[1]+Scv[2]+Scv[3]+Scv[4]+Scv[5] end if
if Indv = 1 then Cp.Va = Scv end if
if Indv = 2 then Cp.La = Scv end if
if Indv = 3 then Cp.Lad = Scv end if
if Indv = 4 then Cp.Lo = Scv end if
if Indv = 5 then Cp.Lod = Scv end if
if Indv = 6 then Cp.Vi = Scv end if
if Indv = 7 then Cp.Az = Scv end if
if Indv = 8 then Cp.Dt = Scv end if
Scv = ""
inc(Indv)
end if
end if
next Bc1
Lecture du checksum envoyé avec la trame :
Chs= "00" + Rec[Pchs+1] + Rec[Pchs+2] 'Checksum dans la trame, Pchs = position de *
Calcul du checksum de la trame reçue
Ce calcul est fait sur la portion de trame compris entre les caractères $ (36) et * (42)
Code : Tout sélectionner
'Fonction contrôle cheksum (entre "$" et "*" et renvoi 0 si ok)_________________
sub function CtrlCs(dim byref Rec3 as string[80], dim byref ChS1 as string[4],dim Pt as word ) as integer
dim ChSum as word
dim Bc as integer
dim ChSumTxt as string[4]
ChSum = 0
for bc = 0 to (Pt - 1)
ChSum = ChSum xor ord(Rec3[Bc]) 'Calcul checksum sur trame recue
next bc
ChSumTxt = ""
wordtohex(ChSum,ChSumTxt)
result = StrCmp(ChSumTxt,ChS1) 'Si Cs reçu = Cs calculé alors result = 0
end sub
Calcul timestamp heure et date reçus du GPS :
Comme le GPS envoi l’heure UTC il faut la convertir en heure locale.
Pour convertir l’heure UTC en heure locale, nous devons comparer le timestamp de l’heure actuelle aux timestamps des changements d’horaires été et hiver
Pour cela nous utilisons Time_dateToEpoch de la librairie Time, qui transforme une date heure en en une valeur LongInt qui représente le nombre de secondes depuis le 1er janvier 1960 à 00:00:00.
Code : Tout sélectionner
'Calcul timestamp actuel________________________________________________________
sub function CalcEpoch(dim byref GmtSat as string[12])as longint
dim ts1 as TimeStruct
J1Str, M1Str, H1Str, N1Str, S1Str, Yy as string[3]
Jr, Mo,He, Mn, Se as word
Y1Str as string[5]
Yr as word
H1Str = GmtSat[0]+ GmtSat[1]
He = strtoword("0"+H1Str)
N1Str = GmtSat[2]+ GmtSat[3]
Mn = strtoword("0"+N1Str)
S1Str = GmtSat[4]+ GmtSat[5]
Se = strtoword("0"+S1Str)
J1Str = GmtSat[6]+ GmtSat[7]
Jr = strtoword("0"+J1Str)
M1Str = GmtSat[8]+ GmtSat[9]
Mo = strtoword("0"+M1Str)
Y1Str = "20" + GmtSat[10]+ GmtSat[11]
Yr = strtoword(Y1Str)
Ts1.ss = byte(Se)
Ts1.mn = byte(Mn)
Ts1.hh = byte(He)
Ts1.wd = 0
Ts1.md = byte(Jr)
Ts1.mo = byte(Mo)
Ts1.yy = word(Yr)
result = Time_DateToEpoch(@Ts1) 'Timestamp actuel
end sub
Calcul Timestamp du changement d’heure hiver été.
Code : Tout sélectionner
'Recherche jour du passage hiver --> éte________________________________________
sub function TsEte(dim An1 as word) as longint
Ts10.ss = 0
Ts10.mn = 0
Ts10.hh = 1 '1 heure UTC
Ts10.wd = 0
Ts10.md = 31 - (integer(((5*(2000+An1))/4)+4)) mod 7 'Jour
Ts10.mo = 3 'Mois de mars
Ts10.yy = An1+2000
result = Time_DateToEpoch(@Ts10) 'Timestamp été
end sub
Calcul Timestamp du changement d’heure été hiver.
Code : Tout sélectionner
'Recherche jour du passage été --> hiver________________________________________
sub function TsHiv(dim An1 as word) as longint
Ts10.ss = 0
Ts10.mn = 0
Ts10.hh = 1 '1 heure UTC
Ts10.wd = 0
Ts10.md = 31 - (integer(((5*(2000+An1))/4)+1)) mod 7 'Jour
Ts10.mo = 10 'Mois d'octobre
Ts10.yy = An1+2000
result = Time_DateToEpoch(@Ts10) 'Timestamp été
end sub
Conversion Heure UTC en heure locale :
Nous pouvons maintenant définir le décalage horaire à appliquer.
Par convention le passage :
Hiver --> été se fait le dernier dimanche de mars à 01:00:00 soit UTC + 7200 secondes.
Eté --> hiver se fait le dernier dimanche d’octobre à 01:00:00 soit UTC + 3600 secondes.
Code : Tout sélectionner
EpAct = CalcEpoch(UtcSat) 'Calcul timestamp actuel
EpEte = TsEte(AnAct) 'Timestamp hiver --> éte
EpHiv = TsHiv(AnAct) 'Timestamp été --> hiver
if ((EpAct >= EpEte) and (EpAct < EpHiv)) then
EpochCor = EpAct + 7200 'Si été Utc + 2
else
EpochCor = EpAct + 3600 'Si hiver Utc + 1
end if
Time_epochToDate(EpochCor,@ts2) 'Decode le timestamp corrigé
Mise en forme heure et date :
Code : Tout sélectionner
'Mise en forme date time________________________________________________________
'hh
bytetostr(ts2.hh,hhStr)
ltrim(hhStr)
if ts2.hh < 10 then hhStr = "0" + hhStr end if
'mn
bytetostr(ts2.mn,mnStr)
ltrim(mnStr)
if ts2.mn < 10 then mnStr = "0" + mnStr end if
'ss
bytetostr(ts2.ss,ssStr)
ltrim(ssStr)
if ts2.ss < 10 then ssStr = "0" + ssStr end if
ScTime = hhStr+":"+mnStr+":"+ssStr
'md
bytetostr(ts2.md,mdStr)
ltrim(mdStr)
if ts2.md < 10 then mdStr = "0" + mdStr end if
'mo
bytetostr(ts2.mo,moStr)
ltrim(moStr)
if ts2.mo < 10 then moStr = "0" + moStr end if
'yy
wordtostr(ts2.yy,yyStr)
ltrim(yyStr)
ScDate = mdStr+"/"+moStr+"/"+yyStr
VitKmh = ConvVit(Cp.Vi) 'Conversion noeuds – kmh
Formatage dd°mm' ss.ddd'' :
Code : Tout sélectionner
'Procedure affichage latitude au format dd°mm'ss.ddd_________________________________
Sub procedure AfLat(dim byref Lat1 as string[10])
dim SecLat as string[6]
SecLatFl as float
SecLatStr as string[17]
copy(SecLat,Lat1,4,6) 'copie partie secondes
SecLatFl = str2float(SecLat) * 60
Float2Str(SecLatFl,SecLatStr,3)
Ltrim(SecLatStr)
ScLat = "Lat = " +Cp.La[0]+ Cp.La[1]+chr($DF)+Cp.La[2]+Cp.La[3]+"'"+ SeclatStr +" "+ Cp.Lad
I2c_lcd_out(3,1,Sclat) 'Affiche latitude sur Lcd
end sub
Affichage résultats :
Code : Tout sélectionner
'Affichage sur LCD______________________________________________________________
I2c_lcd_out(1,1,ScDate+" "+ScTime)
AfLat(cp.La)
AfLon(Cp.Lo)
I2c_lcd_out(4,1,("V = "+VitKmh + " Az = " + Cp.Az))
Lecture des trames GPS avec un PC :
A la mise sous tension, il faut entre 30 et 240 secondes pour obtenir la liaison avec le GPS.
2 / Partie LCD
Liaison PIC – LCD :
Broche RC3 (SLC) du PIC vers broche SCL du module PCF 8574A
Broche RC4 (SDA) du PIC vers broche SDA du module PCF 8574A
Mettre des résistances pull up sur SCL et SDA sur PCF 8574T, mais inutile sur PCF 8574A.
VCC EasyPic vers VCC PCF 8574A
GND Easy Pic vers GND PCF 8574A
Détail du module PCF 8574A :
Ce module est à souder à l’arrière du LCD en respectant l’orientation.
Adressage du PCF 8574A :
Le code complet en MikroBasic :
Les librairies utilisées dans ce projet :
Strng_P18 se trouve sous Libstock 1487242654_Utilities_MikroBasic_Pic.
Le fichier de configuration : (Pour l'utiliser, il faut renommer l'extension en .CfgSch)
Ram utilisé = 555 octets (36.6%)
Rom utilisé = 17961 octets (54.8%) d'où l'utilisation d'un PIC 18F2520
Code : Tout sélectionner
program Gps_Lcd
'Projet GpsLcd 20/10/2017 en MikroBasic
'Ce programme reçoit les trames GPS une fois par seconde.
'La trame GPRMC est isolée et les différents champs qui la composent sont extraits.
'L'heure UTC reçue est convertie en heure locale été - hiver.
'Les champs sont affichés sur un LCD I2C 4x20.
'PIC 18F2520, Q = 8 Mhz (PLL 4 x Fosc1 32 Mhz).
'Librairie StrngUtils_p18 activée
'Module LCD I2C 4x20____________________________________________________________
include Mod_Lcd_I2c 'Module avec les procédures de gestion I2C_LCD
'Déclaration structure GPS__________________________________________________________
structure GpsStruc
dim Hr as string[6] 'Heure hhmmss
dim Va as string[1] 'Validation
dim La as string[10] 'Latitude
dim Lad as string[1] 'Direction latitude
dim Lo as string[11] 'Longitude.
dim Lod as string[1] 'Direction longitude
dim Vi as string[5] 'Vitesse
dim Az as string[5] 'Azimut
dim Dt as string[6] 'Date jjmmaa
end structure
'Déclaration des variables______________________________________________________
Dim Rec as string[80] 'Trame reçue
ScTime as string[8] 'hh:mm:ss
ScDate as string[10] 'jj/mm/aaaa
ScLat,ScLon as string[20] 'Lignes Lcd
UtcSat as string[12] 'Heure date UTC
i, Bc1 as integer 'Indices de boucles
Indv, T1, Pchs as byte 'Cnt champs
Chs as string[4] 'Cheksum lu en string
VitKmh as string[5] 'Vitesse en kmh en string
ts2, ts10 as TimeStruct 'Structures Time
EpochCor, EpAct, EpEte, EpHiv as longint 'Timestamps
hhStr,mnStr,ssStr,mdStr,moStr as string[3] 'Chaines date time
yyStr as string[5] 'Chaine année
AnAct as word 'Année courte actuelle
Scv as string[11] 'Champs
Cp as GpsStruc 'Structure champs
'Fonction lecture RX Uart_______________________________________________________
sub function ReadChr as byte
do
loop until UART1_Data_Ready = 1
result=UART1_Read
end sub
'Fonction contrôle cheksum (entre "$" et "*" et renvoi 0 si ok)_________________
sub function CtrlCs(dim byref Rec3 as string[80], dim byref ChS1 as string[4],dim Pt as word ) as integer
dim ChSum as word
dim Bc as integer
dim ChSumTxt as string[4]
ChSum = 0
for bc = 0 to (Pt - 1)
ChSum = ChSum xor ord(Rec3[Bc]) 'Calcul checksum sur trame recue
next bc
ChSumTxt = ""
wordtohex(ChSum,ChSumTxt)
result = StrCmp(ChSumTxt,ChS1) 'Si Cs reçu = Cs calculé alors result = 0
end sub
'Conversion vitesse en noeud en kmh_____________________________________________
sub function ConvVit(dim byref ScVit as string[5]) as string[5]
dim PosP as word 'Position du point décimal
Ve, Vd as string[5] 'Valeurs entiere et décimale en string
VeW, VdW as word 'Valeurs entiere et décimale en word
Vf as float 'Vitesse en kmh en float
Vfs as string[23] 'Vitesse en kmh en string
PosP = StrStr(ScVit,".") 'Recherche position point décimal
if PosP = 1 then 'Si point en 1 (origine 0)
Ve = ScVit[0]+""
Vd = ScVit[2] + ScVit[3] + ScVit[4]
end if
if PosP = 2 then 'Si point en 2
Ve = ScVit[0] + ScVit[1]
Vd = ScVit[3] + ScVit[4]
end if
if PosP = 3 then 'Si point en 3
Ve = ScVit[0] + ScVit[1] + ScVit[2]
Vd = ScVit[4]+""
end if
VeW = strtoword(Ve) 'Conversion valeur entiere en word
VdW = strtoword(Vd) 'Conversion valeur décimale en word
if PosP = 1 then VF = (float(VeW) + (float(VdW) /1000))*1.852 end if
if PosP = 2 then VF = (float(VeW) + (float(VdW) /100))*1.852 end if
if PosP = 3 then VF = (float(VeW) + (float(VdW) /10))*1.852 end if
floattostr(Vf,Vfs)
result = Vfs[0]+Vfs[1]+Vfs[2]+Vfs[3]+Vfs[4]
end sub
'Recherche jour du passage hiver --> éte (Dernier dimanche de mars à 1h UTC)____
sub function TsEte(dim An1 as word) as longint
Ts10.ss = 0
Ts10.mn = 0
Ts10.hh = 1 '1 heure
Ts10.wd = 0
Ts10.md = 31 - (integer(((5*(2000+An1))/4)+4)) mod 7 'Jour
Ts10.mo = 3 'Mois de mars
Ts10.yy = An1+2000 'An
result = Time_DateToEpoch(@Ts10) 'Timestamp été
end sub
'Recherche jour du passage été --> hiver (Dernier dimanche d'octobre à 1h UTC)__
sub function TsHiv(dim An1 as word) as longint
Ts10.ss = 0
Ts10.mn = 0
Ts10.hh = 1 '1 heure
Ts10.wd = 0
Ts10.md = 31 - (integer(((5*(2000+An1))/4)+1)) mod 7 'Jour
Ts10.mo = 10 'Octobre
Ts10.yy = An1+2000 'An
result = Time_DateToEpoch(@Ts10) 'Timestamp été
end sub
'Calcul timestamp actuel________________________________________________________
sub function CalcEpoch(dim byref GmtSat as string[12])as longint
dim ts1 as TimeStruct
J1Str, M1Str, H1Str, N1Str, S1Str, Yy as string[2]
Jr, Mo,He, Mn, Se as word
Y1Str as string[5]
Yr as word
H1Str = GmtSat[0]+ GmtSat[1]
He = strtoword("0"+H1Str)
N1Str = GmtSat[2]+ GmtSat[3]
Mn = strtoword("0"+N1Str)
S1Str = GmtSat[4]+ GmtSat[5]
Se = strtoword("0"+S1Str)
J1Str = GmtSat[6]+ GmtSat[7]
Jr = strtoword("0"+J1Str)
M1Str = GmtSat[8]+ GmtSat[9]
Mo = strtoword("0"+M1Str)
Y1Str = "20" + GmtSat[10]+ GmtSat[11]
Yr = strtoword(Y1Str)
Ts1.ss = byte(Se)
Ts1.mn = byte(Mn)
Ts1.hh = byte(He)
Ts1.wd = 0
Ts1.md = byte(Jr)
Ts1.mo = byte(Mo)
Ts1.yy = word(Yr)
result = Time_DateToEpoch(@Ts1) 'Timestamp actuel
end sub
'Procedure affichage latitude au format dd°mm'ss.ddd_________________________________
Sub procedure AfLat(dim byref Lat1 as string[10])
dim SecLat as string[6]
SecLatFl as float
SecLatStr as string[17]
copy(SecLat,Lat1,4,6) 'copie partie secondes
SecLatFl = str2float(SecLat) * 60
Float2Str(SecLatFl,SecLatStr,3)
Ltrim(SecLatStr)
ScLat = "Lat = " +Cp.La[0]+ Cp.La[1]+chr($DF)+Cp.La[2]+Cp.La[3]+"'"+ SeclatStr +" "+ Cp.Lad
I2c_lcd_out(3,1,Sclat) 'Affiche latitude sur Lcd
end sub
'Procedure affichage longitude au format dd°mm'ss.ddd_________________________________
Sub procedure AfLon(dim byref Lon1 as string[11])
dim SecLon as string[6]
SecLonFl as float
SecLonStr as string[17]
copy(SecLon,Lon1,5,6) 'Copie partie secondes
SecLonFl = str2float(SecLon) * 60
Float2Str(SecLonFl,SecLonStr,3)
Ltrim(SecLonStr)
ScLon = "Lon =" +Cp.Lo[0]+ Cp.Lo[1]+Cp.Lo[2]+chr($DF)+Cp.Lo[3]+Cp.Lo[4]+"'"+ SeclonStr +" "+ Cp.Lod
I2c_lcd_out(2,1,Sclon) 'Affiche longitude sur Lcd
end sub
main:'__________________________________________________________________________
UART1_INIT(9600)
delay_ms(250)
ADCON1 = $0F
CMCON = 7
PORTA = $0
PORTB = $0
PORTC = $0
TRISA = %00000000
TRISB = %00000000
TRISC = %10000000
I2C1_Init(100000) 'Init I2C à 100 kbit / s.
delay_ms(500)
I2C_LCD_Init() 'Init LCD
I2C_LCD_Cmd(_LCD_CURSOR_OFF) 'Curseur non visible
I2C_LCD_Cmd(_LCD_CLEAR) 'Effacement du LCD
I2C_Lcd_Out(1,1," Demo GPS ")
Delay_ms(2000)
I2c_Lcd_Out(3,1,"Recherche satellite ")
While true
'Lecture des trames GPS avec filtre sur la trame GPRMC___________________________
Deb: Rec = ""
T1 = 0
i = 0
do 'Recherche début trame (caractère $)
loop until ReadChr = 36
i = -1
do 'Extraction Trames
inc(i)
Rec = Rec + char(ReadChr) 'Lecture trame caractère par caractère
if i = 2 then
if Rec[2]="R" then inc(T1) else dec(T1) end if 'Fltrer sur trame RMC
end if
if i = 3 then
if Rec[3]="M" then inc(T1) else dec(T1) end if
end if
if i = 4 then
if Rec[4]="C" then inc(T1) else dec(T1) end if
if T1 <> 3 then goto Deb end if 'GPRMC non trouvé
end if
loop until Rec[i]=chr(10) 'Fin trame
'Extraction des champs de la trame GPRMC________________________________________
Scv = ""
Indv = 0
for Bc1 = 0 to strlen(Rec)
if Rec[Bc1]="*" then Pchs = Bc1 end if 'Position caractère *
if Bc1 > 5 then 'Néglige GPRMC,
if Rec[Bc1] <> "," then
Scv = Scv + Rec[Bc1]
else
if Indv = 0 then Cp.Hr= Scv[0]+Scv[1]+Scv[2]+Scv[3]+Scv[4]+Scv[5] end if
if Indv = 1 then Cp.Va = Scv end if
if Indv = 2 then Cp.La = Scv end if
if Indv = 3 then Cp.Lad = Scv end if
if Indv = 4 then Cp.Lo = Scv end if
if Indv = 5 then Cp.Lod = Scv end if
if Indv = 6 then Cp.Vi = Scv end if
if Indv = 7 then Cp.Az = Scv end if
if Indv = 8 then Cp.Dt = Scv end if
Scv = ""
inc(Indv)
end if
end if
next Bc1
Chs= "00" + Rec[Pchs+1] + Rec[Pchs+2] 'Checksum reçu
UtcSat = Cp.Hr + Cp.Dt 'hhmmss + jjmmaa
AnAct = strtoword(Cp.Dt[4]+ Cp.Dt[5]) 'An actuel
if CtrlCs(Rec,ChS, Pchs) = 0 then 'Si checksum calculé = checksum reçu
if Cp.Va[0] = "A" then 'Si trame valide
LatA.0 = 1 'Led RA0 = 1
EpAct = CalcEpoch(UtcSat) 'Calcul timestamp actuel
EpEte = TsEte(AnAct) 'Calcul hiver --> éte
EpHiv = TsHiv(AnAct) 'Calcul été --> hiver
if ((EpAct >= EpEte) and (EpAct < EpHiv)) then
EpochCor = EpAct + 7200 'Si été Utc + 2
else
EpochCor = EpAct + 3600 'Si hiver Utc + 1
end if
Time_epochToDate(EpochCor,@ts2) 'Decode le timestamp corrigé
'Mise en forme date time________________________________________________________
'hh
bytetostr(ts2.hh,hhStr)
ltrim(hhStr)
if ts2.hh < 10 then hhStr = "0" + hhStr end if
'mn
bytetostr(ts2.mn,mnStr)
ltrim(mnStr)
if ts2.mn < 10 then mnStr = "0" + mnStr end if
'ss
bytetostr(ts2.ss,ssStr)
ltrim(ssStr)
if ts2.ss < 10 then ssStr = "0" + ssStr end if
ScTime = hhStr+":"+mnStr+":"+ssStr
'md
bytetostr(ts2.md,mdStr)
ltrim(mdStr)
if ts2.md < 10 then mdStr = "0" + mdStr end if
'mo
bytetostr(ts2.mo,moStr)
ltrim(moStr)
if ts2.mo < 10 then moStr = "0" + moStr end if
'yy
wordtostr(ts2.yy,yyStr)
ltrim(yyStr)
ScDate = mdStr+"/"+moStr+"/"+yyStr
VitKmh = ConvVit(Cp.Vi) 'Conversion noeuds - kmh
'Affichage sur LCD______________________________________________________________
I2c_lcd_out(1,1,ScDate+" "+ScTime)
AfLat(cp.La)
AfLon(Cp.Lo)
I2c_lcd_out(4,1,("V = "+VitKmh + " Az = " + Cp.Az))
end if 'Validation A
end if 'Checksum OK
LatA.0 = 0 'Led RA0 = 0
delay_ms(50)
wend
end.
Le module de gestion du LCD I2C :
'Ce module utilise la librairie I²C full master MSSP
Code : Tout sélectionner
'Commandes du LCD
symbol _LCD_FIRST_ROW = $80 'Déplace curseur en ligne 1
symbol _LCD_SECOND_ROW = $C0 'Déplace curseur en ligne 2
symbol _LCD_THIRD_ROW = $94 'Déplace curseur en ligne 3
symbol _LCD_FOURTH_ROW = $D4 'Déplace curseur en ligne 4
symbol _LCD_CLEAR = $01 'Efface LCD
symbol _LCD_RETURN_HOME = $02 'Retour curseur en position initiale
symbol _LCD_CURSOR_OFF = $0C 'Curseur invisible
symbol _LCD_UNDERLINE_ON = $0E 'Curseur bas visible
symbol _LCD_BLINK_CURSOR_ON = $0F 'Curseur clignotant
symbol _LCD_MOVE_CURSOR_LEFT = $10 'Curseur à gauche sans changer les datas en RAM
symbol _LCD_MOVE_CURSOR_RIGHT = $14 'Curseur à droite sans changer les datas en RAM
symbol _LCD_TURN_ON = $0C 'LCD marche
symbol _LCD_TURN_OFF = $08 'LCD arrêté
symbol _LCD_SHIFT_LEFT = $18 'Shift LCD à gauche sans changer les datas en RAM
symbol _LCD_SHIFT_RIGHT = $1E 'Shift LCD à droite sans changer les datas en RAM
symbol LCD_ADDR = $7E 'Adresse PCF 8574AT (3 straps ouverts soit 111)
dim txt1 as string[20] 'Texte ligne 1
txt2 as string[20] 'Texte ligne 2
txt3 as string[20] 'Texte ligne 3
txt4 as string[20] 'Texte ligne 4
sub procedure I2C_LCD_Cmd (dim out_char as byte)
sub procedure I2C_LCD_Init()
sub procedure I2C_LCD_Chr(dim row as byte, dim column as byte, dim out_char as byte)
sub procedure I2C_LCD_Chr_Cp(dim out_char as byte)
sub procedure I2C_LCD_Out(dim row as byte, dim column as byte, dim byref text as string)
sub procedure I2C_LCD_Out_Cp(dim byref text as string)
implements
'_Envoi de commandes au LCD______________________________________________________
sub procedure I2C_LCD_Cmd (dim out_char as byte)
dim hi_n, lo_n, rs as byte
rs = 0
hi_n = out_char and $F0
lo_n = (out_char << 4) and $F0
I2C1_Start()
I2C1_Is_Idle()
I2C1_Wr(LCD_ADDR)
I2C1_Is_Idle()
I2C1_Wr(hi_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(hi_n or rs or $00 or $08)
I2C1_Is_Idle()
Delay_us(100)
I2C1_Wr(lo_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(lo_n or rs or $00 or $08)
I2C1_Is_Idle()
I2C1_stop()
if(out_char = $01) then
Delay_ms(2)
end if
end sub
'_Initialisation du LCD_________________________________________________________
sub procedure I2C_LCD_Init()
dim rs as byte
rs = 0
I2C1_Start()
I2C1_Is_Idle()
I2C1_Wr(LCD_ADDR) 'Adresse du module I2C
I2C1_Is_Idle()
Delay_ms(30)
I2C1_Wr($30 or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr($30 or rs or $00 or $08)
I2C1_Is_Idle()
Delay_ms(10)
I2C1_Wr($30 or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr($30 or rs or $00 or $08)
I2C1_Is_Idle()
Delay_ms(10)
I2C1_Wr($30 or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr($30 or rs or $00 or $08)
I2C1_Is_Idle()
Delay_ms(10)
I2C1_Wr($20 or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr($20 or rs or $00 or $08)
I2C1_Is_Idle()
I2C1_Stop()
Delay_ms(10)
I2C_LCD_Cmd($28)
I2C_LCD_Cmd($06)
end sub
'_Envoi un caractère à la position Ligne, Colonne________________________________
sub procedure I2C_LCD_Chr(dim row as byte, dim column as byte, dim out_char as byte)
dim hi_n, lo_n,rs as byte
rs = 1
select case (row)
case 1
I2C_LCD_Cmd($80 + (column - 1)) 'Ligne 1
case 2
I2C_LCD_Cmd($C0 + (column - 1)) 'Ligne 2
case 3
I2C_LCD_Cmd($94 + (column - 1)) 'Ligne 3
case 4
I2C_LCD_Cmd($D4 + (column - 1)) 'Ligne 4
end select
hi_n = out_char and $F0
lo_n = (out_char << 4) and $F0
I2C1_Start()
I2C1_Is_Idle()
I2C1_Wr(LCD_ADDR)
I2C1_Is_Idle()
I2C1_Wr(hi_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(hi_n or rs or $00 or $08)
I2C1_Is_Idle()
Delay_us(100)
I2C1_Wr(lo_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(lo_n or rs or $00 or $08)
I2C1_Is_Idle()
I2C1_stop()
end sub
'_Envoi un caractère à la position courante du curseur__________________________
sub procedure I2C_LCD_Chr_Cp(dim out_char as byte)
dim hi_n, lo_n, rs as byte
rs = $01
hi_n = out_char and $F0
lo_n = (out_char << 4) and $F0
I2C1_Start()
I2C1_Is_Idle()
I2C1_Wr(LCD_ADDR)
I2C1_Is_Idle()
I2C1_Wr(hi_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(hi_n or rs or $00 or $08)
I2C1_Is_Idle()
Delay_us(100)
I2C1_Wr(lo_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(lo_n or rs or $00 or $08)
I2C1_Is_Idle()
I2C1_stop()
end sub
'_Envoi un texte à la ligne, colonne____________________________________________
sub procedure I2C_LCD_Out(dim row as byte, dim column as byte, dim byref text as string)
dim i as byte
for i = 0 to Strlen(text) - 1
I2C_LCD_Chr(row, column, text[i])
column = column + 1
next i
end sub
'_Envoi un texte à partir de la position du curseur__________________________________________
sub procedure I2C_LCD_Out_Cp(dim byref text as string)
dim i as byte
for i = 0 to Strlen(text) - 1
I2C_LCD_Chr_Cp(text[i])
next i
end sub
end.



Bravo pour ce joli tutoriel pspic


@++
- paulfjujo
Expert- Messages : 2413
- Âge : 72
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :

remark : un test du nb de satellites visibles par le GPS, permettrait de valider ou pas les données ..
et d'avoir un element Qualité de reception.
Probleme vecu, surtout par temps tres nuageux.
A moins que la donnée "Etat A" englobe déja ce test ?


les statistiques RAM et ROM utilisés
et le fichier de config *.cfgsh

Merci pour tes conseils pertinents.
Je viens d'ajouter l'occupation Ram - Rom, ainsi que le fichier de configuration.
Pour utiliser ce fichier il doit être renommé de Txt en Cfgsch, car ce forum n'accepte pas l'extension Cfgsch pour les pièces jointes.
Je ne suis pas certain que le nombre de satellites soit un critère de qualité ?
Dans l'exemple ci-après avec 4 satellites, je n'ai pas de status valide alors qu'au pas suivant j'ai toujours 4 satellites avec un status valide.
Je n'ai pas trouvé les conditions qui font que le status passe de V en A, si quelqu'un a l'explication ?
Ce projet m'a fait découvrir la librairie Utilities/StrngUtils (Libstock), qui est très intérresante pour manipuler des chaines.


Pour le paramétré j'aimerais me servir de la version U-centre 8.15, le seule qui peut tourner sous Windows XP pack3, j'ai lu ton tutoriel
et je m'aperçois que tu branches avec ta com virtuel
TX avec TX
RX avec RX
Est ce que il y aurait pas une erreur, ou doit suivre ce que tu décris ?


Retourner vers « Langage BASIC & PASCAL »
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité