;********************************************************************** ; ; NOM: TPE ASPIRATEUR ; Date: 6/01/05 ; Version:1.00 ; Circuit: ; Auteur: Skynack (nicnsmith@free.fr) ; ;********************************************************************** ; Fichier requis: P16F84a.inc ;********************************************************************** LIST p=16F84a ; Définition de processeur #include ; Définitions des constantes __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC ; '__CONFIG' précise les paramètres encodés dans le processeur au moment de ; la programmation du processeur. Les définitions sont dans le fichier include. ; Voici les valeurs et leurs définitions : ; _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 ; _XT_OSC Oscillateur quartz moyenne vitesse ; _HS_OSC Oscillateur quartz grande vitesse ; _RC_OSC Oscillateur à réseau RC ;********************************************************************* ; ASSIGNATIONS * ;********************************************************************* OPTIONVAL EQU H'0040' ; Valeur registre option ; Résistance pull-up ON ; Interrupt flanc montant RB0 ; Préscaler timer à 2 (exemple) INTERMASK EQU H'0090' ; Masque d'interruption ; Interruptions sur RB0 (exemple) GAUCHE EQU H'0000' ; la gauche prend la valeur 0 DROITE EQU H'0001' ; la droite prend la valeur 1 ;INTERON EQU H'0090' ; autorise l'interruption de RB0/INT INTEROFF EQU H'0000' ; refuse toutes les interruptions ;********************************************************************* ; DEFINE * ;********************************************************************* ; sorties #DEFINE MDA PORTA,0 ; Sortie Moteur Droit Avancer #DEFINE MGA PORTA,1 ; Sortie Moteur Gauche Avancer #DEFINE MDR PORTA,2 ; Sortie Moteur Droit Reculer #DEFINE MGR PORTA,3 ; Sortie Moteur Gauche Reculer ;------- ;entrées #DEFINE CAU PORTB,1 ; Entrée capteur Avant Ultrason #DEFINE CAM PORTB,0 ; Entrée capteur Avant Magnétique #DEFINE CD PORTB,2 ; Entrée capteur Droite infrarouge #DEFINE CG PORTB,3 ; Entrée capteur Gauche infrarouge ;------- ; réceptivité Mise en marche #DEFINE MISEEM PORTB,4 ; Entrée bouton mise en marche ;********************************************************************* ; MACRO * ;********************************************************************* BANK0 macro bcf STATUS , RP0 ; passer banque0 endm BANK1 macro bsf STATUS , RP0 ; passer banque1 endm MDAON macro bsf MDA ; met à 1 le bit Moteur Droit Avancer endm MDAOFF macro bcf MDA ; met à 0 le bit Moteur Droit Avancer endm MGAON macro bsf MGA ; met à 1 le bit Moteur Gauche Avancer endm MGAOFF macro bcf MGA ; met à 0 le bit Moteur Gauche Avancer endm MDRON macro bsf MDR ; met à 1 le bit Moteur Droit Reculer endm MDROFF macro bcf MDR ; met à 0 le bit Moteur Droit Reculer endm MGRON macro bsf MGR ; met à 1 le bit Moteur Gauche Reculer endm MGROFF macro bcf MGR ; met à 0 le bit Moteur Gauche Reculer endm ;********************************************************************* ; DECLARATIONS DE VARIABLES * ;********************************************************************* ;exemples ;--------- CBLOCK 0x00C ; début de la zone variables w_temp :1 ; Sauvegarde du registre W status_temp : 1 ; Sauvegarde du registre STATUS varAv : 1 ; cette variable est en fait ; une présélection du virage prochain ; établie après le virage précédent ; à 0, c'est droite ; à 1, c'est gauche varVirageSel : 1 ; validation du virage, avant de l'éffectuer sauve_cd_log : 1 ; sauve la valeur du bit CD sauve_cg_log : 1 ; sauve la valeur du bit CG op_log : 1 ; variable contenant divers resultats ; d'opérations cmpt1 : 1 ; compteur 1 variable 1 cmpt2 : 1 ; compteur 1 variable 2 cmpt3 : 1 ; compteur 1 variable 3 autorisation_vir : 1 ; = 0 => autorise le virage ; = 1 => necessite tests ENDC ; Fin de la zone ;********************************************************************** ; DEMARRAGE SUR RESET * ;********************************************************************** org 0x000 ; Adresse de départ après reset goto init ; Adresse 0: initialiser ;********************************************************************** ; ROUTINE INTERRUPTION * ;********************************************************************** ;sauvegarder registres ;--------------------- org 0x004 ; adresse d'interruption movwf w_temp ; sauver registre W swapf STATUS,w ; swap status avec résultat dans w movwf status_temp ; sauver status swappé ; switch vers différentes interrupts ; inverser ordre pour modifier priorités ;---------------------------------------- btfsc INTCON,T0IE ; tester si interrupt timer autorisée btfss INTCON,T0IF ; oui, tester si interrupt timer en cours goto intsw1 ; non test suivant call inttimer ; oui, traiter interrupt timer bcf INTCON,T0IF ; effacer flag interrupt timer goto restorereg ; et fin d'interruption ; SUPPRIMER CETTE LIGNE POUR ; TRAITER PLUSIEURS INTERRUPT ; EN 1 SEULE FOIS intsw1 btfsc INTCON,INTE ; tester si interrupt RB0 autorisée btfss INTCON,INTF ; oui, tester si interrupt RB0 en cours goto intsw2 ; non sauter au test suivant call intrb0 ; oui, traiter interrupt RB0 bcf INTCON,INTF ; effacer flag interupt RB0 goto restorereg ; et fin d'interruption ; SUPPRIMER CETTE LIGNE POUR ; TRAITER PLUSIEURS INTERRUPT ; EN 1 SEULE FOIS intsw2 btfsc INTCON,RBIE ; tester si interrupt RB4/7 autorisée btfss INTCON,RBIF ; oui, tester si interrupt RB4/7 en cours goto intsw3 ; non sauter call intrb4 ; oui, traiter interrupt RB4/7 bcf INTCON,RBIF ; effacer flag interupt RB4/7 goto restorereg ; et fin d'interrupt ; SUPPRIMER CETTE LIGNE POUR ; TRAITER PLUSIEURS INTERRUPT ; EN 1 SEULE FOIS intsw3 BANK1 ; passer banque1 btfsc INTCON,EEIE ; tester si interrupt EEPROM autorisée btfss EECON1,EEIF ; oui,tester si interrupt EEPROM goto restorereg ; non sauter call inteep ; traiter interruption eeprom ;restaurer registres ;------------------- restorereg swapf status_temp,w ; swap ancien status, résultat dans w movwf STATUS ; restaurer status swapf w_temp,f ; Inversion L et H de l'ancien W ; sans modifier Z swapf w_temp,w ; Réinversion de L et H dans W ; W restauré sans modifier status retfie ; return from interrupt ;********************************************************************** ; INTERRUPTION TIMER 0 * ;********************************************************************** inttimer return ; fin d'interruption timer ; peut être remplacé par ; retlw pour retour code d'erreur ;********************************************************************** ; INTERRUPTION RB0/INT * ;********************************************************************** intrb0 ; sauvegarde les ports des moteurs ; on vérifie que les moteurs soient éteints btfsc MGA ; teste si le moteur gauche est à 1 MGAOFF ; si mot gauche = 1, on met à 0 btfsc MDA ; teste si le moteur droit est à 1 MDAOFF ; si mot droit = 1, on met à 0 ; si c'est le cas, on recule MGRON ; on lance les moteurs : gauche MDRON ; droit call tempoRecul05 ; effectue la temporisation MGROFF ; éteint les moteurs MGROFF ; éteint les moteurs return ; fin d'interruption RB0/INT ; peut être remplacé par ; retlw pour retour code d'erreur ;********************************************************************** ; INTERRUPTION RB0/RB4 * ;********************************************************************** intrb4 return ; fin d'interruption RB0/RB4 ; peut être remplacé par ; retlw pour retour code d'erreur ;********************************************************************** ; INTERRUPTION EEPROM * ;********************************************************************** inteep return ; fin d'interruption eeprom ; peut être remplacé par ; retlw pour retour code d'erreur ;********************************************************************* ; INITIALISATIONS * ;********************************************************************* init clrf PORTA ; Sorties portA à 0 clrf PORTB ; sorties portB à 0 BANK1 ; passer banque1 ;clrf EEADR ; permet de diminuer la consommation movlw OPTIONVAL ; charger masque movwf OPTION_REG ; initialiser registre option ; Effacer RAM ; ------------ movlw 0x0c ; initialisation pointeur movwf FSR ; pointeur d'adressage indirect init1 clrf INDF ; effacer ram incf FSR,f ; pointer sur suivant btfss FSR,6 ; tester si fin zone atteinte (>=40) goto init1 ; non, boucler btfss FSR,4 ; tester si fin zone atteinte (>=50) goto init1 ; non, boucler ; ZONE A COMPLETER BANK1 bcf varVirageSel, 0 ; initialise la variable bsf varAv, 0 ; virage opar défaut = droite; bsf TRISB ,0 ; Bit PORTB.0 en entrée bsf TRISB,1 ; Bit PORTB.1 en entrée bsf TRISB,2 ; Bit PORTB.2 en entrée bsf TRISB,3 ; Bit PORTB.3 en entrée bcf TRISA,0 ; Bit PORTA.0 en sortie bcf TRISA,1 ; Bit PORTA.1 en sortie bcf TRISA,2 ; Bit PORTA.2 en sortie bcf TRISA,3 ; Bit PORTA.3 en sortie bsf TRISB,4 ; Bit PORTB.4 en entrée ; désactivation des interruptions movlw INTEROFF ; on passe la valeur des interrup dans W movwf INTCON ; on passe W dans le registre d'interrup BANK0 ; passer banque0 movlw INTERMASK ; masque interruption movwf INTCON ; charger interrupt control goto start ; sauter programme principal ;********************************************************************* ; ROUTINE DE FONCTIONNEMENT normal * ; cette ensemble de fonctions teste la présence initiale de personne ; face au système : dans le cas d'une présence, on recule ; dans le cas d'une absence on avance ;********************************************************************* ; teste l'absence fonctionnement absenceUltra btfsc CAU ; teste présence capteur frontal ultrasons goto recul1 ; CAU = 1 on lance séquense recul goto absenceMag ; CAU = 0 on teste le capteur magnétique absenceMag btfsc CAM ; teste présence capteur frontal magnétique goto recul1 ; CAM = 1 on lance séquence recul goto avance1 ; CAM = 0 rien devant on avance ; tests effectués négatifs , il faut reculer pour libérer l'espace recul1 MDRON ; allume moteur droit en recul MGRON ; allume moteur gauche en recul call tempoRecul01 ; on appelle la tempo de recul MDROFF ; on arête le moteur gauche MGROFF ; on arete le moteur droit goto avance1 ; après avoir libéré l'espace, on avance ; tests effectués positifs , on effectue l'avance avance1 btfss MGA ; teste si le moteur gauche est à 0 MGAON ; si mot gauche = 0, on met à 1 btfss MDA ; teste si le moteur droit est à 0 MDAON ; si mot droit = 0, on met à 1 goto detection ; on va ensuite tester l'environnement ;********************************************************************* ; ROUTINE DE détection Mag/Ultra ; cette routine teste les capteurs pour détecter la présence d'un ; obstacle : dans le cas de présence, on effectue la routine de choix de ; virage, dans le cas échéant elle se boucle. Les tests permettent ; surtout de différencier la détection magnétique, et la détection ; avec le capteur ultrasons ;********************************************************************* detection btfsc CAU ; on teste le capteur ultrasons goto virageUltrason ; CAU = 1, il fo faire les tests ;virage ultrason btfsc CAM ;on teste le capteur magnétique goto virageMagnetique ; CAM = 1, lance le test virage ; magnétique goto detection ; CAM = 0, reboucle les tests de présence ;********************************************************************* ; ROUTINE DE préparation au Virage; ;********************************************************************** virageUltrason MGAOFF ; MDAOFF ; MGROFF ; MDROFF ; goto virageSelection ; on choisit le virage à effectuer virageMagnetique MGAOFF ; MDAOFF ; MGRON ; MDRON ; call tempoRecul05 ; on recule d'abord MGROFF ; MDROFF ; goto virageSelection ; on choisit le virage à effectuer ;********************************************************************* ; ROUTINE DE choix du Virage; ;********************************************************************** virageSelection clrf varVirageSel ; on efface la var pour la remplacer test CD movlw H'00' ; on charge d'abord 0 btfsc CD ; charge la valeur dans W movlw H'01' ; CD = 1 nop ; CD = 0 movwf sauve_cd_log ; sauvegarde dans la var movlw H'00' btfsc CG ; charge la valeur dans W movlw H'01' ; CG = 1 nop ; CG = 0 movwf sauve_cg_log ; sauvegarde dans la var movlw H'00' ; on place 0 dans W btfsc sauve_cg_log, 0 ; teste le bit 0 de la var movlw H'01' ; = 1 nop ; = 0 andwf sauve_cd_log, w ; AND entre les 2 var movwf op_log ; sauvegarde btfsc op_log, 0 ; teste le bit 0 de op_log call call_recul ; si = 1 on recule et on teste call call_test ; si = 0 on fait les tests suivants btfsc autorisation_vir, 0 ; teste l'autorisation goto virageSelection ; = 1 demande les tests nop ; = 0 effectue le virage clrf sauve_cd_log ; efface deux variables clrf sauve_cg_log ; goto virageEffectue ; ;********************************************************************* ; ROUTINES DE VIRAGE * ;********************************************************************* virageEffectue MDAOFF ; on eteint le moteur droit MGAOFF ; on eteint le moteur gauche btfsc varVirageSel, 0 ; on teste si le virage doit etre ; à gauche ou à droite goto virageEffectueDroite ; = 1 = droite goto virageEffectueGauche ; = 0 = gauche virageEffectueGauche ;movlw INTERON ; on active ;movwf INTCON ; l'interruption de la patte RB0/INT MGAOFF ; on éteint le moteur gauche MDAON ; on allume le moteur droit call tempoVirage ; vire pendant la durée de la tempo MGAOFF ; on éteint le moteur gauche MDAOFF ; on éteint le moteur droit bsf varAv, 0 ; on veut un prochain virage à droite ; désactivation des interruptions ;movlw INTEROFF ; on passe la valeur des interrup dans W ;movwf INTCON ; on passe W dans le registre d'interrup clrf autorisation_vir ; on efface l'autorisation goto start ; on recommence le cycle virageEffectueDroite ;movlw INTERON ; on active ;movwf INTCON ; l'interruption de la patte RB0/INT MDROFF ; on éteint le moteur droite MGROFF ; on éteint le moteur gauche MDAOFF ; on éteint le moteur droite MGAON ; on allume le moteur gauche call tempoVirage ; vire pendant la durée de la tempo MGAOFF ; on éteint le moteur gauche MDAOFF ; on éteint le moteur droit ; désactivation des interruptions ;movlw INTEROFF ; on passe la valeur des interrup dans W ;movwf INTCON ; on passe W dans le registre d'interrup bcf varAv, 0 ; on veut un prochain virage à gauche clrf autorisation_vir ; on efface l'autorisation goto start ; on recommence le cycle ;********************************************************************* ; ROUTINES DE TESTS * ;********************************************************************* call_test btfss varAv, 0 ; on teste varAv goto call_test_gauche1 ; = 0 => demande Gauche goto call_test_droite1 ; = 1 => demande Droite call_test_gauche1 btfss CG ; teste le capteur gauche goto call_valide_gauche ; = 0 => on valide le virage gauche goto call_test_gauche2 ; = 1 => Phase 2 de test propose Gauche call_test_droite1 btfss CD ; teste le capteur droit goto call_valide_droite ; = 0 => on valide le virage droite goto call_test_droite2 ; = 1 => Phase 2 de test propose Droite call_test_gauche2 btfss CG ; teste le capteur gauche goto call_valide_gauche ; = 0 => on valide le virage Gauche return ; = 1 => call_test_droite2 btfss CD ; teste le capteur droit goto call_valide_droite ; = 0 => on valide le virage Droite return ; = 1 => call_valide_droite movlw H'00' ; on place l'indice dans le registre ; de travail movwf autorisation_vir ; variable = 0 pour autoriser virage movlw H'01' ; envoie la valeur droite ds W movwf varVirageSel ; valide la variable et retourne return ; call_valide_gauche movlw H'00' ; on place l'indice dans le registre ; de travail movwf autorisation_vir ; variable = 0 pour autoriser virage movlw H'00' ; envoi la valeur gauche ds W movwf varVirageSel ; valide la variable et retourne return call_recul MGAOFF ; on arete les moteurs d'avancement MDAOFF ; // MGRON ; allume les moteurs de recul MDRON ; // ; ///////////////////// TEMPORISATION 0.5 S////////////////////////// movlw 2 ; on place 2 dans W movwf cmpt3 ; on place W dans cmpt3 boucleB3 clrf cmpt2 ; effacer cmpt2 boucleB2 clrf cmpt1 ; effacer cmpt1 boucleB1 nop ; + 256 * 256 * 2 decfsz cmpt1, f ; decrem cmpt1 goto boucleB1 ; si pas 0, boucler decfsz cmpt2, f ; si 0, décr compt2 goto boucleB2 ; si cmpt2 pas 0, reco boucle B1 decfsz cmpt3, f ; si 0, décr compt3 goto boucleB3 ; si cmpt3 pas 0, reco boucle B2 ; /////////////////FIN DE TEMPORISATION 0.5 S////////////////////////// MGROFF ; eteint les moteurs de recul MDROFF ;// movlw H'01' ; on place l'indice dans le registre ; de travail movwf autorisation_vir ; variable = 1 pour demander des tests return ; ;********************************************************************* ; ROUTINES DE TEMPORISATION * ;********************************************************************* ;############################################################### ; cette temporisation a une durée de .66 seconde environ tempoVirage movlw 2 ; on place 2 dans W movwf cmpt3 ; on place W dans cmpt3 boucle3 clrf cmpt2 ; effacer cmpt2 boucle2 nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; clrf cmpt1 ; effacer cmpt1 boucle1 nop ; 256 * 256 * 2 nop ; 256 * 256 * 2 decfsz cmpt1, f ; decrem cmpt1 goto boucle1 ; si pas 0, boucler decfsz cmpt2, f ; si 0, décr compt2 goto boucle2 ; si cmpt12 pas 0, reco boucle 1 decfsz cmpt3, f ; si 0, décr compt3 goto boucle3 ; si cmpt3 pas 0, reco boucle 2 return ; ;############################################################### ; cette temporisation a une durée de 1 seconde environ tempoRecul01 movlw 4 ; on place 4 dans W movwf cmpt3 ; on place W dans cmpt3 boucle23 clrf cmpt2 ; effacer cmpt2 boucle22 clrf cmpt1 ; effacer cmpt1 boucle21 nop ; 4 * 256 * 256 decfsz cmpt1, f ; decrem cmpt1 goto boucle21 ; si pas 0, boucler decfsz cmpt2, f ; si 0, décr compt2 goto boucle22 ; si cmpt12 pas 0, reco boucle 21 decfsz cmpt3, f ; si 0, décr compt3 goto boucle23 ; si cmpt3 pas 0, reco boucle 22 return ; ;############################################################### ; cette temporisation a une durée de 0.5 seconde environ tempoRecul05 movlw 2 ; on place 2 dans W movwf cmpt3 ; on place W dans cmpt3 boucle33 clrf cmpt2 ; effacer cmpt2 boucle32 clrf cmpt1 ; effacer cmpt1 boucle31 nop ; + 256 * 256 * 2 decfsz cmpt1, f ; decrem cmpt1 goto boucle31 ; si pas 0, boucler decfsz cmpt2, f ; si 0, décr compt2 goto boucle32 ; si cmpt2 pas 0, reco boucle 31 decfsz cmpt3, f ; si 0, décr compt3 goto boucle33 ; si cmpt3 pas 0, reco boucle 32 return ; ;############################################################### ;********************************************************************* ; PROGRAMME PRINCIPAL * ;********************************************************************* start btfss MISEEM ; on teste si le bit de mise en marche ; est à 1 goto start ; MARCHE = 0; on reboucle call tempoRecul05 ; tempo de quelques 0.5s goto fonctionnement ; MARCHE = 1; séquence lancement moteur END ; directive fin de programme