Esta es la solución más válida que encomtrarás dar, sin embargo obsérvala pausadamente y analiza si se puede adaptar a tu trabajo.
Solución:
Si desea hacerlo sin incluir una biblioteca completa o usar define, puede usar un sencillo plantilla recursiva:
//By Christopher Andrews, released under MIT licence.
template< unsigned N > struct Nops
static void generate() __attribute__((always_inline))
__asm__ volatile ("nop");
Nops< N - 1 >::generate();
;
template<> struct Nops<0> static inline void generate() ;
void setup()
Nops<10>::generate();
void loop()
Esto generará el número exacto de nop requeridos.
0000010a configuración:
10a: 00 00 nop
10c: 00 00 nop
10e: 00 00 nop
110: 00 00 nop
112: 00 00 nop
114: 00 00 nop
116: 00 00 nop
118: 00 00 nop
11a: 00 00 nop
11c: 00 00 no
11e: 08 95 ret
He usado este método en un controlador TFT para Arduino.
EDITAR:
Hay otra manera de hacer esto fácilmente en un AVR compilado con avr-gcc. Supongo que esto puede no estar disponible en cadenas de herramientas más antiguas.
Con el fin de retrasar la ejecución de un número específico de ciclos, GCC implementa
void __builtin_avr_delay_cycles (unsigned long ticks)
ticks es el número de ticks para retrasar la ejecución. Tenga en cuenta que esta función integrada no tiene en cuenta el efecto de las interrupciones que podrían aumentar el tiempo de retraso. ticks debe ser una constante entera de tiempo de compilación; no se admiten retrasos con un número variable de ciclos
Desde aquí: https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/AVR-Built_002din-Functions.html
El siguiente código funciona con GNU C,
#define NOP __asm__("nop")
#define ten(a) a;a;a;a;a;a;a;a;a;a
#define handred(a) ten(ten(a))
int
main()
handred(NOP);
return 0;
Compilar y depurar:
[email protected]:~/debug$ gcc -g -o debug_NOP debug_NOP.c
[email protected]:~/debug$ gdb -q --nh debug_NOP
Reading symbols from debug_NOP...done.
(gdb) set disassembly-flavor intel
(gdb) start
Temporary breakpoint 1 at 0x664: file debug_NOP.c, line 10.
Starting program: /home/code/debug/debug_NOP
Temporary breakpoint 1, main () at debug_NOP.c:10
10 handred(NOP);
(gdb) disassemble
Dump of assembler code for function main:
0x0000555555554660 <+0>: push rbp
0x0000555555554661 <+1>: mov rbp,rsp
=> 0x0000555555554664 <+4>: nop
0x0000555555554665 <+5>: nop
0x0000555555554666 <+6>: nop
0x0000555555554667 <+7>: nop
0x0000555555554668 <+8>: nop
0x0000555555554669 <+9>: nop
....
0x00005555555546c6 <+102>: nop
0x00005555555546c7 <+103>: nop
0x00005555555546c8 <+104>: mov eax,0x0
0x00005555555546cd <+109>: pop rbp
0x00005555555546ce <+110>: ret
End of assembler dump.
No se te olvide comunicar esta división si lograste el éxito.