Code:
'===============================================================================
'RC Eingang 1 an Pin 3 (PB1, PCINT9)
'RC Eingang 2 an Pin 6 (PA7, PCINT7)
'RC Eingang 3 an Pin 5 (PB2, INT0)
'Servo 1 an Pin 13 (PA0)
'Servo 2 an Pin 12 (PA1)
'Servo 3 an Pin 11 (PA2)
'Servo 4 an Pin 10 (PA3)
'===============================================================================
$regfile = "attiny84.dat"
$crystal = 8000000 'FuseBit CKDIV8 deaktivieren
$hwstack = 50
$swstack = 50
$framesize = 50
'-------------------------------------------------------------------------------------------------
'Timer und konfigurieren
'-------------------------------------------------------------------------------------------------
Config Timer1 = Timer , Prescale = 8 'Timer für Einlesen RC Signale
Start Timer1
Config Timer0 = Timer , Prescale = 64 'Timer für Servoausgabe, Wert 125 entspricht 1ms, Wert 250 entspricht 2ms
Enable Timer0
On Timer0 Servoausgabe
'-------------------------------------------------------------------------------------------------------------
'Variablen definieren
'-------------------------------------------------------------------------------------------------------------
'Variablen fürs RC Einlesen
Dim Rc_signal_1_start As Word
Dim Rc_signal_2_start As Word
Dim Rc_signal_3_start As Word
Dim Impulslaenge_1 As Word
Dim Impulslaenge_2 As Word
Dim Impulslaenge_3 As Word
'Variablen für Berechnungen
Dim Berechnung_1 As Word
Dim Berechnung_2 As Word
'Variablen für Servoausgabe
Dim Kanal As Byte
Dim Servoausgabe_1 As Byte
Dim Servoausgabe_2 As Byte
Dim Servoausgabe_3 As Byte
Dim Servoausgabe_4 As Byte
Dim Pausen_variable As Byte
'-------------------------------------------------------------------------------------------------
'Einigen Variablen Werte zuweisen
'-------------------------------------------------------------------------------------------------
Kanal = 1
Pausen_variable = 0
'-------------------------------------------------------------------------------------------------------------
'Ein- und Ausgang festlegen
'-------------------------------------------------------------------------------------------------------------
Ddra = &B00001111 'PA0 - PA3 werden Ausgänge
Ddrb = &B00000000 'PortB bleibt Eingang
'-------------------------------------------------------------------------------------------------
'Interrupt-Service-Routinen konfigurieren und freigeben
'-------------------------------------------------------------------------------------------------
'Info:
'Alle Porta Pinchangeinterrupts sind in Bascom "PCINT0" zugeordnet.
'Alle Portb Pinchangeinterrupts sind in Bascom "PCINT1" zugeordnet.
Pcmsk1.pcint9 = 1 'beim Flankenwechsel an PB1/PCINT9 (RC Eingang 1) Pinchangeinterrupt1 auslösen und in die Subroutine springen
Enable Pcint1 'Pinchangeinterrupt1 (1 weil auf PortB) zulassen
On Pcint1 Rc_eingang_1 Nosave 'Register werden manuel in der ISR gesichert
Pcmsk0.pcint7 = 1 'beim Flankenwechsel an PA7/PCINT6 (RC Eingang 2) Pinchangeinterrupt0 auslösen und in die Subroutine springen
Enable Pcint0 'Pinchangeinterrupt0 (0 weil auf PortA) zulassen
On Pcint0 Rc_eingang_2 Nosave 'Register werden manuel in der ISR gesichert
Config Int0 = Change 'beim Flankenwechsel an PB2/INT0 (RC Eingang 3) Int0 auslösen und in die Subroutine springen
Enable Int0
On Int0 Rc_eingang_3 Nosave 'Register werden manuel in der ISR gesichert
Enable Interrupts
'======================================================
'Hauptprogramm
'======================================================
Do
'Umrechnung erstes RC Signal auf 8-Bit
Berechnung_1 = Impulslaenge_1 / 8 'ergibt Werte zwischen 125 und 250
If Berechnung_1 > 255 Then 'zu hohe Werte abfangen
Berechnung_1 = 255
End If
If Berechnung_1 < 120 Then 'zu kleine Werte abfangen
Berechnung_1 = 120
End If
'Umrechnung zweites RC Signal auf 8-Bit
Berechnung_2 = Impulslaenge_2 / 8 'ergibt Werte zwischen 125 und 250
If Berechnung_2 > 255 Then 'zu hohe Werte abfangen
Berechnung_2 = 255
End If
If Berechnung_2 < 120 Then 'zu kleine Werte abfangen
Berechnung_2 = 120
End If
Servoausgabe_1 = Berechnung_1
Servoausgabe_2 = Berechnung_2
Servoausgabe_3 = 190
Servoausgabe_4 = 190
Loop
'======================================================
'ISR
'======================================================
'Rc_eingang_1:
' If Pinb.1 = 1 Then
' Rc_signal_1_start = Timer1
' Else
' Impulslaenge_1 = Timer1 - Rc_signal_1_start
' End If
'Return
Rc_eingang_1:
$asm
sbis pinb , 1 'Skip next Instr if PINBx = 1
rjmp pulslaenge1 'Spring zur Berechnung von Impulslaenge
push r17 'Register auf Stack sichern
in r17 , tcnt1l 'Timer1 low Byte holen
sts {Rc_signal_1_start} , r17 'Speichere Timer1 low Byte nach Rc_signal low Byte
in r17 , tcnt1h 'Timer1 high Byte holen
sts {Rc_signal_1_start} + 1 , r17 'Speichere Timer1 high Byte nach Rc_signal high Byte
pop r17 'Register vom Stack zurückholen
rjmp ende1 'Springe zum Ende
Pulslaenge1:
push r16 'Register auf Stack sichern
in r16,sreg 'Statusregister holen und halten
push r17 'Register auf Stack sichern
push r18 'Register auf Stack sichern
in r17 , tcnt1l 'Timer1 low Byte holen
lds r18 , {Rc_signal_1_start} 'Hole Rc_signal low Byte
Sub R17 , R18 'Subtrahiere Rc_signal low Byte von Timer1 low Byte
sts {Impulslaenge_1} , r17 'Speichere Resultat low Byte nach Impulslaenge low Byte
in r17 , tcnt1h 'Timer1 high Byte holen
lds r18 , {Rc_signal_1_start} + 1 'Hole Rc_signal high Byte
sbc r17 , r18 'Subtrahiere Rc_signal high Byte von Timer1 high Byte
sts {Impulslaenge_1} + 1 , r17 'Speichere Resultat high Byte nach Impulslaenge high Byte
pop r18 'Register vom Stack zurückholen
pop r17 'Register vom Stack zurückholen
Out Sreg , R16 'Statusregister zurückspeichern
pop r16 'Register vom Stack zurückholen
Ende1:
$end Asm
Return
'Rc_eingang_2:
' If Pina.7 = 1 Then
' Rc_signal_2_start = Timer1
' Else
' Impulslaenge_2 = Timer1 - Rc_signal_2_start
' End If
'Return
Rc_eingang_2:
$asm
sbis pinA , 7 'Skip next Instr if PINBx = 1
rjmp pulslaenge2 'Spring zur Berechnung von Impulslaenge
push r17 'Register auf Stack sichern
in r17 , tcnt1l 'Timer1 low Byte holen
sts {Rc_signal_2_start} , r17 'Speichere Timer1 low Byte nach Rc_signal low Byte
in r17 , tcnt1h 'Timer1 high Byte holen
sts {Rc_signal_2_start} + 1 , r17 'Speichere Timer1 high Byte nach Rc_signal high Byte
pop r17 'Register vom Stack zurückholen
rjmp ende2 'Springe zum Ende
Pulslaenge2:
push r16 'Register auf Stack sichern
in r16,sreg 'Statusregister holen und halten
push r17 'Register auf Stack sichern
push r18 'Register auf Stack sichern
in r17 , tcnt1l 'Timer1 low Byte holen
lds r18 , {Rc_signal_2_start} 'Hole Rc_signal low Byte
Sub R17 , R18 'Subtrahiere Rc_signal low Byte von Timer1 low Byte
sts {Impulslaenge_2} , r17 'Speichere Resultat low Byte nach Impulslaenge low Byte
in r17 , tcnt1h 'Timer1 high Byte holen
lds r18 , {Rc_signal_2_start} + 1 'Hole Rc_signal high Byte
sbc r17 , r18 'Subtrahiere Rc_signal high Byte von Timer1 high Byte
sts {Impulslaenge_2} + 1 , r17 'Speichere Resultat high Byte nach Impulslaenge high Byte
pop r18 'Register vom Stack zurückholen
pop r17 'Register vom Stack zurückholen
Out Sreg , R16 'Statusregister zurückspeichern
pop r16 'Register vom Stack zurückholen
Ende2:
$end Asm
Return
'Rc_eingang_3:
' If Pinb.2 = 1 Then
' Rc_signal_3_start = Timer1
' Else
' Impulslaenge_3 = Timer1 - Rc_signal_3_start
' End If
'Return
Rc_eingang_3:
$asm
sbis pinb , 2 'Skip next Instr if PINBx = 1
rjmp pulslaenge3 'Spring zur Berechnung von Impulslaenge
push r17 'Register auf Stack sichern
in r17 , tcnt1l 'Timer1 low Byte holen
sts {Rc_signal_3_start} , r17 'Speichere Timer1 low Byte nach Rc_signal low Byte
in r17 , tcnt1h 'Timer1 high Byte holen
sts {Rc_signal_3_start} + 1 , r17 'Speichere Timer1 high Byte nach Rc_signal high Byte
pop r17 'Register vom Stack zurückholen
rjmp ende3 'Springe zum Ende
Pulslaenge3:
push r16 'Register auf Stack sichern
in r16,sreg 'Statusregister holen und halten
push r17 'Register auf Stack sichern
push r18 'Register auf Stack sichern
in r17 , tcnt1l 'Timer1 low Byte holen
lds r18 , {Rc_signal_3_start} 'Hole Rc_signal low Byte
Sub R17 , R18 'Subtrahiere Rc_signal low Byte von Timer1 low Byte
sts {Impulslaenge_3} , r17 'Speichere Resultat low Byte nach Impulslaenge low Byte
in r17 , tcnt1h 'Timer1 high Byte holen
lds r18 , {Rc_signal_3_start} + 1 'Hole Rc_signal high Byte
sbc r17 , r18 'Subtrahiere Rc_signal high Byte von Timer1 high Byte
sts {Impulslaenge_3} + 1 , r17 'Speichere Resultat high Byte nach Impulslaenge high Byte
pop r18 'Register vom Stack zurückholen
pop r17 'Register vom Stack zurückholen
Out Sreg , R16 'Statusregister zurückspeichern
pop r16 'Register vom Stack zurückholen
Ende3:
$end Asm
Return
Servoausgabe:
If Kanal = 1 Then
If Porta.0 = 0 Then 'wenn der Ausgangspin aus ist
Load Timer0 , Servoausgabe_1 'wird der Timer0 mit dem Wert der Variable "Servoausgabe_1" vorgeladen
Porta.0 = 1 'und der Ausgangspin eingeschaltet
Else 'erst beim nächsten Timer0 Überlauf landen wir hier
Porta.0 = 0 'Ausgangspin wird wieder ausgeschaltet
Incr Kanal 'und der nächsten Kanal bearbeitet
End If
End If
If Kanal = 2 Then
If Porta.1 = 0 Then
Load Timer0 , Servoausgabe_2
Porta.1 = 1
Else
Porta.1 = 0
Incr Kanal
End If
End If
If Kanal = 3 Then
If Porta.2 = 0 Then
Load Timer0 , Servoausgabe_3
Porta.2 = 1
Else
Porta.2 = 0
Incr Kanal
End If
End If
If Kanal = 4 Then
If Porta.3 = 0 Then
Load Timer0 , Servoausgabe_4
Porta.3 = 1
Else
Porta.3 = 0
Incr Kanal
End If
End If
'Pausenauffüllung
If Kanal = 5 Then
Timer0 = 0 '8-Bit Timer auf 0, Überlauf alle 2,048ms
If Pausen_variable < 7 Then '2,048ms * 6 = 12,288ms Pausenfüllzeit
Incr Pausen_variable
Else
Pausen_variable = 0
Kanal = 1
End If
End If
Return
Lesezeichen