GPSDO SourceCode serial.asm
Release status: Prototype
Description | GPSDO
|
License | |
Author | |
Contributors | Yannick Turcotte
|
Based-on | [[]]
|
Categories | |
CAD Models | |
External Link |
MIT License
Copyright (c) 2020 Yannick Turcotte
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;
;
;Serial routine
.equ baud=9600 ;Baud rate
.equ fosc=10000000 ;Crystal frequency
USART_Init:
in temp, pinb ;check si jumper sur pb3. Si oui on est a 4800 au lieu de 9600
andi temp, 0b00001000
cpi temp, 0
breq onesta4800
ldi r17, high(fosc/(16*baud)-1)
ldi r16, low(fosc/(16*baud)-1)
rjmp setbaudrate
onesta4800:
ldi r17, high(fosc/(16*4800)-1)
ldi r16, low(fosc/(16*4800)-1)
setbaudrate:
STORE UBRR0H, r17
STORE UBRR0L, r16
ldi r16, (1<<RXEN0)|(1<<TXEN0) |(0<<RXCIE0) ; Enable receiver and transmitter, interrupt rx disabled
STORE UCSR0B,r16
ldi r16, (0<<USBS0)|(3<<UCSZ00) ; Set frame format: 8data, 1stop bit
STORE UCSR0C,r16
ret
RX: ; Wait for data to be received
load r17,UCSR0A
sbrs r17,RXC0 ;This flag bit is set when there are unread data in the receive buffer and cleared when the receive buffer is empty. 1 = unread
rjmp RX ;donc loop ici jusqu'au temps que rxc0 vaut 1
lds r16, UDR0 ; Get and return received data from buffer
ret
TX: ; Wait for empty transmit buffer
load r17,UCSR0A ;Load into R17 from SRAM UCSR0A. The UDRE0 Flag indicates if the transmit buffer (UDR0) is ready to receive new data. If UDRE0 is one,
sbrs r17,UDRE0 ;the buffer is empty, and therefore ready to be written.. Skip next instruction If Bit Register is set
rjmp TX
STORE UDR0,r16 ; Put data (r0) into buffer, sends the data
ret
;Ramasse le nombre de satellite et le met dans sateiilteh,l
checkgpgga: ;$GPGGA pour neo 6m MAIS GNGGA sur neo 8M Donc je regarde pour seulement GGA
wdr
rcall rx
cpi temp, $47 ;G
brne checkgpgga
rcall rx
cpi temp, $47 ;G
brne checkgpgga
rcall rx
cpi temp, $41 ;A
brne checkgpgga
;ici on a detecter $GPGGA on doit rammaser le nombre de satellite
clr r18
kjkj: ;on compte 7 virgules. Ensuite on lit le nombre de satellites.
rcall rx
cpi temp, $2C ;,
brne kjkj
inc r18
cpi r18, $07
brne kjkj ;compte 7 virgules
;ici s'en vienne les 2 nombres ascii. Exemple 31, 32 pour 12.
;Addition de code pour gerer les gps module qui envois 9 au lieu de 09.
rcall rx
sts satelliteh, temp
rcall rx
sts satellitel, temp ;ici le nombre de satellites est en ascii dans satelliteh:satellitel exemple 31:32 pour afficher 12.
cpi temp, $2c ;regarde si nous avous recu 9 virgule au lieu de 09
breq pasmoduleublox
ret
pasmoduleublox:
lds temp, satelliteh ;prend 9
sts satellitel, temp ;on le met dans le low
ldi temp, $30
sts satelliteh, temp ;et on met 30 dans le high pour afficher le 0 ---- > 09
ret
;*********************************************************************************************************
;*********************************************************************************************************
affichesatellite:
load r16, UCSR0A ;regarde si ya de quoi qui a été recu par le serial
sbrs r16, RXC0 ;skip if bit in register is set
ret ;rxc0 est a 0 on a rien recu
;on a recu de quoi sur le serial
lds temp, affichesatelliteflag
cpi temp, $01
breq onpeut
ret
onpeut:
adiw yh:yl, $01 ;incremente le compteur du wait car on pert ici une seconde.
rcall checkgpgga ;on ramasse le nombre de satellite
rcall posi2
ldi r31,high(data30*2) ;sat locked =
ldi r30,low(data30*2)
rcall message
lds temp, satelliteh
rcall afficheascii
rcall tx
lds temp, satellitel
rcall afficheascii
rcall tx
rcall nextline
call SatelliteLedDriver
ret
;*********************************************************************************************************
;*********************************************************************************************************
;S=12
affichesatellite2:
load r16, UCSR0A ;regarde si ya de quoi qui a été recu par le serial
sbrs r16, RXC0
ret ;rxc0 est a 0 on a rien recu
rcall checkgpgga ;on ramasse le nombre de satellite
rcall posisat
ldi temp, $53 ; S
rcall afficheascii
call tx
ldi temp, $3d ; =
rcall afficheascii
call tx
lds temp, satelliteh
rcall afficheascii
call tx
lds temp, satellitel
rcall afficheascii
call tx
ldi temp, $2c ;,
call tx
call SatelliteLedDriver
ret
;*********************************************************************************************************
;*********************************************************************************************************
SatelliteLedDriver:
;dois comparer si on a plus que 3 sat et allumer le led sinon le fermer..
lds temp, satelliteh ;39 2c
subi temp, $30
lsl temp
lsl temp
lsl temp
lsl temp
lds r17, satellitel
subi r17, $30
add temp, r17
cpi temp, $3
brge onallumeleled22
;sinon on ferme le led
call SatLedOff
ret
onallumeleled22:
call SatLedOn
ret
;*********************************************************************************************************
;*********************************************************************************************************
;*********************************************************************************************************
;*********************************************************************************************************
;$GPGGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh
afficheheureposition:
;affiche heure pour 10 secondes
rcall videecran
call nextline
load r16, UCSR0A ;regarde si ya de quoi qui a été recu par le serial
sbrs r16, RXC0 ;skip if bit in register is set
rjmp nosat ;rxc0 est a 0 on a rien recu pas de signal
ldi r26, 10
afseconde:
call nextline
rcall checkgpggahp ;ramasse les valeur (heure)
rcall posi1
lds temp, heureh
rcall afficheascii
call tx
lds temp, heurel
rcall afficheascii
call tx
ldi temp, $3A ; :
rcall afficheascii
call tx
lds temp, minuteh
rcall afficheascii
call tx
lds temp, minutel
rcall afficheascii
call tx
ldi temp, $3A ; :
rcall afficheascii
call tx
lds temp, secondeh
rcall afficheascii
call tx
lds temp, secondel
rcall afficheascii
call tx
rcall espace
call espaceserial
ldi temp, $55 ;U
rcall afficheascii
call tx
ldi temp, $54 ;T
rcall afficheascii
call tx
ldi temp, $43 ;C
rcall afficheascii
call tx
attendprochaineseconde:
load r16, UCSR0A ;regarde si ya de quoi qui a été recu par le serial
sbrs r16, RXC0 ;skip if bit in register is set
rjmp attendprochaineseconde ;rxc0 est a 0 on a rien recu
dec r26
brne afseconde
;le temps vien d'etre afficher 10 seconde maintenant latitude et longitude
rcall videecran
call nextline
ldi r26, 10 ;pour 10 seconde
debutdeaffichagelatitudelongitude:
;affiche position pour 10 secondes
rcall ramassegga ;ramasse la string gga au complet incluant l'heure
rcall posi1
call nextline
ldi zh, high(gga) ;adresse de RAM $240 dans Z
ldi Zl, low(gga)
ldi r18, 2 ;on passe 2 virgule pour se rendre a la latitude. On passe par dessus l'heure
aflatitude:
ld r0, z+ ;charge r0 avec le contenu de l'adresse que pointe z
mov temp, r0 ;
cpi temp, $2c ;compare avec virgule
brne aflatitude
dec r18
brne aflatitude
;debut latitude
ld r0, z+ ;4
mov temp, r0 ;
rcall afficheascii
call tx
ld r0, z+ ;6
mov temp, r0 ;
rcall afficheascii
call tx
ldi temp, $27 ;`
rcall afficheascii
call tx
suitelatitude:
ld r0, z+ ;
mov temp, r0 ;compare avec virgule.... pourquoi ? parce que dans différent module il n'y a pas toujours le meme nombres de chiffre apres le point.
cpi temp, $2c ;,
breq emisphere
rcall afficheascii
call tx
rjmp suitelatitude
emisphere:
rcall espace
call espaceserial
ld r0, z+ ;on ecris N ou S
mov temp, r0 ;
rcall afficheascii
call tx
rcall posi2
call nextline
ld r0, z+ ;passe virgule
ld r0, z+
mov temp, r0 ;
rcall afficheascii ;0
call tx
ld r0, z+
mov temp, r0
rcall afficheascii ;7
call tx
ld r0, z+
mov temp, r0
rcall afficheascii ;2
call tx
ldi temp, $27 ;`
rcall afficheascii
call tx
nextline2:
ld r0, z+ ;on affiche le reste jusqua la virgule.
mov temp, r0
cpi temp, $2c
breq nextlinefini
rcall afficheascii
call tx
rjmp nextline2
nextlinefini:
rcall espace
call espaceserial
ld r0, z+ ;W ou E
mov temp, r0
rcall afficheascii
call tx
call nextline
dec r26 ;decremene 26 et on recommence sinon fini
brne debutdeaffichagelatitudelongitude2
ret
debutdeaffichagelatitudelongitude2:
rjmp debutdeaffichagelatitudelongitude
nosat:
call nextline
rcall posi1
ldi r31,high(data36*2) ;P 1 1 sec
ldi r30,low(data36*2)
rcall message
ret
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;check heure seulement
checkgpggahp: ;$GPGGA pour neo 6m MAIS GNGGA sur neo 8M Donc je regarde pour seulement GGA
;checkgga heure position et store dans memoire heure et position
;$xxGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
wdr
rcall rx
cpi temp, $47 ;G
brne checkgpggahp
rcall rx
cpi temp, $47 ;G
brne checkgpggahp
rcall rx
cpi temp, $41 ;A
brne checkgpggahp
clr r18
kjkj1: ;on compte 1 virgules.
rcall rx
cpi temp, $2C ;,
brne kjkj1
inc r18
cpi r18, $01
brne kjkj1 ;compte 1 virgules
;ici s'en vienne les 6 nombres ascii. Exemple 31, 32 pour 12.
rcall rx
sts heureh, temp
rcall rx
sts heurel, temp ;
rcall rx
sts minuteh, temp
rcall rx
sts minutel, temp ;
rcall rx
sts secondeh, temp
rcall rx
sts secondel, temp ;
ret
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
ramassegga: ;$ramasse toute la string de gga. et la met dans $240 +
wdr
rcall rx
cpi temp, $47 ;G
brne ramassegga
rcall rx
cpi temp, $47 ;G
brne ramassegga
rcall rx
cpi temp, $41 ;A
brne ramassegga
; rcall rx ;passe la virgule
;ici on a detecter $GPGGA on doit rammaser la string
ldi zh, high(gga) ;adresse de RAM $240 dans Z
ldi Zl, low(gga)
prochainbytes:
rcall rx
mov r0,temp
st z+, R0 ;R0 dans ce que pointe Z ici $240 en montant
cpi temp, $24 ;regarde si rx recoit $. Si oui = veut dire qu'on a ramasser gga au complet
breq donegga
rjmp prochainbytes
donegga:
ret
; 46`19.81427 m. N
;**********************************************************************************************
;**********************************************************************************************
;**********************************************************************************************
affichenombreSerial: ;affiche un nombre DCB. Exemple si 0x17 est dans temp. 17 sera affiché sur port serie
push temp ;17 ;On additionne 30 sur lsb et msb donc 17 = 31 + 37
swap temp ;71
andi temp, $0F ;1
subi temp, -$30 ;31
rcall tx
pop temp ;17
andi temp, $0F
subi temp, -$30 ;31
rcall tx
ret
;***************************************************************************************
affichenombreSerialhigh: ;affiche un nombre DCB. Exemple si 0x17 est dans temp. 17 sera affiché sur port serie
push temp
swap temp ;71
andi temp, $0F ;1
subi temp, -$30 ;31
rcall tx
pop temp
ret
affichenombreSeriallow:
push temp
andi temp, $0F
subi temp, -$30 ;31
rcall tx
pop temp
ret
;***************************************************************************************
messageserial:
lpm ;lpm = load program memory. Le contenu de l'adresse pointé par Z se retrouve dans R0
mov temp, r0 ;comparons r0 avec 04 pour vois si le message est à la fin
cpi temp, $04
breq finmessageserial
mov temp, r0 ;Il faut séparer la valeur lu, exemple:(41) en 40 et 10 pour envoyer à l'afficheur
rcall tx
adiw ZH:ZL,1 ;incremente zh,zl et va relire l'addresse suivante
rjmp messageserial
finmessageserial:
ret
;************************************************************************************
affichegate1ksserial:
ldi r31,high(data37*2) ;Gate 1000s
ldi r30,low(data37*2)
rcall messageserial
ldi temp, $2c ;,
rcall tx
ret
;***************************************************************************************
affichegate10ksserial:
ldi r31,high(data34*2) ;Gate 10000s
ldi r30,low(data34*2)
rcall messageserial
ldi temp, $2c ;,
rcall tx
ret
;***************************************************************************************
affichesatellite2serial:
load r16, UCSR0A ;regarde si ya de quoi qui a été recu par le serial
sbrs r16, RXC0
ret ;rxc0 est a 0 on a rien recu
rcall checkgpgga ;on ramasse le nombre de satellite
ldi temp, $53 ; S
rcall tx
ldi temp, $3d ; =
rcall tx
lds temp, satelliteh
rcall tx
lds temp, satellitel
rcall tx
ldi temp, $2c ;,
rcall tx
ret
;**************************************************************************************
nextline:
ldi temp, $d
rcall tx
ldi temp, $a
rcall tx
ret
;**************************** affichememoireserial *************************************
;affiche le contenu tel quel. exemple si $3a est dans temp 3a sera afficher
affichememoireserial:
push temp
swap temp ;exemple 3A
andi temp, $0f ;on garde le 3
ldi r31,high(hexa*2) ;pointe l'addresse le la database dans R0
ldi r30,low(hexa*2) ; l'addresse de mémoire;
add ZL, temp ;augmente l'adresse pour pointer le bon chiffre (r31 et r30 constitue zh et zl)
brcc okpasdedepassementqserial ;(branch if carry est 0) si le carry est a 1 (il y a une retenue) = plus que FF on incrémente donc zh. Sinon il passe et laisse zl normal
inc zh
okpasdedepassementqserial:
lpm
mov temp,r0
rcall tx
pop temp
andi temp, $0f ;on garde le 3
ldi r31,high(hexa*2) ;pointe l'addresse le la database dans R0
ldi r30,low(hexa*2) ; l'addresse de mémoire;
add ZL, temp ;augmente l'adresse pour pointer le bon chiffre (r31 et r30 constitue zl et zh)
brcc okpasdedepassement7qserial ;(branch if carry est 0) si le carry est a 1 (il y a une retenue) = plus que FF on incrémente donc zh. Sinon il passe et laisse zl normal
inc zh
okpasdedepassement7qserial:
lpm
mov temp,r0
rcall tx ;3 est afficher
ret
espaceserial:
push temp
ldi temp, $20
call tx
pop temp
ret