Analoge Modellbauservos
werden mit Impulsen angesteuert. Die Impulslänge bestimmt
dabei die Sollstellung der Servoachse. Die Pulse sind zwischen 1 ms und
2 ms lang, und werden etwa 50 mal pro Sekunde wiederholt. Eine
Impulslänge von 1,5 ms entspricht der Servomittelstellung.
In einem bestimmten Schiffsmodell war es nötig, den Servo
andersherum einzubauen, als ursprünglich geplant. Dadurch drehte
der Servo jetzt genau in die falsche Richtung. Dieses Problem
lässt sich mit einem Servo-Inverter beheben, der in die Leitung
zwischen Modell-Funkempfänger und Servo eingeschliffen wird. Der
Inverter verändert die Impulsweite so, dass bei minimalem
Eingangsimpuls (vom Empfänger) ein maximaler Ausgangsimpuls (zum
Servo) erzeugt wird, und umgekehrt.
(Normalerweise kann man so ein Problem auch durch die Umprogrammierung der Fernsteuerung beheben, dass war aber aus anderen Gründen nicht erwünscht.)
Ein PIC12F629
mit 8-Pins ist ausreichend. Der Einfachheit halber wird der interne 4-MHz-Oszillator des PIC verwendet. Als Eingangspin für den Puls verwende ich GPIO2 (Pin 5) und als Ausgang GPIO5 (Pin 2). Das Pin GPIO0 (Pin 7) dient dem Anschluss einer Korrekturtaste (nach Vss) zur Nullpunkteinstellung. Das ist auch schon die ganze Schaltung. |
list p=12f629 ;*********************************************************************** ;* Pinbelegung ;* ---------------------------------- ;* GP: 0 < KorrekturTaste ;* 1 < 1,5 ms Taste ;* 2 < Puls-Eingang ;* 3 - ;* 4 > out 4 ;* 5 > Puls-Ausgang ;* ;*********************************************************************** ; ;sprut (zero) Bredendiek 12/2010 ; ; Servo-Inverter mit 12F629 ; ; Prozessor 12F629 ; ; Prozessor-Takt 4 MHz intern ; Zyklus = 1 us ; ; es werden Pulse von 0,5 ms bis zu 2,5 ms akzeptiert (500 .. 2500 Zyklen) ; outPulse = 3 ms - inPuls ; ; ;*********************************************************************** ; Includedatei für den 12F629 einbinden #include <P12f629.INC> ERRORLEVEL -302 ;SUPPRESS BANK SELECTION MESSAGES ; Configuration festlegen: ; Power on Timer, kein Watchdog, int-Oscillator, Brown out 2,1V __CONFIG _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_ON ;*********************************************************************** ; Variablen festlegen 20h ... 5Fh W_save Equ 0x20 ; auch 0xA0 Status_save equ 0x21 ; registers for saving context PCLATH_save equ 0x22 Flags equ 0x23 ; flag bits (see definitions below) counter equ 0x24 ; Misc counter PinL equ 0x25 PoutL equ 0x26 Nullpunkt equ 0x27 ; Flag bits (FLAGS) #define InPulse GPIO, 2 #define OutPulse GPIO, 5 #define KorrekturTaste GPIO, 0 #define MittenTaste GPIO, 1 ;*********************************************************************** ;voreingestellte Daten für den EEPROM ab der Zelle 00h org H'2100' ; Adresse des EEPROM für den Brenner de D'44' ; 44 -> (0) ;*********************************************************************** org 0x00 goto Main ;*********************************************************************** ; Initialisierung ; ;*********************************************************************** Init ; IO-Pins bcf STATUS, RP0 ; Bank 0 clrf GPIO ; aus! movlw 0x07 movwf CMCON ; alle Pins digital (nicht Comp) bsf STATUS, RP0 ; Bank 1 ; nur 12F675 ; CLRF ANSEL ; GP0,1,2,4 von ADC auf digital movlw B'11011111' movwf TRISIO bcf OPTION_REG,7 ; GPPU movlw 0xFF movwf WPU ; pull up ein bcf STATUS, RP0 ; Bank0 ; interner Taktgenerator bsf STATUS, RP0 ; Bank 1 call 0x3FF movwf OSCCAL ; 4-MHz-Kalibrierung bcf STATUS, RP0 ; Bank 0 ; Interrupt bcf INTCON, GIE ; Int deaktiviert clrf counter clrf Flags movlw 0 call EEread movwf Nullpunkt return ;*********************************************************************** ;Main ; ;*********************************************************************** Main call Init ; PIC initialisieren LoopStart ; auf Pulse warten ___XXXXX___ clrf PinL WaitForPulse btfss InPulse goto WaitForPulse ; puls da, nun laenge messen in 10us increments WFP1 nop nop nop nop incf PinL, f BTFSC STATUS, Z GOTO LoopStart ; viel zu lang >2,56 ms WFP2 btfsc InPulse goto WFP1 ; Plausibilitetstest 0,5 ... 2,5 ms movlw D'50' subwf PinL, w ; PinL - 50 so sollte nun C kommen BTFSS STATUS, C GOTO LoopStart ; viel zu kurz < 0,5 ms Taste1 ; Korrekturtaste ?? btfsc KorrekturTaste goto Taste2 ; ok, das soll nun also 1,5 ms sein ; dafuer muss nun Nullpunkt angepasst werden movlw D'150' addwf PinL, w movwf Nullpunkt call EEwrite goto Berechne Taste2 btfsc MittenTaste goto Berechne movlw D'150' movwf PoutL goto PA Berechne ; Pulse berechnen ; outPulse = 3 ms - inPuls ; PoutL = 300 - PinL ; PoutL = 256 +44 - PinL ; PoutL = 44 - PinL movfw PinL subwf Nullpunkt, w movwf PoutL PA ; Pulse ausgeben bsf OutPulse PA1 nop nop nop nop nop nop nop decfsz PoutL, f goto PA1 bcf OutPulse goto LoopStart ;*********************************************************************** ; (w) -> w EEread bsf STATUS, RP0 ;movlw Adresse movwf EEADR bsf EECON1, RD movf EEDATA, w bcf STATUS, RP0 return ;*********************************************************************** ; w -> (0) EEwrite BSF STATUS, RP0 ; EEADR und EEDATA liegen in der Bank 1 MOVWF EEDATA ; Wert aus w wollen wir schreiben MOVLW 0x00 MOVWF EEADR ; Die Zelle 0 soll beschrieben werden BSF EECON1, WREN ; nun ist Schreiben erlaubt BCF INTCON, GIE ; verbieten aller Interrupts ; Die folgenden 5 Zeilen müssen genau so im Code stehen!!! MOVLW 0x55 MOVWF EECON2 ; schreibe 55h nach EECON2 MOVLW 0xAA MOVWF EECON2 ; schreibe AAh nach EECON2 BSF EECON1, WR ; starte den Schreibzyklus ;BSF INTCON, GIE ; Interrupts wieder erlauben bcf STATUS, RP0 return ;*********************************************************************** end ;*********************************************************************** |