c - Precise delays on Arduino using nop assembly? -



c - Precise delays on Arduino using nop assembly? -

i'm looking create short pulse after rising border signal input.

the hard part here command (to high resolution) timing of delay before pulse, , duration of pulse. can command stringing nops myself, hard coding delays, i'm not sure how arbitrary delay, same level of accuracy.

after lot of headache chasing downwards timers, , realizing limited interupt routine entry/exit time, settling @ trying command delay via nops.

i had assumed c switch statement wanted (after compiling, hoping become efficient , alter programme counter right spot), produces odd behavior...

switch(delaytime){ case 10: __asm__ __volatile__("nop"); case 9: __asm__ __volatile__("nop"); case 8: __asm__ __volatile__("nop"); case 7: __asm__ __volatile__("nop"); case 6: __asm__ __volatile__("nop"); case 5: __asm__ __volatile__("nop"); case 4: __asm__ __volatile__("nop"); case 3: __asm__ __volatile__("nop"); case 2: __asm__ __volatile__("nop"); case 1: __asm__ __volatile__("nop"); } portd = 0x10; ...

ideally, run through code compile this: (it's weird psuedocode of c , assembly, still not sure how of in assembly)

0x005 reg1 = 0xff-val1 %(where somehow 0xff known? / found out?) 0x006 reg2 =0x1ff-val2 0x007 ijmp reg1 0x008 nop 0x009 nop 0x00a nop ... 0x0ff mov 0x40, portd % assign value 0x40 static variable "portd" 0x100 ijmp reg2 0x101 nop 0x102 nop 0x103 nop 0x104 nop ... 0x1ff mov 0x00, portd % assign value 0x00 static variable "portd"

i'm overall not sure how find memory location code after / during run time "0xff" , "0x1ff" aspects of programme not bad (it seems it's super unsafe just, assembly of code, , hard code in... i'd rather not that). also, while it's easy flood 200+ nops, how ijmp cmd behave way want to? (i don't know if that's command want)..

i guess in general i'm looking assembly command (that can't seem find) allows me "add n programme counter" , can create sure that command run in assembly @ to the lowest degree n+1 commands of assembly ahead of it, hard coded in.

as side note, of executing within of interrupt routine, don't sense bad playing around pc... also, know kinda bad blocking 500 operations, task @ hand, timing more of import how badly blocks routine.

i'm not familiar avr instruction set, general thought utilize call instruction set programme counter (pc) on stack. utilize pop move pc z register. can add number z register, , utilize ijmp jump resulting address.

so along these lines

delay: phone call delay1 ; force pc onto stack delay1: pop r30 ; pop pc z registers pop r31 add together r30,r0 ; add together amount pc value addc r31,r1 ijmp ; utilize ijmp jump resulting address nop nop nop ...

random thoughts:

on 8mb machines, need 3rd pop remove 3rd byte of pc stack. z 16 bits, hence code must in first 128kb of programme memory. i'm not sure register (r30 or r31) supposed popped first. the value added z must relative delay1 since call going force address of delay1 onto stack. in other words, minimum amount needs added 6, since that's number of instructions delay1 first nop. the minimum delay determined 6 instructions , including ijmp. should increment r1/r0 (reduce number of nops) accordingly.

like said, i'm no expert on avr instruction set, should take general suggestion, , prepared spend time working out particulars. luck!

c assembly arduino arduino-uno

Comments

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -