Korte delay loop gezocht

Ik wil variabele delays kunnen opgeven,
Dit is in PICBASIC. De Frequentie die ik gebruik is 18.48 MHz,
dus de instructie tijd is 0.2164502 microseconden.
Dit geeft dat delayus niet te gebruiken is.
Nu zoek ik naar delays van 4 - 6 instructies tot 210 instr.
Misschien dat er een ASM guru is die een kortere methode heeft.

Pogingen:

; TEST INSTRUCTION DELAY
SUB:
X = 210 ; 2 instr X = maximaal 210 instr
GoSub Vert ; 1 instr

Vert:
Dec X ;1 instr
If X = 0 Then Return ;4 instr
GoTo Vert ;2 instr

FORNEXT:
For X = 0 To 210 ; 2 instr
Next X ; 5 instr

FORNEXTNEG:
For X = 210 To 0 Step -1
Next X

DECREMENTAL:
X = 210
Instru:
Dec X
If X > 0 Then GoTo Instru

ASSEMBLY

SUB
F1_000064 equ $ ; in [TRAP1848.BAS] X = 210 ; 2 instr X = maximaal 210 instr
Movlw 210
Movwf _X
F1_000065 equ $ ; in [TRAP1848.BAS] GoSub Vert ; 1 instr
Call VERT
VERT
F1_000068 equ $ ; in [TRAP1848.BAS] Dec X ;1 instr
Decf _X,F
F1_000069 equ $ ; in [TRAP1848.BAS] If X = 0 Then Return ;4 instr
Movf _X,F
Btfss STATUS,2
Goto bc@LL2
Return
bc@LL2
F1_000070 equ $ ; in [TRAP1848.BAS] GoTo Vert ;2 instr
Goto VERT
FORNEXT
F1_000074 equ $ ; in [TRAP1848.BAS] For X = 0 To 210 ; 2 instr
Clrf _X
fr@lb4
Movlw 211
Subwf _X,W
Btfsc STATUS,0
Goto nx@lb5
F1_000075 equ $ ; in [TRAP1848.BAS] Next X ; 5 instr
Incf _X,F
Btfss STATUS,2
Goto fr@lb4
nx@lb5
FORNEXTNEG
F1_000078 equ $ ; in [TRAP1848.BAS] For X = 210 To 0 Step -1
Movlw 210
Movwf _X
fr@lb6
F1_000079 equ $ ; in [TRAP1848.BAS] Next X
Movlw 1
Subwf _X,F
Btfsc STATUS,0
Goto fr@lb6
nx@lb7
DECREMENTAL
F1_000082 equ $ ; in [TRAP1848.BAS] X = 210
Movlw 210
Movwf _X
INSTRU
F1_000084 equ $ ; in [TRAP1848.BAS] Dec X
Decf _X,F
F1_000085 equ $ ; in [TRAP1848.BAS] If X > 0 Then GoTo Instru
Movf _X,F
Btfsc STATUS,2
Goto bc@LL8
Goto INSTRU
bc@LL8
F1_EOF equ $ ; TRAP1848.BAS
LIST
END

Guus@Sint-Michielsgestel

Is er geen timer die een interrupt geeft?

Hensz

Golden Member

Als je genoeg programmageheugen hebt, kun je 210 NOPs achter elkaar zetten en op de juiste plek erin springen. Bij de eerste voor de langste delay en bij de laatste voor de kortste. Duurt 1 instructie per keer.

Heel korte vertragingen, 4-8 instructies, moeten eigenlijk wel inline. Anders ben je al meer tijd kwijt aan het in- en uitspringen van een subroutine.

Of je maakt een loopje waarbij je een register aftelt. Hoe hoger de waarde in het register, hoe langer de delay. Dit duurt wel tot 4 instructies/keer. Dit is geschikter voor de wat langere vertragingen, maar dan komt een timer-interrupt ook in beeld.

[Bericht gewijzigd door Hensz op 20 november 2020 14:14:28 (26%)]

Don't Panic!

