;choisir Tab Size = 10 dans les options de l'editeur de MPLAB IDE
;pour obtenir un alignement correct du listing
;
;si vous visualisez avec Wordpad, vous aurez des soucis d'alignement...
;choisissez dans les options de Wordpad "pas de retour a la ligne"
;sinon les longues lignes de commentaires seront tronquees
;et passeront dans les colonnes etiquettes et code
;**********************************************************************
;
;
;
;LISTE DES PRINCIPALES PROCEDURES: (Double-clic sur 1 mot puis F3 dans MPLAB, c'est pratique...)
;TESTS
;MACROS
;mot16A macro ;charge AH et AL avec le mot code sur 16 bits transmis
;mot16B macro ;charge BH et BL avec le mot code sur 16 bits transmis
;Changements de banques
;R_EEPROM
;W_EEPROM
;CONSTANTES
;VARIABLES_EN_BANQUE0
;INITIALISATION DES PORTS
;PROGRAMMATION DU REGISTRE OPTION (BANK1)
;PROG DU REGISTRE INTCON (BANK0)
;PROG DU REGISTRE T1CON (BANK0)
;PROG DU REGISTRE T2CON (BANK0)
;PROG DU REGISTRE PR2 (BANK1)
;PROG DU REGISTRE PIE1 (BANK1)
;Initialisation_des_variables
;BOUCLE_PRINCIPALE
;inttimer0 -> le Timer0 est utilise au sein de l'INT portB0 (voir plus bas) pour mesurer la duree PPM voie GAZ
;inttimer1 -> le Timer1 est utilise dans l'INT portB4-7 (voir plus bas) pour mesurer la duree PPM voie ANTI-COUPLE
;inttimer2 -> generation du signal de sortie
;intB0
;intB5
;convhbin ;conversion sexadecimale -> binaire ;entree: AA, BB ;resultat: AH,AL = 60*AA+BB
;multi ;mutiplication 8 bits x 8 bits de AA par w (donnees sur 1 octet) ;resultat (sur 2 octets) dans AH,AL
;divi2 ;division d'une valeur codee sur 16 bits (AH,AL) par 2
;divi60 ;division d'une valeur codee sur 16 bits (AH,AL) par 60 ;resultat dans w ;reste de la division dans (BH,BL)
;add16A ;addition 16bits resultat dans A ;(AH,AL)+(BH,BL) -> (AH,AL)
;add16B ;addition 16bits resultat dans B ;(AH,AL)+(BH,BL) -> (BH,BL)
;cpl16x ;complement a deux de la variable codee sur 2 octets situes aux adresses w et w+1 permet les soustractions
;compa16p ;comparaison de deux valeurs codees sur 16 bits (AH,AL a BH,BL) ;resultat dans STATUS carry et zero
;movxA ;mov la variable codee sur 2 octets situes aux adresses w et w+1 dans -> AH,AL
;movAx ;mov AH,AL dans -> la variable codee sur 2 octets situes aux adresses w et w+1
;movxB ;mov la variable codee sur 2 octets situes aux adresses w et w+1 dans -> BH,BL
;movBx ;mov BH,BL dans -> la variable codee sur 2 octets situes aux adresses w et w+1
;procedures d'affichage LCD
;cvBDU ;CONVERSION BINAIRE(1) (1 octet incomplet 0..99 et pas 0..255) --> BCD ;nombre a convertir dans AA
;cvBCU ;CONVERSION BINAIRE(2) (1 octet complet 0..255) --> BCD ;resultat dans BB (centaines) et dans AA (unites)
;tp154us
;tp1ms
;tp2ms
;tp10ms
;tp100ms
;vari_vit
;TABLEAUX
;
;
; ;pour Qx=20,000 Mhz
;
;
;
;
;***********************************************************************************************
; VARIATEUR pour moteur DC (pour helico Piccolo) : variat2_05.asm
; pour PIC16F628
; par Silicium 628
;************************************************************************************************
;derniere mise a jour: 29/05/2005
;remarque: suite aux modifications (=ameliorations!) certains commentaires peuvent se reveler faux !!!
;j'en suis desole. Je relis regulierement les commentaires et essaye de les tenir a jour.
;toutefois il m'arrive de trouver des enormites ! que je corrige...
;------------------------------------------------------------------------------------------------
;*********************************************** PRINCIPE *****************************************
;int Exterieure par bit 0 du port B sert a detecter les fronts du signal PPM du recepteur de radio-commande
;on en deduit sa duree (1 a 2,2 ms)
;******************************** REMARQUES GENERALES *********************************************
;representation d'un nombre hexadecimal: commence par "0x" ex: 0x20
;representation d'un nombre decimal: commence par "." ex: .20
; ex: 0x20 = .32
; B'00010000' represente une valeur binaire
;Utiliser une version recente de MPLAB afin que le PIC16F628 soit pris en compte (ma version= 5.70.00 )
;voir sur le site de Microchip(R): http://www.microchip.com
;***************************************************************************************************
;----------------------------------------------------------------------
list p=16f628 ; list directive to define processor
#include <p16f628.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _MCLRE_ON & _LVP_OFF
; '__CONFIG' precise les parametres encodes dans le processeur au moment de
; la programmation du processeur. Les definitions sont dans le fichier include.
; Voici les valeurs et leurs definitions :
; _CP_ON Code protection ON : impossible de relire
; _CP_OFF Code protection OFF
; _PWRTE_ON Timer reset sur power on en service
; _PWRTE_OFF Timer reset hors-service
; _WDT_ON Watch-dog en service
; _WDT_OFF Watch-dog hors service
; _LP_OSC Oscillateur quartz basse vitesse (32<F<200Khz)
; _XT_OSC Oscillateur quartz moyenne vitesse (200Khz<F<4Mhz)
; _HS_OSC Oscillateur quartz grande vitesse (4Mhz<F<20Mhz)
; _RC_OSC Oscillateur a reseau RC
; Reset du PIC si tension <4V
; ------------------------------
; _BODEN_ON Reset tension en service Valide PWRTE_ON automatiquement
; _BODEN_OFF Reset tension hors service
; Programmation sur circuit
; -------------------------
; _LVP_ON RB4 permet la programmation serie du PIC
; _LVP_OFF RB4 en utilisation normale
;
; "departRam equ 0x20"
;----------------------------------------------------------------------
;*****************************************************************************
; MACROS *
;*****************************************************************************
mot16A macro mot16 ;charge AH et AL avec le mot code sur 16 bits transmis
movlw low mot16
movwf AL
movlw high mot16
movwf AH
endm
mot16B macro mot16 ;charge BH et BL avec le mot code sur 16 bits transmis
movlw low mot16
movwf BL
movlw high mot16
movwf BH
endm
; Changements de banques
BANK0 macro ; passer en banque0
bcf STATUS,RP0
bcf STATUS,RP1
endm
BANK1 macro ; passer en banque1
bsf STATUS,RP0
bcf STATUS,RP1
endm
BANK2 macro ; passer en banque2
bcf STATUS,RP0
bsf STATUS,RP1
endm
BANK3 macro ; passer en banque3
bsf STATUS,RP0
bsf STATUS,RP1
endm
; lire eeprom (adresse et resultat en w)
R_EEPROM macro
clrwdt
bsf STATUS,RP0 ; Bank 1
movwf EEADR ; Adresse to read
bsf EECON1,RD ; ordre de lecture
movf EEDATA,w ; W = EEDATA
bcf STATUS,RP0 ; Bank 0
endm
;ecriture en EEPROM (adresse dans DDD (commun 4 banques), data dans w)
W_EEPROM macro
clrwdt
LOCAL loop
bsf STATUS,RP0 ; Bank 1
movwf EEDATA ; Data to write
; movlw adress1 ; adresse passee en parametre a la macro (moins souple que par registre)
movf DDD,w ; adresse passee par registre DDD, commun aux 4 banques
movwf EEADR
bsf EECON1, WREN ; Enable Write
bcf INTCON, GIE ; Disable INTs
movlw 0x55
movwf EECON2 ; Write 55
movlw 0xAA
movwf EECON2 ; Write AA
bsf EECON1, WR ; lancer cycle d'ecriture
bsf INTCON, GIE ; reautoriser INTs
loop clrwdt
btfsc EECON1 , WR ; tester si ecriture terminee
goto loop ; non, attendre
bcf EECON1 , WREN ; verrouiller prochaine ecriture
bcf STATUS , RP0 ; passer en banque0
endm
;*****************************************************************************
;CONSTANTES
w equ 0
f equ 1
RESET_V equ 0x0000 ; adresse du vecteur de reset
ISR_V equ 0x0004 ; adresse du vecteur d'interruption general
;----------------------------------------------------------------------
;VARIABLES_EN_BANQUE0
;le PIC16F628 possede 224 octets de RAM repartis en 3 emplacements (96+80+48 octets)
;ici premiere banque de 96 octets, debut a l'adresse 0x20
;verifier sur le listing absolu que la derniere adresse soit < 7Fh
;L'utilisation de CBLOCK permet de permutter facilement les variables (par rapport a "equ" )
CBLOCK 0x20 ;debut de la zone RAM utilisateur de 96 octets en banque 0
AA : 1 ;registre de travail
BB : 1 ;registre de travail
CC : 1 ;registre de travail
DD : 1 ;registre de travail
AH : 1 ;registre de travail poids fort
AL : 1 ;registre de travail poids faible
BH : 1 ;registre de travail poids fort
BL : 1 ;registre de travail poids faible
count0 : 1 ;
count1 : 1 ;utilise dans la multiplication 8bits x 8bits
count2 : 1 ;utilise dans la procedure vari_vit
dtlcd : 1 ;data vers afficheur LCD
aff1 : 1
aff2 : 1
aff3 : 1
aff4 : 1
bitn : 1
t1 : 1 ;pour les tempos
t2 : 1 ;pour les tempos
t3 : 1 ;pour les tempos
rapcyc1 : 1 ;pour faire varier le rapport cyclique du signal de sortie voie ANTI-COUPLE
rapcyc2 : 1 ;pour faire varier le rapport cyclique du signal de sortie voie GAZ
butcyc2 : 1
T_PPM_G : 1 ;temps (duree) du signal PPM (voie des GAZ en sortie du recepteur de radiocommande)
T_PPM_A : 1 ;temps (duree) du signal PPM (voie des ANTI-COUPLE en sortie du recepteur de radiocommande)
memo1 : 1 ;variable locale
memo2 : 1 ;variable locale
adrEE : 1 ;pour memoriser en EEPROM
;voir fonctionnement des timer pour l'explication du 255-...
mesflags : 1 ;8 flags perso divers
;b0: stop moteur principal (GAZ) par ordre emis par la radio-commande (trim des gaz en bas...)
;b1: phase du signal de sortie voie ANTI-COUPLE (Timer1)
;b2: phase du signal de sortie voie GAZ (Timer2)
;b3:
;b4: memorise si front montant/descendant en cours sur l'entree RB0
;b5:
;b6:
;b7:
ENDC ; Fin de la zone
;----------------------------------------------------------------------
; VARIABLES ZONE COMMUNE
; Zone de 16 bytes
CBLOCK 0x70 ;Debut de la zone (0x70 a 0x7F)
WW : 1 ;pour sauvegarder w pendant INT
STUS_TMP : 1 ;pour sauvegarder STATUS pendant INT
FSR_temp : 1 ;sauvegarde FSR (si indirect en interrupt)
PLATH_tmp : 1
DDD : 1 ;registre d'adresses commun
ENDC ; Fin de la zone
;----------------------------------------------------------------------
;VARIABLES EN BANQUE1 accessible avec IRP=0 si adressage indirect
CBLOCK 0xA0 ;=.160 debut de la zone RAM utilisateur de 80 octets en banque 1
ENDC ;Fin de la zone
;----------------------------------------------------------------------
ORG RESET_V ; Vecteur de RESET
RESET goto start
;***********************************************************************
; TRAITEMENT DES INTERRUPTIONS (Aiguillage vers routines)
;***********************************************************************
;ici INT par le Timer 0
;RAPPEL Un seul vecteur d'interruption, d'adresse 004 est diponible
;Quelle que soit la cause de l'interruption, le PC est donc charge par 004
;a vous ensuite de tester les differents indicateurs pour savoir quel est la source de l'INT.
;voir le registre INTCON
ORG ISR_V ; Vecteur d'Interruption
movwf WW
swapf STATUS,w
movwf STUS_TMP
movf FSR , w
movwf FSR_temp
movf PCLATH , w ;charger PCLATH
movwf PLATH_tmp ;le sauver
clrf PCLATH ;on est en page 0
BANK0 ;passer en banque0
intRB0 btfss INTCON,1 ;test FLAG INT exterieure bit 0 du port B
goto intRB5 ;non suite
call intB0 ;oui, traiter interrupt PORTB,0
bcf INTCON,1 ;effacer flag interupt portB: reautorise interruption PORTB,0
goto restorREG
intRB5 btfss INTCON,0 ;test FLAG INT exterieure bits 4 a 7 du port B
goto intTMR1 ;non suite
call intB5 ;oui, traiter interrupt PORTB,0
bcf INTCON,0 ;effacer flag interupt portB: reautorise interruption PORTB,0
goto restorREG
intTMR1 btfss PIR1,TMR1IF ;test FLAG timer1
goto intTMR0 ;non test suivant
call inttimer1 ;oui, traiter interrupt timer1
bcf PIR1,TMR1IF ;reautorise l'INT par Timer1
goto restorREG
intTMR0 btfss INTCON,2 ;test FLAG timer0
goto intTMR2 ;non suite
call inttimer0 ;oui, traiter interrupt timer0
bcf INTCON,2 ;effacer flag interupt timer: reautorise l'INT Timer0
goto restorREG
intTMR2 btfss PIR1,TMR2IF ;test FLAG timer2
goto restorREG ;non suite...
call inttimer2 ;oui, traiter interrupt timer2
bcf PIR1,TMR2IF ;reautorise l'INT par Timer2
goto restorREG
restorREG movf PLATH_tmp, w ;recharger ancien PCLATH
movwf PCLATH
movf FSR_temp,w
movwf FSR
swapf STUS_TMP,w ;swap STATUS_TMP, resultat dans w
movwf STATUS ;restaurer status
swapf WW,f ;Inversion L et H de l'ancien W sans modifier Z
swapf WW,w ;Re-inversion de L et H dans W
retfie ;remet GIE a 1 puis return
;***********************************************************************
; START START START START START START START START START START START
;***********************************************************************
org ISR_V+.60
start clrwdt
bcf STATUS,IRP ;pour l'adressage indirect
;IRP: Register Bank Select bit (used for indirect addressing)
;=0 -> Bank 0, 1 (00h - FFh)
;=1 -> Bank 2, 3 (100h - 1FFh)
BANK0 ;pour l'adressage direct
;***********************************************************************
;ZONE de TESTS de procedures
; mot16B .61000
; movlw .335
; call divi16_8
; nop
; movlw .200
; movwf rapcyc2 ;G
;la movlw .255
; movwf BB ;mancheAC
; call calc_AC
; movlw .10
; addwf rapcyc2,f
; goto la
;***********************************************************************
call tp100ms
clrwdt
;***********************************************************************
; INITIALISATION DES PORTS
;***********************************************************************
;RA0=entree: signal du capteur magnetique (detection de la phase du rotor)
;RA1=entree: signal en provenance du circuit de detection de vitesse faible ou nulle suite a decrochage du moteur
;RA2=entree: detection tension alim faible ( "BEC" )
;RA3=sortie: LED alim faible
;RA3=
;RB0=entree: signal PPM du recepteur de radio-commande, voie 'gaz'
;RB1=
;RB2=sortie: commande MOSFET canal N
;RB3=
;RB4=
;RB5=s
;RB6=s
;RB7=
BANK0
movlw 0x07
movwf CMCON ; PORT A en E/S numeriques (BANK0)
BANK1
movlw B'00000000' ;0=sortie 1=entree attention RA4 =drain ouvert
movwf TRISA ;config du port A (TRISA en page 1)
movlw B'00101001'
movwf TRISB ;config du port B
bcf OPTION_REG,7 ;Enable PORTB pull-ups
;----------------------------------------------------------------------
;PROGRAMMATION DU REGISTRE OPTION (BANK1) - voir datasheet p:20 du datasheet PIC16F62X.pdf
;bit7: RBPU =0 -> R tirage a Vdd du port B
;bit6: INTEDG=1 -> INT sur front montant ou descendant de RB0
; 1 = Interrupt on rising edge of RB0/INT pin
; 0 = Interrupt on falling edge of RB0/INT pin
;bit5: T0CS = 0 -> TMR0 Clock Source Select bit
; 1 = Transition on RA4/T0CKI pin (Fonctionnement en mode compteur)
; 0 = Internal instruction cycle clock (CLKOUT) (Fonctionnement en mode timer)
;bit4: RTE = 0 -> inc sur front montant
;bti3: PSA = 0 -> prediv affecte au timer0
;bits2,1,0:PS2,1,0
;Bit Value TMR0 Rate WDT Rate
;000 1 : 2 1 : 1
;001 1 : 4 1 : 2
;010 1 : 8 1 : 4
;011 1 : 16 1 : 8
;100 1 : 32 1 : 16
;101 1 : 64 1 : 32 ***** ICI 100b -> Timer0 = 1/64 *****
;110 1 : 128 1 : 64
;111 1 : 256 1 : 128
BANK1
; nº bits: '76543210'
movlw B'01000101'
movwf OPTION_REG
;----------------------------------------------------------------------
;PROG DU REGISTRE INTCON (BANK0) - voir datasheet p:21
;bit7 GIE =0 -> INT GLOBALE interdite. (voir + bas)
;bit6 PEIE=1 -> INT PERIPHERIQUES autorisees. (timer1 en fait partie)
;bit5 T0IE=0 -> INT par debordement Timer0 autorisee.
;bit4 INTE=0 -> INT de RB0/INT autorisees (INTERRUPTIONS EXTERNES)
;bit3 RBIE=1 -> INT du port RB4 a RB7 autorisees.
;bit2 T0IF=x (flag mis a 1 par debordement du Timer0)
;bit1 INTF=x (flag mis a 1 par une INT provoquee par la libne RB0/INT du port B)
;bit0 RBIF=x (flag mis a 1 si changement d'etat des entrees RB4 a RB7 du port B. attention RB1 a RB3 -> pas d'INT)
BANK0
; nº bits: '76543210'
movlw B'01111000'
movwf INTCON
;----------------------------------------------------------------------
;PROG DU REGISTRE T1CON (BANK0)
;bit7 : Inutilise : lu comme « 0 »
;bit6 : Inutilise : lu comme « 0 »
;bit5 : T1CKPS1 : Timer 1 oscillator ClocK Prescale Select bit 1
;bit4 ; T1CKPS0 : Timer 1 oscillator ClocK Prescale Select bit 0
;bit3 : T1OSCEN : Timer 1 OSCillator ENable control bit (oscillateur interne)
;bit2 : T1SYNC : Timer 1 external clock input SYNChronisation control bit
;bit1 : TMR1CS : TiMeR 1 Clock Source select bit (0=internal clock)
;bit0 : TMR1ON : TiMeR 1 ON bit
BANK0
; nº bits: '76543210'
movlw B'00110001' ;prescale Timer1=1/8
movwf T1CON
;----------------------------------------------------------------------
;PROG DU REGISTRE T2CON (BANK0)
;bit 7: Unimplemented: Read as '0'
;bit 6-3: TOUTPS3:TOUTPS0: Timer2 Output Postscale Select bits
;0000 = 1:1 Postscale
;0001 = 1:2 Postscale
;0010 = 1:3 Postscale
;0011 = 1:4 Postscale
;0100 = 1:5 Postscale etc... (valeur binaire +1)
;1111 = 1:16 Postscale
;bit 2: TMR2ON: Timer2 On bit =1 : Timer2 is on
;bit 1-0: T2CKPS1:T2CKPS0: Timer2 Clock Prescale Select bits
;00 = Prescaler = 1
;01 = Prescaler = 4
;1x = Prescaler = 16 (valeur choisie ici)
BANK0
; nº bits: '76543210'
movlw B'00000110'
movwf T2CON
;----------------------------------------------------------------------
;PROG DU REGISTRE PR2 (BANK1)
;utilise par timer2
BANK1
movlw .64
movwf PR2
;----------------------------------------------------------------------
;PROG DU REGISTRE PIE1 (BANK1)
;bit7 : PSPIE b7 : Toujours 0 sur PIC 16F876
;bit6 : ADIE : masque int convertisseur A/D
;bit5 : RCIE : masque int reception USART
;bit4 : TXIE : masque int transmission USART
;bit3 : SSPIE : masque int port serie synchrone
;bit2 : CCP1IE: masque int CCP1
;bit1 : TMR2IE: masque int TMR2 = PR2
;bit0 : TMR1IE: masque int debordement tmr1
BANK1
; nº bits: '76543210'
movlw B'00000011' ;enable INT TIMER1 - enable INT TIMER2 - disable int reception USART (port serie)
movwf PIE1
;----------------------------------------------------------------------
;Initialisation_des_variables
initvar clrwdt
BANK0
movlw B'00000001' ;STOP moteur !
movwf mesflags
clrf count2
clrf DDD
movlw .200
movwf TMR0
clrf TMR1L
clrf TMR1H
movlw .128
movwf TMR2
movlw .5
movwf T_PPM_G
movlw .128
movwf T_PPM_A
movlw .1
movwf rapcyc1
movwf rapcyc2
bsf INTCON, GIE ;->INT GLOBALE autorisee
;-----------------------------------------------------------------------
; clrwdt
;RAZ LCD
; call dspclr
; call home
; call fset
; call setmod0
; call dsp10
; movlw "V"
; call ecrire
; movlw "a"
; call ecrire
; movlw "r"
; call ecrire
; movlw "i"
; call ecrire
; movlw "a"
; call ecrire
; movlw "t"
; call ecrire
; call tp100ms
;------------------------------------------------------------------------------------------------------------------
;BOUCLE_PRINCIPALE
boucle1 BANK0
call tp10ms ;DETERMINE LA VITESSE DE REPONSE
; btfss PORTB,3
; call ecrireEE ;pour test uniquement
;CES AFFICHAGES SONT DESTINES A UN AFFICHEUR LCD INTERFACE SUR LE PORT A
;pour la phase de mise au point uniquement. (Ralentit la reponse globale)
; movlw 00h ;affiche en ligne1 du LCD
; call ddras
; movf rapcyc2,w
; call affiw
; movlw 40h ;affiche en ligne2 du LCD
; call ddras
; comf rapcyc1,w
; call affiw
;------------------------------------------------------------------------------------------------------------------
;ajustement du rapport cyclique en fonction du signal ' VOIE GAZ'
;T_PPM est calcule dans la procedure duree du signal PPM VOIE GAZ
;(T_PPM = 84..173 avec un Qx=20MHz)
;arret moteur en dessous d'une valeur palier
movlw .88 ;valeur de T_PPM au dessous de laquelle on va stopper le moteur
subwf T_PPM_G,w ;w:= T_PPM - 88 (result -> w : ne touche pas a T_PPM)
btfsc STATUS,0 ;c=0 ? (c=0 si f < 5 )
goto test2
bsf mesflags,0 ;oui: ARRET D'URGENCE (si manche + trim gaz au mini)
goto tppm1
test2 movlw .5 ;valeur de rapcyc2 au dessous de laquelle on va stopper le moteur
subwf rapcyc2,w ;w:= rapcyc2 - 5 (result -> w : ne touche pas a rapcyc2)
btfss STATUS,0 ;c=0 ? (c=0 si f < 5 )
goto stop ;oui
goto go ;non
stop bsf mesflags,0 ;oui: STOP
; clrf butcyc2
; clrf rapcyc2
goto tppm1
go btfsc STATUS,0 ;meme question
bcf mesflags,0 ;non: pas STOP
;calcul du rapport cyclique
tppm1 movf T_PPM_G,w
movwf memo1
movlw .84 ; T_PPM_G mini CETTE VALEUR EST A AJUSTER EN FONCTION DE VOTRE RADIO
subwf memo1,f ; T_PPM_G:= T_PPM_G - 84 (pre-ofset)
btfss STATUS,0 ;debordement ?
clrf memo1 ;oui
rlf memo1,w ; w:= 2 x T_PPM_G
addwf memo1,w ; w:= 3 x T_PPM_G
btfsc STATUS,0 ;debordement ? (result > 255 ?)
movlw .253 ;oui, butee haute
movwf butcyc2
;calibrage final
movlw .253 ;valeur max de rapcycl admissible (attention: si > 253 -> int Timer2 = HS)
;avec prediv =1/16 (voir T2CON)
subwf butcyc2,w ;w:= rapcycl - 240 (result -> w : ne touche pas a rapcycl) d=f-w
btfss STATUS,0 ;c=0 ? rapcycl < 240 ? (c=0 si w > f )
goto fincal ;oui
movlw .253 ;non alors on bloque a butee max
movwf butcyc2
fincal nop
;progressivite de la reponse (pour eviter de casser les dents de la roue dentee en plastique sur l'arbre rotor)
;on fait tendre progressivement rapcyc2 vers butcycl2
;-------------------------------
rapvari movf rapcyc2,w
subwf butcyc2,w
btfsc STATUS,2 ;z
goto finrapv
btfss STATUS,0 ;c
goto moins
goto plus
moins decf rapcyc2,f
; movlw .2
; call tx10ms ;decroissance lente
goto finrapv
plus incf rapcyc2,f
finrapv nop
;------------------------------------------------------------------------------------------------------------------
;ajustement du rapport cyclique en fonction du signal ' voie ANTI-COUPLE'
;T_PPM est calcule dans la procedure duree du signal PPM voie ANTI-COUPLE
;=========================================
;RAPPEL:
;les valeurs du rapport cycliques sont codees sur un octet
;le rapport cyclique varie entre 0% et 100% c.a.d. en analogique [0..1] ce qu'on code ici sur un octet [0..255]
;il y a donc 256 pas possibles
;VOICI LE MIXAGE UTILISE:
;AC=(G*G/256 * Manche_AC /170 + G)/2 qui s'annule pour GAZ=0 mais pas pour AC=0
;ou son equivalent qui evite 1 debordement:
;AC=G*G/256/2*Manche_AC/170 + G/2
;cette courbe du second degre (gaz " au carre") a ete determine empiriquement
;Les calculs se font sur deux octets mais les resultats sont reencodes sur un octet
;=========================================
;calcul du signal voie ANTI-COUPLE
tppm2 movf T_PPM_A,w ;manche anti-couple
movwf memo1
movlw .84 ; T_PPM_A mini CETTE VALEUR EST A AJUSTER EN FONCTION DE VOTRE RADIO
subwf memo1,f ; T_PPM_A:= T_PPM_A - 84 (pre-ofset)
btfss STATUS,0 ;debordement ?
clrf memo1 ;oui
rlf memo1,w ; w:= 2 x T_PPM_A
addwf memo1,w ; w:= 3 x T_PPM_A
btfsc STATUS,0 ;debordement ? (result > 255 ?)
movlw .250 ;oui, butee haute
movwf BB ;non, on garde le resultat obtenu BB=AntiCouple
;calcul du rapport cyclique (mixage de la valeur obtenue avec celle de la voie "GAZ")
calc_AC movf rapcyc2,w ;w=GAZ
movwf AA
call multi ;w*AA -> AH,L = GAZ*GAZ =GAZ^2 ; AL=GAZ^2/256
movf BB,w ;w=manche AntiCouple
movwf AA ;AA=manche AntiCouple
bcf STATUS,0 ;RAZ c
rrf AH,w ;w=G*G/256/2
call multi ;w*AA -> AH,L = G*G/256/2 * Manche_AC
movlw AH ;w=adresse du registre AA
call movxB ;BH,L = AH,L donc BH,L := G*G/256/2 * Manche_AC
movlw .170 ;dividende
call divi16_8 ; w:=BH,L / 170 = G*G/256/2 * Manche_AC / 170
movwf AA ;AA:=BH,L / 170 = G*G/256/2 * Manche_AC / 170
bcf STATUS,0 ;RAZ c
rrf rapcyc2,w ;w:=G/2
addwf AA,f ;AA:=G*G/256/2 * Manche_AC / 170 +G/2
btfss STATUS,0 ;c depassement ?
goto clc2 ;non
movlw 0xFF ;oui, on force a 255
movwf AA
clc2 comf AA,w ;pour agir dans le bon sens (les 2 moteurs doivent accelerer en meme temps)
movwf rapcyc1 ;rapcyc1=resultat
; comf rapcyc1,f ;POUR TEST SEULEMENT
; return ;POUR TEST SEULEMENT
;calibrage final
movlw .250 ;valeur max de rapcycl admissible (attention: si > 250 -> int Timer2 = HS)
;avec prediv =1/8 (voir T1CON)
subwf rapcyc1,w ;w:= rapcycl - 240 (result -> w : ne touche pas a rapcycl) d=f-w
btfss STATUS,0 ;c=0 ? rapcycl < 240 ? (c=0 si w > f )
goto finbcl1 ;oui
movlw .250 ;non alors on bloque a butee max
movwf rapcyc1
;------------------------------------------------------------------------------------------------------------------
finbcl1 goto boucle1
;-----------------------------------------------------------------------
;DEBUT DES PROCEDURES
;-----------------------------------------------------------------------
;***********************************************************************
; SOUS-ROUTINES d'INTERRUPTIONS
;***********************************************************************
;int timer0
;en principe ne deborde jamais ici.
;est utilise au sein de l'INT portB0 (voir plus bas) pour mesurer la duree PPM voie GAZ
inttimer0
fintimer0 return
;----------------------------------------------------------------------
;int timer1
;generation du signal de sortie voie ANTI-COUPLE
;ce timer fonctionne ici suivant 2 alternances consecutives de durees inegales, mais dont la somme est constante
;on obtient dont une frequence constante avec un rapport cyclique variable
;valeur max de rapcycl admissible =253 (avec prediv =1/8 (voir T1CON))
inttimer1 movlw B'00000010'
xorwf mesflags,f ;inverse le flag de phase
btfsc mesflags,1 ;test du flag de phase
goto int1_a
movf rapcyc1,w ;ici w=rapcycl
sublw .255 ;ici w=255-rapcycl
movwf TMR1L
movlw 0xFF ;pour utiliser le timer1 sur 8 bits seulement
movwf TMR1H
goto int1_b
int1_a movf rapcyc1,w
movwf TMR1L
movlw 0xFF
movwf TMR1H
btfsc mesflags,0 ;STOP ?
goto int1_b ;oui, on va bloquer le MOSFET
bsf PORTB,1 ;SORTIE PHYSIQUE sur le port B pour commander le MOSFET voie ANTI-COUPLE
return
int1_b bcf PORTB,1 ;SORTIE PHYSIQUE sur le port B pour commander le MOSFET voie ANTI-COUPLE
fin_int1 return
;----------------------------------------------------------------------
;int timer2
;generation du signal de sortie VOIE GAZ
;ce timer fonctionne ici suivant 2 alternances consecutives de durees inegales, mais dont la somme est constante
;on obtient dont une frequence constante avec un rapport cyclique variable
;valeur max de rapcycl admissible =253 (avec prediv =1/16 (voir T2CON))
;attention: si prediv<1/16 ou si rapcycl > 253 alors-> int Timer2 = HS (pas le temps de reinitialier PR2)
inttimer2 movlw B'00000100'
xorwf mesflags,f ;inverse le flag de phase
btfsc mesflags,2 ;test du flag de phase
goto int2_a
movf rapcyc2,w ;ici w=rapcycl
sublw .255 ;ici w=255-rapcycl
BANK1
movwf PR2 ;PR2 = registre 8bits de periode du Timer2 situe en banque1
BANK0
goto int2_b
int2_a movf rapcyc2,w
BANK1
movwf PR2 ;PR2 = registre 8bits de periode du Timer2
BANK0
btfsc mesflags,0 ;STOP ?
goto int2_b ;oui, on va bloquer le MOSFET
bsf PORTB,2 ;SORTIE PHYSIQUE sur le port B pour commander le MOSFET VOIE GAZ
return
int2_b bcf PORTB,2 ;SORTIE PHYSIQUE sur le port B pour commander le MOSFET VOIE GAZ
fin_int2 return
;----------------------------------------------------------------------
;int Exterieure par bit 0 du port B
;sert a detecter les fronts du signal PPM du recepteur de radio-commande, voie GAZ
;et a mesurer la duree du signal a 1
intB0 btfss mesflags,4 ;quel front vient-on de detecter ?
goto frontD0 ;le front descendant
frontM0 clrf TMR0 ;le front montant. RAZ Timer0
BANK1
bcf OPTION_REG,6 ;Interrupt on falling edge of RB0/INT pin (detectera le front descendant)
BANK0
bcf mesflags,4 ;pour eviter une lecture en bank1 au debut de cette procedure, on testera ce flag
return
frontD0 movf TMR0,w ;le timer0 a compte (l'horloge du PIC) depuis le front montant precedent
movwf T_PPM_G ;MEMORISATION DE LA MESURE DU SIGNAL PPM voie GAZ pour le reste du programme
BANK1
bsf OPTION_REG,6 ;(detectera le front montant)
BANK0
bsf mesflags,4
clrf TMR0
return
;----------------------------------------------------------------------
;int Exterieure par bit5 du port B
;sert a detecter les fronts du signal PPM du recepteur de radio-commande, voie ANTI-COUPLE
;et a mesurer la duree du signal a 1
;REMARQUE: contrairement a l'intRB0, les INT RB4-7 sont declenchees par les fronts montants ET descendants
;sans que l'on puisse choisir lequel
;Mais en fait ceci aboutit a simplifier la procedure
;lorsque l'int est declenchee, il suffit de tester l'etat du port pour savoir si elle a ete declenchee par un
;front montant ou descendant.
;REMARQUE2: Cette procedure utilise volontairement LE MEME timer (le Timer0) que la precedente (intB0)
;ceci est possible car les signaux PPM des differentes voies ne sont jamais simultanes, mais sont successifs.
;Donc les comptages des temps par le Timer0 ne se chevauchent pas (voir plus bas la precaution a prendre)
;ET AINSI ON GAGNE UN TIMER !
;(on peut eenddre ce principe pour un plus grand nombre de voies ! avec 1 seul timer, on peut mesurer
;autant de periodes de temps qu' on veut, pourvu qu' elles soient disjointes)
;************* ATTENTION ****************
;Pour eviter un RAZ intempestif du Timer0 d'une voie par l'autre,
;LES VOIES GAZ ET ANTI-COUPLE NE DOIVENTS PAS ETRE 2 VOIES CONSECUTIVES SUR LA RADIO !!!
;choisir par exemple les voies 2et4 MAIS PAS les voies 3et4 ou 2et3 pour l'anti-couple et les gaz.
;****************************************
intB5 btfss PORTB,5 ;quel front vient-on de detecter ?
goto frontD5 ;le front descendant
frontM5 clrf TMR0 ;le front montant. RAZ Timer0
return
;le timer1 a compte (l'horloge du PIC) depuis le front montant precedent
frontD5 movf TMR0,w ;le timer0 a compte (l'horloge du PIC) depuis le front montant precedent
movwf T_PPM_A ;MEMORISATION DE LA MESURE DU SIGNAL PPM voie A.Couple pour le reste du programme
clrf TMR0
return
;------------------------------------------------------------------------
;Pour test seulement: memorise en EEPROM les valeurs simultanees de la vitesse Rotor et AntiCouple
;afin d'etudier la courbe obtenue (sous Excel par exemple)
ecrireEE movf adrEE,w
movwf DDD
movf rapcyc2,w
W_EEPROM
incf adrEE,f
movf adrEE,w
movwf DDD
comf rapcyc1,w
W_EEPROM
incf adrEE,f
call tp100ms ;anti-rebond
call tp100ms
call tp100ms
call tp100ms
call tp100ms
return
;************************************************************************
;debut des procedures d'affichage LCD (utilisent le portA)
;************************************************************************
;FUNCTION SET
fset bcf PORTA,2 ;E=0
bcf PORTA,3 ;R/S=0
movlw .56 ;(32+16+8)
movwf dtlcd
call dt_out ;transmission serie vers 4015 -> DATA // LCD
call impuls
return
;----------------------------------------------------------------------
;DISPLAY CLEAR
dspclr bcf PORTA,2 ;E=0
bcf PORTA,3 ;R/S=0
movlw .1
movwf dtlcd
call dt_out
call impuls
return
;----------------------------------------------------------------------
;RETURN HOME
home clrf PORTA
movlw .2
movwf dtlcd
call dt_out
call impuls
return
;----------------------------------------------------------------------
;ENTRY MODE SET 0
;le curseur se deplace
setmod0 bcf PORTA,2 ;E=0
bcf PORTA,3 ;R/S=0
movlw .6 ;( 4+2 sens inverse si 4+0 )
movwf dtlcd
call dt_out
call impuls
return
;----------------------------------------------------------------------
;ENTRY MODE SET 1
;curseur gele
setmod1 bcf PORTA,2 ;E=0
bcf PORTA,3 ;R/S=0
movlw .7 ;( 4+2+1 )
movwf dtlcd
call dt_out
call impuls
return
;----------------------------------------------------------------------
;DISPLAY ON OFF
dsp10 bcf PORTA,2 ;E=0
bcf PORTA,3 ;R/S=0
movlw .12 ;( 8+4 )
movwf dtlcd
call dt_out
call impuls
return
;----------------------------------------------------------------------
;DDRAM ADRESS SET (A)
;w doit contenir l'adresse (position d'affichage. voir doc)
ddras bcf PORTA,2 ;E=0
bcf PORTA,3 ;R/S=0
addlw .128
movwf dtlcd
call dt_out
call impuls
return
;----------------------------------------------------------------------
;CURSOR OR DISPLAY SHIFT
;DEFILEMENT DU TEXTE
shiftT bcf PORTA,2 ;E=0
bcf PORTA,3 ;R/S=0
movlw .24 ;( 16+8 )
movwf dtlcd
call dt_out
call impuls
return
;----------------------------------------------------------------------
;CURSOR OR DISPLAY SHIFT
;DEFILEMENT DE LA POSITION D'AFFICHAGE (CURSEUR)
shiftC bcf PORTA,2 ;E=0
bcf PORTA,3 ;R/S=0
movlw .16 ;( 16 )
movwf dtlcd
call dt_out
call impuls
return
;----------------------------------------------------------------------
;ECRIRE
;w doit contenir lavaleur ASCII du caractere a afficher
ecrire bcf PORTA,2 ;E=0
bsf PORTA,3 ;R/S=1
movwf dtlcd
call dt_out
bsf PORTA,2 ;impuls E a 1 avec RS=1
call tp10ms
bcf PORTA,2 ;fin impulsion
call tp10ms
return
;----------------------------------------------------------------------
;impulsion E a 1 avec RS=0
impuls bcf PORTA,3 ;R/S=0
bsf PORTA,2 ;impulsion E a 1
call tp10ms
bcf PORTA,2 ;fin impulsion
call tp10ms
return
;----------------------------------------------------------------------
;SORTIE DATA (8 bits) en serie sur PA0 vers CD4015. PA1=Clock 4015.
dt_out movlw .8
movwf bitn
dtbcl rlf dtlcd,f
bcf PORTA,0 ;bit = 0 (a priori)
btfsc STATUS,0 ;test carry
bsf PORTA,0 ;non, bit = 0
out bsf PORTA,1 ;clock 4015
call tp154us
bcf PORTA,1 ;fin clock
call tp154us
decfsz bitn,f
goto dtbcl
return
;------------------------------------------------------------------------
affi4 movf aff4,w
addlw .48 ;code ASCII de zero
call ecrire
affi3 movf aff3,w
addlw .48 ;code ASCII de zero
call ecrire
affi2 movf aff2,w
addlw .48 ;code ASCII de zero
call ecrire
movf aff1,w
addlw .48 ;code ASCII de zero
call ecrire
return
;------------------------------------------------------------------------
;nb decimaux dans AA(unites) et BB(centaines) au prealable
affdeci movf BB,w
movwf CC ;memo BB danc CC because cvBDU utilise BB
call cvBDU
movf AA,w ;ld A,V
movwf aff1 ;ld Aff1,A
movf BB,w ;ld A,W
movwf aff2 ;ld Aff2,A
movf CC,w ;ld A,BB ;0..99
movwf AA
call cvBDU
movf AA,w
movwf aff3
movf BB,w
movwf aff4
return
;-----------------------------------------------------------------------
;affiche un octet complet sur aff1..4 (4 TIL 702)
;W doit contenir l'octet a afficher
affiw movwf AA
call cvBDU ;BB=18 et AA=4
movf AA,w
movwf aff1 ;aff1=4
movf BB,w ;w=18
movwf AA ;AA=18
call cvBDU ;BB=1 et AA=8
movf AA,w
movwf aff2 ;aff2=8
movf BB,w
movwf aff3 ;aff3=1
clrf aff4
call affi4
return
;-----------------------------------------------------------------------
;affichage nombre 0..9999
;AH et AL contiennent un nb 0..9999
affnb movf AL,w ;ld A,AL
movwf AA
call cvBCU ;convertit period0 en BCD
;resultat dans AA(unites) et BB(centaines)
;on va ajouter valbin1 x 256
movf AH,w ;ld A,AH
movwf DD ;ld memo3,A pour'pas toucher period1
incf DD,f ;hors boucle
afn1 decfsz DD,f
goto saut1 ;jrnz ici1
goto suitef
;ld A,AA
saut1 movlw .56
addwf AA,f ;addi A,56 (+56) retenue decimale possible
movf AA,w
sublw .99 ;carry =0 si AA>99
btfsc STATUS,0 ;bit de carry
goto st1 ;donc saut->conv3 si carry=1, c.a.d si A>99
;jrc st1
movlw .100
subwf AA,f
incf BB,f ;ajout retenue decimale
st1 movlw .2
addwf BB,f ;(+200) soit en tout +256
goto afn1
suitef call affdeci
return
;------------------------------------------------------------------------
;CONVERSION BINAIRE(1) (1 octet incomplet 0..99 et pas 0..255) --> BCD
;nombre a convertir dans AA
;resultat dans BB (dizaines) et dans AA (unites)
;ex: AA=237 -> BB=23 et AA=7
;ex2 AA=84 -> BB=8 et AA=4
cvBDU clrf BB
conv2 movlw .10
subwf AA,w ;w=AA-10 positionne le bit de carry si A<10
btfss STATUS,0 ;bit de carry
goto conv3 ;donc saut ->conv3 si carry=1, c.a.d si A<10
movlw .10
subwf AA,f ;en boucle : revient a diviser A par 10
incf BB,f
goto conv2 ;9 passages au max si nb <= 99
conv3 return
;--------------------------------------------------------------------
;CONVERSION BINAIRE(2) (1 octet complet 0..255) --> BCD
;nombre a convertir dans AA
;resultat dans BB (centaines) et dans AA (unites)
;ex: AA=237 -> BB=23 et AA=7
cvBCU clrf BB
conv4 movlw .100
subwf AA,w ;w=AA-100 positionne le bit de carry si A<100
btfss STATUS,0 ;bit de carry
goto conv5 ;donc saut ->conv3 si carry=1, c.a.d si A<100
movlw .100
subwf AA,f ;en boucle : revient a diviser A par 100
incf BB,f
goto conv4 ;9 passages au max si nb <= 999
conv5 return
;--------------------------------------------------------------------
;***********************************************************************
; ROUTINES MATH
;***********************************************************************
;------------------------------------------------------------------------
;conversion sexadecimale -> binaire
;entree: AA, BB
;resultat: AH,AL = 60*AA+BB
convhbin movlw .60
call multi ;AA contient la donnee a multiplier
movf BB,w
addwf AL,f
btfsc STATUS,0 ;carry
incf AH,f
return
;------------------------------------------------------------------------
;mutiplication 8 bits x 8 bits de AA par w (donnees sur 1 octet)
;d'apres note AN526 Microchip
;resultat (sur 2 octets) dans AH,AL (poids fort et poids faible)
multi clrf AH
movwf AL
movlw .8
movwf count1
movf AL,w
clrf AL
bcf STATUS,0 ;RAZ carry
loop rrf AA,f
btfsc STATUS,0
addwf AH,f
rrf AH,f
rrf AL,f
decfsz count1,f
goto loop
return
;------------------------------------------------------------------------
;division d'une valeur codee sur 16 bits (AH,AL) par 2
divi2 bcf STATUS,0 ;RAZ carry c=0
rrf AH,f ;le bit de poids faible tombe dans -> c ; le bit de poids fort de AH devient nul
rrf AL,f ;le bit de poids faible de AH devient le bit de poids fort de AL
return
;------------------------------------------------------------------------
; addwf AL,f ;(f+w) -> dest ; c=1 si retenue (a traiter)
btfsc STATUS,0 ;c
incf BH,f ;ajout retenue
movf BH,w
addwf AH,f ;(f+w) -> dest ; c=1 si retenue
return
;------------------------------------------------------------------------
;addition 16bits
;(AH,AL)+(AH,AL) -> (BH,BL)
;remarque seule la destination (B) est differente par rapport a la procedure add16A
add16B movf AL,w
addwf BL,f ;(f+w) -> dest ; c=1 si retenue (a traiter)
btfsc STATUS,0 ;c
incf AH,f ;ajout retenue
movf AH,w
addwf BH,f ;(f+w) -> dest ; c=1 si retenue
return
;------------------------------------------------------------------------
;complement a deux de la variable codee sur 2 octets situes aux adresses w et w+1
cpl16x movwf FSR
comf INDF,f ;w=complement (H)
incf FSR,f
comf INDF,f ;w=complement (L)
incf INDF,f ;w=complement a 2 de L
btfss STATUS,2 ;z
return
decf FSR,f ;pointe H
incf INDF,f ;retenue
return
;------------------------------------------------------------------------
;division 16bits par 8 bits resultat sur 8 bits : BH,L / w -> w
;par approximations succesives sur les 8 bits (methode rapide, 8 passages max dans la boucle)
;ATTENTION si le resultat est >255 il sera retourne = 255
;il est evident par exemple que 65535 / 1 = 65535 ne tient pas sur 1 octet
;toutefois dans ce programme, le resultat est borne sur 1 octet
; x/0 donne 255
; 0/0 donne 255
; 0/x (x<>0) donne 0
divi16_8 movwf CC ;CC contient le diviseur
clrf BB
movlw B'10000000';masque du bit teste
movwf DD
movwf BB
divi1 movf CC,w
movwf AA
movf BB,w
call multi ;AH,L=AA*w = diviseur * BB ;ne touche pas
call compar16p ;ne touche pas AA ni BB
btfss STATUS,0
goto trop ;test bit suivant
goto pastrop
decf BB,w ;resultat
return
trop movf DD,w
xorwf BB,f ;eteint le bit precedent
bcf STATUS,0
rrf DD,f ;bit suivant
btfsc STATUS,0 ;c c'etait le dernier ?
goto findiv ; oui
movf DD,w
iorwf BB,f ;allume le bit suivant
goto divi1
pastrop bcf STATUS,0
rrf DD,f ;bit suivant
btfsc STATUS,0 ;c c'etait le dernier ?
goto findiv ; oui
movf DD,w
iorwf BB,f ;allume le bit suivant
goto divi1
findiv movf BB,w
return
;------------------------------------------------------------------------
;mov la variable codee sur 2 octets situes aux adresses w et w+1 dans -> AH,AL
movxA movwf FSR
movf INDF,w
movwf AH
incf FSR,f
movf INDF,w
movwf AL
return
;------------------------------------------------------------------------
;mov AH,AL dans -> la variable codee sur 2 octets situes aux adresses w et w+1
movAx movwf FSR
movf AH,w
movwf INDF
incf FSR,f
movf AL,w
movwf INDF
return
;------------------------------------------------------------------------
;mov la variable codee sur 2 octets situes aux adresses w et w+1 dans -> BH,BL
movxB movwf FSR
movf INDF,w
movwf BH
incf FSR,f
movf INDF,w
movwf BL
return
;------------------------------------------------------------------------
;mov BH,BL dans -> la variable codee sur 2 octets situes aux adresses w et w+1
movBx movwf FSR
movf BH,w
movwf INDF
incf FSR,f
movf BL,w
movwf INDF
return
;------------------------------------------------------------------------
;comparaison de deux valeurs codees sur 16 bits (AH,AL a BH,BL)
;resultat dans STATUS carry et zero
;les valeurs doivent representer des nombres tous deux positifs (pas ok si valeurs codees en complement a 2)
;sauf pour le test d'egalite STATUS,2 ('z')
;16p-> p comme positifs
compar16p movf AH,w
subwf BH,w ;c=0 si AH>BH
btfss STATUS,2 ;z=1 si AH=BH il faut alors comparer AL a BL
return
movf AL,w
subwf BL,w ;z=1 si AL=BL et comme on sait deja que AH=BH, si z=1 -> A=B
return
;------------------------------------------------------------------------
;***********************************************************************
; TEMPOS GENERALES
;***********************************************************************
; Qx = 20,000 Mhz
;TEMPO 154us pile
;tiens compte du call de l'appelant et du return final
tp154us movlw .255 ;1 cycle
movwf t1 ;1 cycle
t3loop1 decfsz t1,f ;1 cycle
goto t3loop1 ;2 cycles
return ;2 cycles
;----------------------------------------------------------------------
; Qx = 20,000 Mhz
; 2,0004ms
;tiens compte du call de l'appelant et du return final
tp2ms movlw .13
movwf t1
t4loop1 movlw .255
movwf t2
t4loop2 decfsz t2,f
goto t4loop2
decfsz t1,f
goto t4loop1
return
;----------------------------------------------------------------------
; Qx = 20,000 Mhz
; 1,000ms
;tiens compte du call de l'appelant et du return final
tp1ms movlw .11
movwf t1
t5loop1 movlw .150
movwf t2
t5loop2 decfsz t2,f
goto t5loop2
decfsz t1,f
goto t5loop1
return
;----------------------------------------------------------------------
; Qx = 20,000 Mhz
; 9,998ms
;tiens compte du call de l'appelant et du return final
tp10ms movlw .65
movwf t1
t1loop1 movlw .255
movwf t2
t1loop2 decfsz t2,f
goto t1loop2
decfsz t1,f
goto t1loop1
return
;----------------------------------------------------------------------
; Qx = 20,000 Mhz
tp100ms clrwdt
movlw .10
movwf t3
t2loop2 clrwdt
call tp10ms
decfsz t3,f
goto t2loop2
return
;----------------------------------------------------------------------
; Qx = 20,000 Mhz
;tempo n x 10ms
;charger w avec n avant l'appel de cette procedure
;
tx10ms movwf t3
txlp2 call tp10ms
decfsz t3,f
goto txlp2
return
;----------------------------------------------------------------------
; Qx = 20,000 Mhz
;tempo n x 1ms
;charger w avec n avant l'appel de cette procedure
;
tx1ms movwf t3
txlp3 call tp1ms
decfsz t3,f
goto txlp3
return
;***********************************************************************
; TABLEAUX DE DONNEES
;***********************************************************************
;NOTE: les tableaux doivent se situer chacun sur 1 seule page d'adresse codee sur 8 bits (longueur<=255, 00FF h)
;c.a.d qu'un tableau ne doit pas etre a cheval sur dex pages
;verifier sur le listing absolu obtenu apres compilation.
;je le place en page6
;NOTE: en exa, chaque page de 256octets = 100 (note 0x100)
;RAM page1=0000 a 00FF
;RAM page2=0100 a 01FF
;RAM page3=0200
;etc... jusqu'a
;RAM page8=0700 a 07FF (8 pages de 256 octets pour le PIC16F628, soit 2kO RAM)
org 07C0h
;Le datasheet de Microchip precise ceci:
;A computed GOTO is accomplished by adding an offset
;to the program counter (ADDWF PCL). When doing a table
;read using a computed GOTO method, care should be
;exercised if the table location crosses a PCL memory
;boundary (each 256 word block). Refer to the application
;note "Implementing a Table Read" (AN556).
;--------------------------fin des tableaux en FLASH -----------------------------------
;=======================================================================================
;DATA EN EEPROM
;=======================================================================================
ORG 0x2100 ; zone EEPROM
;=======================================================================================
end