;************************************************************ ; NOM: PassageNiveauClignotantPWM.asm ; Date: 31/05/2008 ; Auteur: Jean-Claude Grimaldi (jean-claude.grimaldi@centraliens.net) ; avec tous ses remerciements à Psi et JiDé pour la rubrique PIC'TRAIN ;************************************************************ ; Commande de passage à niveau avec clignotant alterné ; ; Doubles cellules de part et d'autre ----ab----PN----cd---- ; Placer chaque groupe de cellules en biais pour ne pas détecter l'écart entre wagons ; De gauche à droite, fermeture PN au front montant de "b" si "a" occultée (tête) ; Dans le même sens, ouverture PN au front descendant de "c" si "d" occultée (queue) ; De droite à gauche (D vers A) fonctionnement en sens inverse. ; La détection des entrées et sorties est indépendante pour permettre à un convoi ; entré dans la zone de ressortir en marche arrière du même côté. ; ; Le test des entrées correspond à un phototransistor branché directement sur l'entrée, ; ce qui correspond à un courant établi en cas d'absence. ; Si l'on utilise des détecteurs à courant établi pour présence, permuter btfsc et btfss. ; ; Structure du programme: ; Détection de l'entrée (boucle d'attente d'une séquence d'entrée par "a" ou "d") ; détection a sans b puis présence b si a est toujours là ; (front montant de "b" si "a" occultée) ; sinon détection front montant de "c" si "d" occultée ; sinon retour à la détection de l'entrée par "a" ; Commande du PN ; une sortie clignotants alternés tristable (haute impédance au repos/+5v/0v) ; une sortie mise à +5v pour commander la fermeture du PN ; Détection de la sortie (boucle d'attente d'une séquence de sortie par "a" ou "d") ; détection a et b puis absence b si a est toujours là ; (front descendant de "b" si "a" occultée) ; sinon détection front descendant de "c" si "d" occultée ; sinon retour à la détection d'une sortie par "a" ; Commande ouverture du PN ; arrêt sortie fixe + remise au neutre de la sortie clignotante ; ; Fonctionnement du clignotant: ; La sortie clignotant fonctionne en tristable: ; la sortie est mise en entrée (haute impédance) en temps normal ; elle est mise en sortie dès qu'une présence a été détectée ; le timer commande une variation PWM (modulation de phase) ; un groupe de LED entre sortie et 0v, un autre entre sortie et +5v ; clignotement alterné pour les deux groupes de LED ; Paramètres du PWM ; Intensité (modulation de phase: conduction pendant (x-255)/255) ; Sens stocke le sens d'évolution (1 croit 0 décroit) ; Cycles nombre de cycles d'attente entre deux crans ; Cran valeur de chaque cran de variation d'intensité ; Le sous-programme clignotant est appelé à chaque boucle de détection de sortie ; dès qu'une présence a été détectée (passage à niveau activé). ; L'intensité varie par crans de 0 à 255 alternativement selon le sens. ; Il est nécessaire de laisser passer plusieurs cycles avant de changer chaque cran ; sinon la variation serait trop rapide (période fonction du rapport Cran/Cycles). ; Si le nombre de cycles est atteint, l'intensité varie d'un cran en plus ou en moins. ; Si l'intensité dépasse 255 elle est limitée à 255 et le sens est inversé. ; De même l'intensité est limitée à 0 en décroissance et le sens est inversé. ;************************************************************ ; Détermination des variables du processeur par MPLAB selon le PIC utilisé ifdef __12F675 LIST p=PIC12F675 #INCLUDE endif ifdef __12F629 LIST p=PIC12F629 #INCLUDE endif ERRORLEVEL -302 __CONFIG _CPD_OFF & _BODEN_OFF & _CP_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT ; oscillateur interne 4 MHz ;********************************************************************* ; DEFINE - EQU - INC ;********************************************************************** #DEFINE IO_A GPIO,0 ; Patte 7 Entrée cellule A #DEFINE IO_B GPIO,1 ; Patte 6 Entrée cellule B #DEFINE IO_C GPIO,2 ; Patte 5 Entrée cellule C #DEFINE IO_D GPIO,3 ; Patte 4 (p.m. toujours entrée) Entrée cellule D #DEFINE IO_S GPIO,4 ; Patte 3 Sortie clignotant (feu alterné) et cloche #DEFINE IO_P GPIO,5 ; Patte 2 Sortie commande fermeture passage à niveau ;********************************************************************** ; INITIALISATION ;********************************************************************** C_Cran EQU d'15' ; Valeurs cran de vitesse et nb cycles d'attente C_Cycles EQU d'10' ; = 6 pour 4 cycles 15 pour 10 cycles CBLOCK 0x020 ; Début de la zone des variables VA_Intensite ; Valeur intensité (entre 0 et 255) VA_Sens ; Sens clignotant (1 augmente 0 diminue) VA_Compteur_Cycles ; Compteur de cycles entre chaque cran ENDC ; Fin de la zone des variables #INCLUDE ;********************************************************************* ; PARAMETRES SPECIFIQUES ;********************************************************************* ; parametres des entrées/sorties BANK1 ; Passage en BANK1 clrf TRISIO ; Tous les bits à 0 (output) bsf TRISIO,0 ; sauf bit 0 (A) bsf TRISIO,1 ; sauf bit 1 (B) bsf TRISIO,2 ; sauf bit 2 (C) bsf TRISIO,3 ; sauf bit 3 (D) bsf TRISIO,4 ; sauf bit 4 (sortie clignotant état neutre) clrf WPU ; Bits à 0 (pas de résistance) bsf WPU,0 ; sauf l’entrée 0 bsf WPU,1 ; sauf l’entrée 1 bsf WPU,2 ; sauf l’entrée 2 bsf WPU,3 ; sauf l’entrée 3 ; Paramètres du prédiviseur bsf OPTION_REG,1 ; Pré-diviseur sur 16 bsf OPTION_REG,0 ; Registre contrôle interruptions INTCON clrf INTCON bsf INTCON,GIE ; Activation des interruptions BANK0 clrf GPIO ; tous les bits E/S initialisés à 0 clrf VA_Intensite ; Initialisation intensité à 0 clrf VA_Compteur_Cycles ; Initialisation compteur cycles à 0 ;********************************************************************** ; Boucle principale ;********************************************************************** ET_BouclePrincipale ; Détection entrée dans la zone ; Entrée par côté A ET_entree_A ; boucle d'attente A en entrée btfss IO_A ; test si présence A goto ET_entree_D ; si non (absence A) saut à entrée par CD btfsc IO_B ; si oui (présence A) test présence B goto ET_BouclePrincipale ; si oui (présence B) retour (il faut A sans B) ET_attente_Be ; présence A et absence B, boucle d'attente B btfss IO_A ; test si toujours présence A goto ET_entree_D ; si non (absence A) saut à entrée par CD btfss IO_B ; test si présence B goto ET_attente_Be ; si non (absence B) boucle goto ET_CommandePN ; si oui (présence B)fermeture passage à niveau ; Entrée par côté D ET_entree_D ; boucle d'attente D en entrée btfss IO_D ; test si présence D goto ET_BouclePrincipale ; si non (absence D) retour btfsc IO_C ; si oui (présence D) test présence C goto ET_BouclePrincipale ; si oui (présence C) retour (il faut D sans C) ET_attente_Ce ; présence D et absence C, boucle d'attente C btfss IO_D ; test si toujours présence D goto ET_BouclePrincipale ; si non (absence D) retour btfss IO_C ; test si présence C goto ET_attente_Ce ; si non (absence C) boucle goto ET_CommandePN ; si oui (présence C)fermeture passage à niveau ; Présence dans la zone: commande passage à niveau ET_CommandePN BANK1 ; Passage en BANK1 bcf TRISIO,4 ; bit 4 clignotant mis en sortie BANK0 ; Retour en BANK0 bsf IO_S ; commande sortie clignotant bsf IO_P ; commande passage à niveau bsf INTCON,T0IE ; lancement Timer0 pour clignotement alterné ; Détection sortie de la zone ; Sortie par côté A ET_sortie_A ; détection sortie par A call SP_Clignotant ; Mise à jour paramètres clignotant btfss IO_A ; test si présence A goto ET_sortie_D ; si non (absence A) saut test sortie par D btfss IO_B ; si oui (présence A) test présence B goto ET_sortie_D ; si non (absence B) saut test sortie par D ET_attente_Bs ; présence A et B, boucle d'attente absence B call SP_Clignotant ; Mise à jour paramètres clignotant btfss IO_A ; test si toujours présence A goto ET_sortie_D ; si non (absence A) saut test sortie par D btfsc IO_B ; si oui (présence A) test présence B goto ET_attente_Bs ; si oui (présence B) boucle goto ET_OuverturePN ; présence A et retombée B : ouverture PN ; Sortie par côté D ET_sortie_D ; boucle d'attente D en sortie call SP_Clignotant ; Mise à jour paramètres clignotant btfss IO_D ; test si présence D goto ET_sortie_A ; si non (absence D) saut test sortie par A btfss IO_C ; si oui (présence D) test présence C goto ET_sortie_A ; si non (absence C) saut test sortie par A ET_attente_Cs ; présence D et C, boucle d'attente absence C call SP_Clignotant ; Mise à jour paramètres clignotant btfss IO_D ; test si toujours présence D goto ET_sortie_A ; si non (absence D) saut test sortie par A btfsc IO_C ; si oui (présence D) test présence C goto ET_attente_Cs ; si oui (présence C) boucle goto ET_OuverturePN ; présence D et retombée C : ouverture PN ; Sortie de la zone: ouverture passage à niveau ET_OuverturePN bcf IO_P ; arrêt commande fermeture PN bcf INTCON,T0IE ; arrêt Timer0 pour clignotant bcf IO_S ; arrêt signalisation BANK1 ; Passage en BANK1 bsf TRISIO,4 ; bit 4 clignotant remis en entrée (état neutre) BANK0 ; Retour en BANK0 goto ET_BouclePrincipale ;********************************************************************* ; Sous programmes ;********************************************************************* ; Sous programme Clignotant à allumage et extinction progressive en PWM ;********************************************************************* SP_Clignotant movf VA_Compteur_Cycles,F; Lire état des cycles d'attente btfss STATUS,Z ; Test compteur cycles restant à 0 return ; Retour si nb de cycles non effectué movlw C_Cycles ; Charger nombre de cycles prévus movwf VA_Compteur_Cycles ; Ecrire dans la variable movfw VA_Sens ; Charger sens clignotant dans W btfsc STATUS,Z ; Test si zéro (décroissant) goto ET_Diminue ET_Augmente movlw C_Cran ; Charger valeur du cran d'intensité addwf VA_Intensite,F ; Ajouter un cran à l'intensité btfss STATUS,C ; Test si dépassement return ; Retour si pas dépassement clrf VA_Sens ; Mettre à 0 variable sens (décroissant) movlw d'255' ; Charger valeur 255 dans le registre movwf VA_Intensite ; Charger dans variable intensité return ; Retour ET_Diminue movlw C_Cran ; Charger valeur du cran d'intensité subwf VA_Intensite,F ; Soustraire un cran à l'intensité btfsc STATUS,C ; Test si dépassement return ; Retour si pas dépassement movlw d'1' ; Mettre 1 dans le registre movwf VA_Sens ; Charger dans variable sens (croissant) clrw ; Mettre à zéro le registre movwf VA_Intensite ; Charger dans variable intensité return ; Retour ;********************************************************************* ; Interruption TMR1 appelée à chaque interruption TMR1 ;********************************************************************* SP_inttimer1 ; non utilisé dans ce montage return ;********************************************************************* ; Interruption TMR0 appelée à chaque interruption TMR0 ;********************************************************************* SP_inttimer0 BANK0 btfsc IO_S ; Test sortie à l'état bas goto ET_Sortie_Haut ; Sinon la sortie est 'haut' ET_Sortie_Bas ; Phase 'haut' pendant (255-intensité) bsf IO_S ; Mettre sortie à 'haut' movf VA_Intensite,W ; Copier l'intensité dans le registre sublw d'255' ; Soustraire le registre de 255 movwf TMR0 ; Charger dans le timer (255-intensité) decf VA_Compteur_Cycles,F; Décrémenter le compteur de cycles return ; Fin de gestion sortie 'haut' ET_Sortie_Haut ; Phase 'bas' pendant (intensité) bcf IO_S ; Mettre sortie à 'bas' movf VA_Intensite,W ; Copier l'intensité dans le registre movwf TMR0 ; Charger dans le timer (intensité) return ; Fin de gestion sortie 'bas' ;********************************************************************* END