Houd er wel rekening mee dat het aanroepen van een sub ook 4 instructiecycles kost...

code:


sub:
  nop
  nop
return

is dus 6 cycles lang...
Een interrupt is onbruikbaar voor zulke korte delays: het aanroepen van een interrupt kost normaal al minimaal 16 instructies (call/context save/restore/return)

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

Hoi Arco en Hensz en andere meelezers,
Ik wil op een 16F628 draaien omdat ik er heb liggen.
Inline wil ik niet teveel nops hoeven in te passen,
vandaar dat ik eruit wil springen in subs o.i.d
Nu lijkt het erop dat inline

FORNEXTNEG:
For X = 210 To 0 Step -1
Next X

de kortste ( minste ) instructies eist.

Vraag is : Kan het korter ( efficienter ) want ik wil het delay kunnen varieren van 4-6 , 25, 50 etc tot 210

Guus@Sint-Michielsgestel

Hoe exact moeten ze zijn? Als het maar een paar waardes zijn kun je voor elke waarde ook een aparte sub maken.
Minimale lengte is 8 instructies voor een sub, korter kan niet.

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

Hoi Arco, Is mijn inline oplossing

For X = 210 To 0 Step -1
Next X

korter ?

Guus@Sint-Michielsgestel

Dat is geen inline assembly, maar gewoon picbasic...
En die is veel langer als 210 instructies. Iedere iteratie in de For...Next loop is minstens 3 instructies. (afhankelijk van wat de compiler er van bakt)

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

pic asm code:


movlw .10           ; setup counts
movwf teller ;
call timer

timer decfsz teller ;teller=teller-1
goto timer          ; if teller=not zero
return              ; else

Als 't exacte timing moet zijn, moet je daarin ook de call en return instructies verrekenen/meetellen...

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com
Hensz

Golden Member

Ik denk dat je eerst ff moet kijken hoe je assembly vanuit picbasic aanroept én wat het aan tijd kost. Dat wordt je kortste vertraging, óf het moet mogelijk zijn om werkelijk inline tussen je basic-code assembler te mogen invoegen.

Don't Panic!
buckfast_beekeeper

Golden Member

Ben je niet beter uit met een snellere processor?

@arco hier onder. Uiteraard maar klokken op 18MHz of 80MHz of 160MHz maakt toch een wereld van verschil. Een ESP32 heeft ook een dual core. Wat het weer net wat gemakkelijker kan maken.

[Bericht gewijzigd door buckfast_beekeeper op 21 november 2020 09:34:47 (66%)]

Van Lambiek wordt goede geuze gemaakt.

Zelfs met hogere cycleclock blijven zulke korte delays lastig. (1 instruction cycle op 18.45MHz is 216.45nS)

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

Hoi allemaal,

Heb er de scoop bijgepakt, heb op 20 MHz gedraaid voor het gemak
van tellen van de instructies.

FOR X = 0 to 4
NEXT
delay van 9.4 us
FOR X =4 to 0 step -1
NEXT
delay van 5.4 us

Ben met de laatste nog wat verder gegaan.

X = 1 geeft 2.4 us
X = 2 geeft 3.4 us
X = 3 geeft 4.4 us

conclusie: Verhoging van X geeft 1 us extra delay, oftewel 5 instructies
Dit is dus met een 20 MHz clock, maar voor 18.48MHz
blijven het 5 instructies.
Ik kan geen kortere delay maken dan 2.4us i.e 12 instucties

Als iemand het korter kan, laat dan van je horen

Guus@Sint-Michielsgestel

Ik kan geen kortere delay maken dan 2.4us

Jawel, zoals reeds enkele malen gezegd: gebruik inline assembly. (NOP is 200nS op 20MHz)
Voor exacte timing is een hogere taal niet geschikt, je bent dan afhankelijk van wat de compiler er van bakt...

[Bericht gewijzigd door Arco op 21 november 2020 11:40:27 (28%)]

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

UPDATE:

X = 1, 2, 3 etc
Test:
Dec X
If X > 0 Then GoTo Test

