PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bascom AVR r6 CPU-Registerbits sparen Interruptzyklen in Bascom



Searcher
14.10.2020, 13:40
Hallo,

benutzt man Interrupt-Service-Routinen in Bascom, werden bei Aufruf der ISR fast alle CPU-Register gesichert. Abhängig von der ISR ist das aber oft nicht notwendig und man kann die ISR schneller machen, indem man den Parameter "nosave" bei der "ON interrupt" Anweisung verwendet. Der Compiler sichert dann keine Register was PUSH/POP Befehle spart aber man muß die in der ISR verwendeten Register selbst händisch sichern.

Um die ISR möglichst schnell ablauffähig zu bekommen verwende ich dort öfter Assembler, der innerhalb von Bascom Programmen sehr einfach zu verwenden ist. Dabei kommt es vor, daß ich in der ISR Flags abfragen oder setzen muß um zB zu entscheiden, ob der Rückwärtsfahr-Portpin oder der Vorwärtsfahr-Portpin geschaltet werden muß.

Dabei bin ich auf Bit 4, 5, 6 und 7 von Register r6 gestoßen, die man anstelle von Flagvariablen nutzen könnte. Nur die Bits 0..3 werden in der Bascom Hilfe als vom Bascom Compiler verwendet erwähnt. r6 selbst wird bei Aufruf einer ISR weder gesichert noch wiederhergestellt. Ich gehe davon aus, das die 4 oberen Bits in r6 in einem Bascom Programm nicht verwendet/verändert werden. (r6 wird jedoch am Beginn eines Programms vom Compiler mit 0 initialisiert).

Man spart damit Zugriffe auf Flagvariable und auch etwas RAM für die Variable. Nicht viel aber wenn man schon beim Zyklenzählen ist ...

Nachstehend ein Programmfragment, wie so etwas aussehen könnte. Kritik und natürlich Zustimmung erwünscht ;), da ich mir da etwas unsicher bin. Erste einfache Versuche verliefen gut.

Gruß
Searcher



$regfile = "attiny44.dat"
$crystal = 8000000
$hwstack = 36
$swstack = 32
$framesize = 32

Const Forward = 0
Const Backward = 1

Dim Direction As Byte

On Compare0a Isr_pwmpulse_on Nosave 'kein Registersichern bei ISR Aufruf
Enable Compare0a
On Timer0 Isr_pwmpulse_off Nosave 'kein Registersichern bei ISR Aufruf
Enable Timer0
Enable Interrupts

Do
Debounce Portb.1 , 0 , Toggle_direction , Sub
Loop

'Denkbar Ist Also Zb ein Unterprogramm
Toggle_direction:
Disable Interrupts 'Inkonsistenz zwischen SET/CLT und BLD vermeiden
If Direction = Forward Then
!SET 'T-Flag in SREG setzen
!BLD r6 , 5 'T-Flag nach r6 Bit5 sichern
Direction = Backward
Else
!CLT 'T-Flag in SREG löschen
!BLD r6 , 5
Direction = Forward
End If
Enable Interrupts
Return

'In der ISR zB
Isr_pwmpulse_on: 'PWM Portpin abhängig von Fahrtrichtung einschalten
!SBRS r6 , 5 'Check Bit 5 in r6
!sbi porta,1 'Setze Portpin für VorwärtsPWMpuls
!SBRc r6 , 5 'Check Bit 5 in r6
!sbi porta,2 'Setze Portpin für RücwärtsPWMpuls
Return

Isr_pwmpulse_off: 'PWM Pulse ausschalten
!CBI porta,1
!CBI porta,2
return

Moppi
15.10.2020, 07:32
Hallo Searcher,

ja, Assembler, die üblichen Hürden. Man muss eben immer alles im Blick haben. Solange ein Register nicht benutzt wird, kann man es verwenden. Oder man sichert es und stellt es am Schluss wieder her.
Wenn Du Meinungen, in Verbindung mit AVR, suchst, habe ich etwas hier gefunden (https://www.mikrocontroller.net/topic/418835).
Mehr kann ich dazu nicht beitragen, Assembler oder Maschinencode ist schon lang nicht mehr mein Hauptgebiet.

MfG

Searcher
18.10.2020, 10:04
Hallo Moppi,

danke für den Link.

Der Hinweis zu den oberen Bits in r6 ist ziemlich sicher nur für Bascom relevant. Das sollte einen Beitrag liefern um eine ISR mit möglichst wenigen Zyklen ablauffähig zu bekommen falls nötig. Ich fand das erwähnenswert, da ich öfter Bascom und Assembler mixe. Ist in der Bascom IDE so schön einfach.

Ich werde das r6 bei Gelegenheit so verwenden. Falls jemand weiß, ob das zu Fehlern führt; bitte melden.

Gruß
Searcher