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 Nosave           'Register werden manuell in der ISR gesichert
'-------------------------------------------------------------------------------------------------------------
'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 = 256 - Berechnung_1     'Servoausgabe_ zum direkten Laden in TCNT0 vorbereiten (Cmd Load umgangen)
Servoausgabe_2 = 256 - Berechnung_2     'Servoausgabe_ zum direkten Laden in TCNT0 vorbereiten (Cmd Load umgangen)
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
 $asm
   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
   lds r17 , {kanal}                    'hole Kanalnummer
   cpi r17 , 1                          'check Kanal und ...
   brne LABEL_KANAL_2                   '... "wenn nicht gleich" verzweige zum nächsten Kanal
   sbic porta , 0                       'Skip next instr. wenn PORTA.0 = 0 ist
   rjmp label_1                         'Springe zum LOW-setzen des Servosignals
   lds r18 , {Servoausgabe_1}           'Hole aufbereiteten Pulslängenwert für Timer0
   Out Tcnt0 , R18                      'Setze Timer0 mit Pulslängenwert
   sbi porta , 0                        'Setze Servosignal HIGH
   rjmp Ende_isr                        'Springe zum Ende der ISR
  Label_1:
   cbi porta , 0                        'Setze Servosignal nach LOW
   inc r17                              'Erhöhe Kanalnummer
   sts {kanal} , r17                    'Sichere Kanalnummer
'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
  Label_kanal_2:                        'Bearbeitung von Kanal 2
   cpi r17 , 2                          'check Kanal und ...
   brne LABEL_KANAL_3                   '... "wenn nicht gleich" verzweige zum nächsten Kanal
   sbic porta , 1                       'Skip next instr. wenn PORTA.1 = 0 ist
   rjmp label_2                         'Springe zum LOW-setzen des Servosignals
   lds r18 , {Servoausgabe_2}           'Hole aufbereiteten Pulslängenwert für Timer0
   Out Tcnt0 , R18                      'Setze Timer0 mit Pulslängenwert
   sbi porta , 1                        'Setze Servosignal HIGH
   rjmp Ende_isr                        'Springe zum Ende der ISR
  Label_2:
   cbi porta , 1                        'Setze Servosignal nach LOW
   inc r17                              'Erhöhe Kanalnummer
   sts {kanal} , r17                    'Sichere Kanalnummer
'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
  Label_kanal_3:                        'Bearbeitung von Kanal 3
   cpi r17 , 3                          'check Kanal und ...
   brne LABEL_KANAL_4                   '... "wenn nicht gleich" verzweige zum nächsten Kanal
   sbic porta , 2                       'Skip next instr. wenn PORTA.2 = 0 ist
   rjmp label_3                         'Springe zum LOW-setzen des Servosignals
   lds r18 , {Servoausgabe_3}           'Hole aufbereiteten Pulslängenwert für Timer0
   Out Tcnt0 , R18                      'Setze Timer0 mit Pulslängenwert
   sbi porta , 2                        'Setze Servosignal HIGH
   rjmp Ende_isr                        'Springe zum Ende der ISR
  Label_3:
   cbi porta , 2                        'Setze Servosignal nach LOW
   inc r17                              'Erhöhe Kanalnummer
   sts {kanal} , r17                    'Sichere Kanalnummer
'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
  Label_kanal_4:                        'Bearbeitung von Kanal 4
   cpi r17 , 4                          'check Kanal und ...
   brne LABEL_KANAL_5                   '... "wenn nicht gleich" verzweige zum nächsten Kanal
   sbic porta , 3                       'Skip next instr. wenn PORTA.3 = 0 ist
   rjmp label_4                         'Springe zum LOW-setzen des Servosignals
   lds r18 , {Servoausgabe_4}           'Hole aufbereiteten Pulslängenwert für Timer0
   Out Tcnt0 , R18                      'Setze Timer0 mit Pulslängenwert
   sbi porta , 3                        'Setze Servosignal HIGH
   rjmp Ende_isr                        'Springe zum Ende der ISR
  Label_4:
   cbi porta , 3                        'Setze Servosignal nach LOW
   inc r17                              'Erhöhe Kanalnummer
   sts {kanal} , r17                    'Sichere Kanalnummer
'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
  Label_kanal_5:                        'Bearbeitung von Kanal 5
   cpi r17 , 5                          'check Kanal und ...
   brne Ende_isr                        '... "wenn nicht gleich" verzweige zum Ende der ISR
   clr r18                              'Setze r18 auf 0
   Out Tcnt0 , R18                      'Setze Timer0 auf 0
   lds r18 , {pausen_variable}          'Hole Pausenvariable
   cpi r18 , 7                          'Vergleiche mit 7
   brlo label_incr_pause                'Ist Pausenvariable (r18) kleiner 7 verzweige
   clr r18                              'Setze r18 auf 0
   sts {pausen_variable} , r18          'Setze Pausenvariable auf 0
   ldi r17 , 1                          'Setze r17 auf 1
   sts {kanal} , r17                    'Setze Kanal auf 1 (Speichere r17 nach Kanal)
   rjmp ende_isr                        'Springe
  Label_incr_pause:
   inc r18                              'Erhöhe r18 um 1
   sts {pausen_variable} , r18          'Speichere r18 nach Pausenvariable
  Ende_isr:
   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
 $end Asm
Return
 
						
Lesezeichen