Initieel delay X = 1 1.6 us ( 8 instructies )
X = 2 2.8 us ( + 6 instructies )
X = 3 4.0 us ( + 6 instructies )

Guus@Sint-Michielsgestel
Hensz

Golden Member

Kijk in de PicBasic-handleiding hoe het precies gaat. Het kan en het staat er dus ook echt in.

Don't Panic!

Het lijkt sterk op een tweerichtings eenrichtingsverkeer. Waters zegt wat en negeert de rest. En de rest geeft zinnige tips waar waters niet op reageert.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Hoi REW en de anderen.

Ik ben op zoek naar een zeer korte loop in basic die een delay geeft.
Ik ben me bewust van NOP's . Ik weet niet waar je op duidt.
Geef me alsjeblieft een hint

Guus@Sint-Michielsgestel
Hensz

Golden Member

De hint is: (zeer) kleine vertragingen kunnen niet in PicBasic

Zie verder de handleiding pagina 117:http://ww1.microchip.com/downloads/en/devicedoc/pbp_reference_manual.p…

Wat heb je tegen NOP's?

Don't Panic!

Ik weet dat kleine delays zoals in "DELAYUS 3" niet kloppen omdat de macro missc wel 17 of 18 instructies gebruikt.
Ik heb niets tegen NOP's maar ben bang dat ik in mijn applicatie er zeer veel nops moet tussen proppen .
Ik maak dus eigenlijk zelf een macro. De kortste tot nu toe is dus 1.6 us.
Dus maar 8 instructies.
Zoals al aangegeven is mijn instructie tijd 0.2164502 microseconden.
Dus kan ik ook geen gebruik maken van "DELAYUS"

Guus@Sint-Michielsgestel

Ik heb niets tegen NOP's maar ben bang dat ik in mijn applicatie er zeer veel nops moet tussen proppen .

Ja en wat is het probleem?

Op 20 november 2020 19:19:25 schreef Arco:
Hoe exact moeten ze zijn? Als het maar een paar waardes zijn kun je voor elke waarde ook een aparte sub maken.
Minimale lengte is 8 instructies voor een sub, korter kan niet.

Als je al een macro of iets kan vinden kan het dus ook onmogelijk korter dan 8 instructies zijn. Een aanroep naar een functie of macro kan dus onmogelijk korter dan dat. Dus zelfs als er wel iets zou bestaan dan zou de compiler daar toch ook gewoon NOP inzetten. Dus of je nu zelf NOP zet of de compiler wat is het verschil?

Als je timing dus zo kritisch is dan heb je de verkeerde cpu of een te langzame. Er zijn CPU die veel efficiënter zijn en in minder clock-cycles een instructie kunnen uitvoeren.
Een 10x sneller cpu kan dan waar je nu maar ruimte hebt voor max 4 instructies er 40 uitvoeren en heeft dus ineens veel tijd over. Zelfs om interrupt gestuurd te gaan.

Dan heb je het maximaal haalbare nu wel te pakken.

Misschien kan het nog net in wat kleinere stappen als je een interne timer gebruikt. De timer op kloksnelheid laten lopen, timer voor-laden met een hoog getal bijv. 65534, timer starten en dan wachten op de timer-overflow.

Misschien zou het helpen als je eens uitlegt wat je precies probeert te bereiken. (dan kunnen we misschien een betere oplossing aandragen)
Zomaar overal NOP's tussen proppen om iets werken te krijgen heb ik nog nooit gedaan: er is altijd een betere oplossing...

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

1) omschrijf het probleem dat je hebt. Waarom moet je wachten?
2) Omschrijf waarom je "delayus" niet kan gebruiken. Ik ben gewend dat de compiler regelt dat daar delays uitkomen die zo goed en zo kwaad als dat gaat kloppen. Ook als je klokfrequentie "raar" is.
3) Wait, what? Is het nog steeds zo dat PICs 4 klok cycli nodig hebben voor een instructie? Wat is dat voor jaren-tachtig technologie?

Edit: ondertussen schreef arco deels hetzelfde.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/