programacion - Programación Arduino Assembler: no pasa nada
programacion arduino pdf (1)
Hola comunidad de StackOverflow,
Estoy intentando programar mi vieja placa Arduino Duemilanove (Atmega 168V-10PU) en ensamblador. Lo intenté varias veces antes, pero cada vez que el código no se ejecutaba. Así que traté de programar un programa de prueba equivalente en C, y funcionó. Aquí está:
// file led.c
#include <avr/io.h>
int main(void)
{
DDRB = 0xFF;
PORTB = 0xFF;
while (1) {
asm("nop/n");
}
return 0;
}
El volcado asm del compilador resulta en (abreviado),
ldi r24,lo8(-1) ; tmp44,
out 0x4,r24 ; MEM[(volatile uint8_t *)36B], tmp44
out 0x5,r24 ; MEM[(volatile uint8_t *)37B], tmp44
que funciona y activa el LED en Arduino Pin 13 (AVR pin PB5).
Pero cuando uso este archivo asm,
// file led.S
#include "avr/io.h"
.global main
main:
ldi r24, 0xFF
out DDRB, r24
out PORTB, r24
end:
jmp end
el volcado del compilador resulta en (abreviado),
ldi r24, 0xFF
out ((0x04) + 0x20), r24
out ((0x05) + 0x20), r24
qué podría explicar por qué no pasa nada
Además, aquí están los makefiles para la versión C y la versión Assembler
¡Gracias por ayudar!
EDITAR: Aquí están también los archivos de volcado del ensamblador completo de la versión C y la versión del ensamblador
EDIT 2: busqué las direcciones de registro en el archivo de inclusión iom168.h, que hace referencia a iomx8.h, donde dice #define PORTB _SFR_IO8 (0x05)
. El compilador sigue la cadena de inclusión
io.h -> iom168.h -> iomx8.h
io.h -> common.h -> sfr_defs.h
En sfr_defs.h está escrito:
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
Algunas líneas más hacia arriba se define el desplazamiento:
#ifndef __SFR_OFFSET
/* Define as 0 before including this file for compatibility with old asm
sources that don''t subtract __SFR_OFFSET from symbolic I/O addresses. */
# if __AVR_ARCH__ >= 100
# define __SFR_OFFSET 0x00
# else
# define __SFR_OFFSET 0x20
# endif
#endif
(Disculpe por el formato) ¿Alguna idea de dónde viene este error?
Debería usar las macros auxiliares _SFR_IO_ADDR()
y _SFR_MEM_ADDR()
para acceder a los SFR usando i / o y las instrucciones de memoria, respectivamente, porque tienen diferentes direcciones en los dos espacios de nombres. El valor predeterminado aparentemente está mapeado en memoria, pero no cuente con él.
Como tal, su código podría verse así:
#include "avr/io.h"
.global main
main:
ldi r24, 0xFF
out _SFR_IO_ADDR(DDRB), r24
out _SFR_IO_ADDR(PORTB), r24
end:
jmp end
O bien, puede cambiar al acceso mapeado en memoria:
#include "avr/io.h"
.global main
main:
ldi r24, 0xFF
sts _SFR_MEM_ADDR(DDRB), r24
sts _SFR_MEM_ADDR(PORTB), r24
end:
jmp end