Pourquoi ce générateur :
Ce générateur est incorporé dans une carte de commande de plaque tournante.
Le but est d’empêcher la manoeuvre des locomotives lorsque la plaque tourne, tout en conservant l’éclairage et le bruitage.
Un schéma simple
Le montage est alimenté directement depuis le feeder DCC.
Le pont redresseur est constitué de diodes rapides.
Le condensateur chimique n’a pas besoin d’être de forte valeur, car le signal DCC est rectangulaire.
Un régulateur 7805 fournit le 5V pour le PIC.
Le condensateur de 1uF est un céramique.
Le L298 étant commandé en permanence (pattes 6 et 11 au +5V), il n’est pas nécessaire de prévoir des diodes de protection sur les sorties.
Le programme
Le PIC commande simultanément les deux sorties du L298.
Le signal est conforme à la norme S9.2 de la NMRA (février 2010), notamment le paragraphe B: Digital Decoder Broadcast Stop Packets For All Decoders.
Cliquez ici pour télécharger le programme source.asm
Cliquez ici pour télécharger le programme assemblé.hex
Variante
Deux améliorations ont été apportées ici, par rapport au schéma précédent :
Choix entre l’arrêt brutal ou l’arrêt progressif :
Conformément à la norme S9.1 de la NMRA (janvier 2006), paragraphe B: Digital Decoder Broadcast Stop Packets For All Decoders , alinéa 3.
Le choix se fait par un cavalier sur la borne GP3 du PIC.
Disjonction en cas de sur-intensité :
Le courant est mesuré à travers la résistance de 0,33 ohms aux bornes 1 et 15 du L298N. La chute de tension aux bornes de cette résistance est limitée par une diode.
Cette chute de tension est mesurée par le convertisseur analogique-numérique du PIC 12F675 (patte AN3).
Elle est mesurée deux fois pendant chaque bit 0: une fois durant chacune des alternances du signal (voir le listing du programme).
En cas de sur-intensité, le circuit est mis en mode flottant pendant une durée de 5 secondes. Pendant ce temps l’information est remontée au Stamp qui gère l’ensemble, à travers l’opto-coupleur sur patte GP5. En l’absence de Stamp, cet opto-coupleur peut être remplacé par une simple LED de signalisation.
Cliquez ici pour télécharger le programme source.asm
Cliquez ici pour télécharger le programme assemblé.hex
Ce montage n’étant qu’une partie d’un ensemble plus complexe, nous ne pouvons proposer de circuit imprimé pour sa réalisation.
:020000040000FA
:1000000085018316803081009501FC308500FF2337
:1000100090008312073099009F0199018E018F0192
:10002000900181018B01013085001030A000322049
:10003000A00B17284320A101272043205030A10006
:10004000272043205030A1002720322015280830D7
:10005000A000A10D031C2E2832202F284320A00B26
:10006000292808000B1D32280000E63081000B1102
:10007000013085000B1D3A280000E63081000B118D
:100080000230850008000B1D4328C83081000B1189
:10009000013085000B1D4A28C83081000B11023049
:0400A00085000800CF
:02400E00C43FAD
:104210004700E9006E00E9007200610074002E00A2
:1042200066007200650069006E006100670065004D
:10423000330030002F00310031002F0030003800F3
:00000001FF
; générateur de freinage
; référence: NMRA standard S9.1 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-00000000-0-01010000-0-01010000-1
; octet1 = 00000000 -> diffusion générale
; octet2 = 01DC000S: D=direction, C=1 -> ignorer D, S=0 -> ralentissement progressif
; octet3 = octet2 puisque octet1 = 0 (XOR…)
;==========================================================================
variable mypic = 675 ; utilisé dans MyMacros.inc
LIST P=PIC12F675
#INCLUDE <P12F675.INC>
__CONFIG _BODEN_ON & _CP_OFF & _PWRTE_ON & _WDT_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT ; 12F675 (MCLRE!) OK
;————————————————————————— alias
#define duree0 d’200′ ; 200=256-((116-4)/2) (4 instructions pour rechargement timer)
#define duree1 d’230′ ; 229=256-((58-4)/2)… ajusté par nop.
; #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’00000001′ ; GP0=1 GP1=0 (FCOM)
#define EtatB b’00000010′ ; GP0=0 GP1=1 (FCOM)
;———————————————————————— variables
cblock 0x20
Compteur ;compteur de bits
Octet ;octet à envoyer
endc
;————————————————————————— EEPROM
org 0x2108
de « Générat.freinage30/11/08 »
;————————————————————————— macros
;pas ici
;**********************************************************************************
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’11111100′ ; GP0 et GP1 en sortie, les autres en entrée (FCOM)
movwf TRISIO
; 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 ADC
clrf ANSEL
clrf VRCON
; 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
;*********************************************************************************
; TESTS DE CALIBRATION avec oscillo ou fréquencemètre
; 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-01010000-0-01010000-1
Paquet:
; préambule: 16×1
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
movlw b’01010000′
movwf Octet
call EnvoiOctet
; start bit: 0
call Bit0
; octet 3: 01010000
movlw b’01010000′
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
nop
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
nop
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. Même que précédemment sauf durée.
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
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
return ; retour avant la fin du bit pour préparer le bit suivant
;*********************************************************************************
end
;=================================================================================
; 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 <P12F675.INC>
__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: 16×1
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
;=================================================================================
:020000040000FA
:1000000085018316803081009501D83085009901E3
:1000100058309F00FF2390008312073099008E0113
:100020008F01900181018B0105308500851610300C
:10003000A0003820A00B19284720A1012D2047201F
:100040005030851D5130A1002D2047205030851D96
:100050005130A1002D20382017280830A000A10D14
:10006000031C3428382035284720A00B2F280800EF
:100070000B1D3828E63081000B11053085000B1D63
:100080003F28E63081000B110630850008000B1D6B
:100090004728C93081000B11053085000D309F00C5
:1000A0000630A200A20B52289F149F185528193021
:1000B00003101E02031872280B1D5C28C930810032
:1000C0000B11063085000D309F000630A200A20BF8
:1000D00067289F149F186A28193003101E020318FE
:1000E00072280800851200308500353090000A30F3
:1000F000A2008E018F010C100C1C7C28A20B792809
:0C0100008E018F0190013430851608003C
:02400E00C43FAD
:10421000470065006E0065007200610074002E00AA
:1042200066007200650069006E006100670065004D
:10423000310035002F00300036002F0030003900EB
:1042400076006500720073002E002000340020000C
:104250007200650067006C006100670065003A004D
:0E42600031002C0035004100200035007300B5
:00000001FF
0 commentaires