; Mit einem PIC Typ 16F88 läst sich dein Problem sicher sehr gut lösen:
; ich habe eine Ansteuerung für Fernsteuerservos damit gemacht:
; Ein Poti (Poti zwischen Vcc und Ground) am ADU-Eingang steuert den Servo in 1024 Schritten.
;
; Hardware Resourcen vom PIC: TIMER 1
; COMPARE 1
; Interrupt COMPARE 1
;
; Kurzbeschreibung: Timer 1 zählt kontinuierlich von 0..65535. Das Compare
; Register wird mit dem entsprechenden Zählerstand geladen. Wenn Timer
; und Compare Register identisch sind, wird ein Interrupt ausgelöst.
; Die Interruptroutine "addiert" zum Compare Wert die neue gewünschte
; Pulslänge und setzt die neue Pegeländerung für das Portbit, welche nach
; Ablauf der neuen Zeit erfolgen soll.
;
; Vergleichswert für das Compare Register = Quarzfrequenz / 4 * Pulslänge
; Bei einem Quarz von 8Mhz ergeben sich folgende Werte:
; 2000000 * 0,0010 sek = 2000 counts für 1,0ms links
; 2000000 * 0,0015 sek = 3000 counts für 1,5ms mitte
; 2000000 * 0,0020 sek = 4000 counts für 2,0ms rechts
;
; deltacount = maxtime-mintime ==> 4000 - 2000 = 2000
; diviert durch Adu Auflösung ==> 2000 / 1024 = 2 entspricht 10 Bit ADU = 1024 Schritte
;
; Vergleichswert = Aducount * 2 + 2000
; 0 * 2 + 2000 = 2000 ==> 0,0010000000000 Sek
; 512 * 2 + 2000 = 3024 ==> 0,0015000000000 Sek
; 1023 * 2 + 2000 = 4046 ==> 0,0019990234375 Sek
;
; den ganzen Code will ich jetzt nicht hier reinstellen, aber vielleicht die Initialisierung:
Code:
; Die Vergleichseinheit initialisieren.
; Wir müssen zunächst sicherstellen, das der Zählerstand vom Timer nicht mit dem Vergleichswert
; übereinstimmt. Da der Timer noch nicht gestartet wurde, sollte er auf 0 stehen.
; Doch man staune :
; also erstmal initialiseren
clrf TMR1H ;
clrf TMR1L ; ist nach Reset undefiniert
; nun setzen wir unseren Vergleichswert auf Maximum.
movlw 0xFF ; lade den Maximalen Vergleichswert 0xFFFF
movwf CCPR1H
movwf CCPR1L
; jetzt stellen wir die Vergleichseinheit so ein, das bei Nichtübereinstimmung der
; Portpin LOW sein soll und bei Übereinstimmung auf High gehen soll.
movlw B'00001000' ; init port to low, on match set to high
movwf CCP1CON
; nun steht der Pegel des Portpin ersteinmal richtig, da Zählerstand und Vergleichswert
; nicht identisch sind.
; nun stellen wir die Vergleichseinheit so ein, das bei Übereinstimmung der Pegel
; der Portpins nicht verändert wird, aber ein Interrupt generiert wird.
movlw B'00001010' ; erzeuge Interrupt wenn Zählerstand (Timer1) und Vergleichswert
movwf CCP1CON ; identisch sind, aber ändere nicht den Level des Portpins
bcf PORTB,3 ; Das Bit 3 im Output Latch des Ports wird auf LOW gesetzt,
; damit beim Umschalten von input auf output der Pegel
; sofort LOW ist. Zudem sollte ein Pulldown an den Portpin gelegt
; werden, da der Pin nach einem Reset floatet, wegen input
movlw B'00000101' ; internal Clock 1:1 Fosc/4
movwf T1CON
bcf PIR1,CCP1IF ; lösche Compare 1 Interrupt Flag
bsf STATUS,RP0 ; RAM BANK 1 wählen
bcf TRISB,3 ; nun das Bit im Richtungsregister auf Output setzen.
bsf PIE1,CCP1IE ; Compare 1 Interrupt einschalten
; der erste Interrupt tritt nach ca. 32,78 ms auf, da wir im
; Vergleichsregister 0xFFFF haben. Er verändert aber nicht den Level
; des Portpins. Es wird dann die TABLE in einer Schleife abgearbeitet.
clrf STATUS ; RAM BANK 0 wählen
; bsf T1CON,TMR1ON ; starte Timer 1
; init Timer 0
BANKSEL OPTION_REG
bcf OPTION_REG,T0CS ; timer 0 internal clock
bcf OPTION_REG,PSA ; prescale to Timer 0
bsf OPTION_REG,PS0
bsf OPTION_REG,PS1
bsf OPTION_REG,PS2
clrf STATUS
; bcf INTCON,TMR0IF ; clear Timer 0 Interrupt Flag
clrf TMR0
bsf INTCON,TMR0IE ; enable Timer 0 Interrupt
bsf INTCON,PEIE ; enable Peripheral Interrupts
bsf INTCON,GIE ; enable Global Interrupts
;
Dein Aktuatorwert könnten die unteren 8 Bits des 10 Bit ADU -Wertes sein.
Ich denke, das ist ein gute Grundlage...
mfg. Siro
Lesezeichen