Привет, сообщество StackOverflow,
Я пытаюсь запрограммировать свою старую плату Arduino Duemilanove (Atmega 168V-10PU) на ассемблере. Я пробовал это несколько раз раньше, но каждый раз код не выполнялся. Поэтому я попытался написать эквивалентную тестовую программу на C, и это сработало. Вот:
// file led.c
#include <avr/io.h>
int main(void)
{
DDRB = 0xFF;
PORTB = 0xFF;
while (1) {
asm("nop\n");
}
return 0;
}
Ассемблерный дамп компилятора приводит к (сокращенно),
ldi r24,lo8(-1) ; tmp44,
out 0x4,r24 ; MEM[(volatile uint8_t *)36B], tmp44
out 0x5,r24 ; MEM[(volatile uint8_t *)37B], tmp44
который работает и активирует светодиод на выводе 13 Arduino (вывод AVR PB5).
Но когда я использую этот ассемблерный файл,
// file led.S
#include "avr/io.h"
.global main
main:
ldi r24, 0xFF
out DDRB, r24
out PORTB, r24
end:
jmp end
дамп компилятора приводит к (сокращенному),
ldi r24, 0xFF
out ((0x04) + 0x20), r24
out ((0x05) + 0x20), r24
что может объяснить, почему ничего не происходит.
Кроме того, здесь находятся make-файлы для C-версии и Ассемблёрная версия
Спасибо за помощь!
РЕДАКТИРОВАТЬ: Вот также полные файлы дампа ассемблера версии C и Ассемблерная версия
РЕДАКТИРОВАТЬ 2: я просмотрел адреса регистров во включаемом файле iom168.h, который ссылается на iomx8.h, где указано #define PORTB _SFR_IO8 (0x05)
. Компилятор следует цепочке включения
io.h -> iom168.h -> iomx8.h
io.h -> common.h -> sfr_defs.h
В sfr_defs.h написано:
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
Еще несколькими строками вверх определяется смещение:
#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
(Извините за форматирование) Любая идея, откуда эта ошибка?
out ((0x04) + 0x00), r24
иout ((0x05) + 0x00), r24
и работает. - person Sojaki   schedule 23.01.2013