; générateur de freinage à double régime et disjoncteur ; référence: NMRA standard S9.2 July 2004 ; paragraphe "Digital decoder broadcast stop packets for all decoders" ; bit 1: 58µs à l'état A, puis 58µs à l'état B (S9.1: 58µs) ; bit 0: 116µs à l'état A, puis 116µs à l'état B (S9.1: >100µs) ; transmettre: préambule-0-octet1-0-octet2-0-octet3-1 ; octet1 = 00000000 -> diffusion générale ; octet2 = 01DC000S: D=direction, C=1 -> ignorer D, S=0 -> ralentissement progressif, S=1 -> arrêt instantané ; octet3 = octet2 puisque octet1 = 0 (XOR...) ; mesure du courant pendant chaque partie des bits 0 (une fois sur chaque alternance) ;========================================================================== variable mypic = 675 ; utilisé dans MyMacros.inc LIST P=PIC12F675 #INCLUDE __CONFIG _BODEN_ON & _CP_OFF & _PWRTE_ON & _WDT_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT ; 12F675 (MCLRE!) OK ;--------------------------------------------------------------------------- alias #define duree0 d'201' ; 201=256-((116-6)/2) (~6 instructions pour rechargement timer) #define duree1 d'230' ; 230=256-((58-6)/2) (~6 instructions pour rechargement timer) ; #define EtatA b'00000100' ; GP2=1 (LED1/VM111, GP4/LED2 utilisé pour oscillo) ; #define EtatB b'00010000' ; GP2=0 (LED1/VM111, tests avec ShowDCC) ; #define EtatB b'00000000' ; GP2=0 (LED1/VM111, GP4/LED2 utilisé pour oscillo) #define EtatA b'00000101' ; GP0=1 GP1=0 GP2=1 (FCOM) #define EtatB b'00000110' ; GP0=0 GP1=1 GP2=1 (FCOM) ; #define EtatOff b'00000111' ; les deux lignes au plus, non flottantes (§) #define EtatOff b'00000000' ; les deux lignes flottantes (§) #define Mode GPIO,3 ; cavalier sur GP3 #define Disjoncteur GPIO,4 ; détection de courant sur AN3 (=GP4) #define Indicateur GPIO,5 ; indication de disjonction vers Stamp ; seuil de disjonction (plafonné à 0.7V): ; sur 0.33ohms: 0.5A=0.17V=8/255, 1A=0.33V=17/255, 1.5A=0.495V=25/255, 2A=0.66V=34/255 #define Seuil d'25' ; 1.5A ;------------------------------------------------------------------------ variables cblock 0x20 Compteur ; compteur de bits Octet ; octet à envoyer Temp ; variable à tout faire endc ;--------------------------------------------------------------------------- EEPROM org 0x2108 de "Generat.freinage15/06/09vers. 4 reglage:1,5A 5s" ;--------------------------------------------------------------------------- macros TestCourant macro ; mesure du courant pendant une moitié du bit 0 ; ça doit durer moins de 116µs en ce qui concerne la première partie du bit (état A) ; en ce qui concerne la seconde partie, ça pourrait être plus long (cf NMRA standard S9.1-A "stretched 0 bit") ; ici la conversion dure 52µs (mesurées): acquisition: 20µs, conversion: 32µs. ; (en fait le temps d'acquisition pourrait être réduit ou supprimé (cf. § 7.2 du PDF): ; puisque RS=0, diminution de 9µs (c.a.d. 11 au lieu de 20)... movlw b'00001101' ; 0-0-xx-11-0-1 = left (MSB only), ref=Vdd, AN3, stop, on movwf ADCON0 movlw d'6' ; attente 3*6 + 1 µs movwf Temp decfsz Temp, F goto $-1 ; à partir d'ici, 32µs (mesurées) bsf ADCON0, GO_DONE ; start conversion btfsc ADCON0, GO_DONE ; is conversion completed? goto $-1 ; no: wait conversion ends ; la valeur est dans ADRESH. ; comparaison avec le seuil choisi: movlw Seuil bcf STATUS, C subwf ADRESH,W ; W = ADRESH-W btfsc STATUS, C ; négatif? goto Disjonction ; oui: ADRESH>W ; fin de la mesure du courant endm ;********************************************************************************** org 0 ;********************************************************************************** ; initialisations E/S clrf GPIO ; initialisations en bank 1 bsf STATUS,RP0 ; Bank 1 movlw b'10000000' movwf OPTION_REG ; pas de pull-ups, le reste à 0. Timer0 compte par 2µs. clrf WPU ; aucune pull-up, au cas où ;movlw b'11101011' ; GP2 et GP4 en sortie, les autres en entrée (VM111) movlw b'11011000' ; GP0, GP1, GP2 et GP5 en sortie, les autres en entrée (FCOM) movwf TRISIO ; disable comparator au cas où clrf VRCON ; initialisation du CAN movlw b'01011000' ; x-001-1111 = F/8, AN3 movwf ANSEL ; calibration call 0x3ff ; Get calibration value movwf OSCCAL ; Set calibration ; initialisations en bank 0 bcf STATUS,RP0 ; Bank 0 ; disable comparator movlw 0x7 ; turn digital i/o movwf CMCON ; on GP0/1/2 ; disable timer1 clrf TMR1L clrf TMR1H clrf T1CON ; preparation timer0 clrf TMR0 clrf INTCON ; préparation des E/S movlw EtatA movwf GPIO ;ClearRam ; macro dans MyMacros.inc bsf Indicateur ; pas de surintensité ;********************************************************************************* ; TESTS DE CALIBRATION ; envoi de 1 permanents ; call Bit1 ; goto $-1 ; envoi de 0 permanents ; call Bit0 ; goto $-1 ; envoi de 0 et 1 alternés ; call Bit0 ; call Bit1 ; goto $-2 ; envoi d'un octet ;test: ; bsf GPIO,4 ; déclenchement oscillo, sera resetté par signal ; movlw b'11111100' ; par exemple ; movwf Octet ; call EnvoiOctet ; goto test ;********************************************************************************* ; ENVOI D'UN PAQUET: préambule-0-00000000-0-0101000S-0-0101000S-1 Paquet: ; préambule: 16x1 movlw d'16' movwf Compteur call Bit1 decfsz Compteur goto $-2 ; start bit: 0 call Bit0 ; octet 1: 00000000 clrf Octet call EnvoiOctet ; start bit: 0 call Bit0 ; octet 2: 01010000 (ralentissement progressif) ou 01010001 (arrêt instantané) movlw b'01010000' ; progressif btfss Mode movlw b'01010001' ; instantané si pas de cavalier movwf Octet call EnvoiOctet ; start bit: 0 call Bit0 ; octet 3: identique à octet 2 (Error Detection) movlw b'01010000' btfss Mode movlw b'01010001' movwf Octet call EnvoiOctet ; end bit: 1 call Bit1 ; et on recommence goto Paquet ;********************************************************************************* EnvoiOctet: ; envoi d'un octet, MSB en premier movlw d'8' movwf Compteur UnBit: rlf Octet, F ; carry = msb btfss STATUS, C ; skip si bit = 1 goto bita0 ; bit à 0 call Bit1 goto BitSuivant bita0: call Bit0 ;goto BitSuivant BitSuivant: ; s'il y en a un decfsz Compteur ; nb de bits restants à transmettre goto UnBit return ;********************************************************************************* Bit1: ; envoi d'un bit 1 btfss INTCON, T0IF ; attente de la fin du bit précédent goto $-1 movlw duree1 ; rechargement du timer movwf TMR0 bcf INTCON, T0IF ; redémarrage du timer movlw EtatA movwf GPIO ; passage à l'état A btfss INTCON, T0IF ; attente de la fin de la première partie du bit en cours goto $-1 movlw duree1 ; rechargement du timer movwf TMR0 bcf INTCON, T0IF ; redémarrage du timer movlw EtatB movwf GPIO ; passage à l'état B return ; retour avant la fin du bit pour préparer le bit suivant ;********************************************************************************* Bit0: ; envoi d'un bit 0. Comme bit 1 sauf durée, plus test de la valeur du courant. btfss INTCON, T0IF ; attente de la fin du bit précédent goto $-1 movlw duree0 ; rechargement du timer movwf TMR0 bcf INTCON, T0IF ; redémarrage du timer movlw EtatA movwf GPIO ; passage à l'état A TestCourant ; lecture et test du courant à l'état A btfss INTCON, T0IF ; attente de la fin de la première partie du bit en cours goto $-1 movlw duree0 ; rechargement du timer movwf TMR0 bcf INTCON, T0IF ; redémarrage du timer movlw EtatB movwf GPIO ; passage à l'état B TestCourant ; lecture et test du courant à l'état B return ; retour avant la fin du bit pour préparer le bit suivant ;********************************************************************************* Disjonction: ; signalisation au Stamp bcf Indicateur movlw EtatOff ; coupure du courant comme choisi au départ (§) movwf GPIO ; attente X secondes movlw b'00110101' ; préparation timer1 avec prescaler 1/8 = 524ms cycle movwf T1CON ; timer1 tourne movlw d'10' movwf Temp ; comptage 10 x timer1 = à peu près 5.24 s Boucle: clrf TMR1L clrf TMR1H bcf PIR1, TMR1IF btfss PIR1, TMR1IF ; attente... goto $-1 ; ... 1 cycle timer1 ; fin du timer decfsz Temp goto Boucle ; fin de la temporisation ; disable timer1 clrf TMR1L clrf TMR1H clrf T1CON movlw b'00110100' ; stop timer1 to save power ; fin de la disjonction bsf Indicateur ;goto Paquet ; non: la pile peut déborder après de multiples disjonctions return ;********************************************************************************* end ;=================================================================================