Soj*_*aki 3 c assembly arduino avr-gcc
您好StackOverflow社区,
我正在尝试在Assembler中编写我的旧Arduino Duemilanove Board(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;
}
Run Code Online (Sandbox Code Playgroud)
编译器的asm转储导致(缩短),
ldi r24,lo8(-1) ; tmp44,
out 0x4,r24 ; MEM[(volatile uint8_t *)36B], tmp44
out 0x5,r24 ; MEM[(volatile uint8_t *)37B], tmp44
Run Code Online (Sandbox Code Playgroud)
它可以在Arduino Pin 13(AVR引脚PB5)上工作并激活LED.
但是当我使用这个asm文件时,
// file led.S
#include "avr/io.h"
.global main
main:
ldi r24, 0xFF
out DDRB, r24
out PORTB, r24
end:
jmp end
Run Code Online (Sandbox Code Playgroud)
编译器转储导致(缩短),
ldi r24, 0xFF
out ((0x04) + 0x20), r24
out ((0x05) + 0x20), r24
Run Code Online (Sandbox Code Playgroud)
什么可以解释为什么没有发生.
谢谢你的帮助!
编辑2:我在包含文件iom168.h中查找了寄存器地址,该文件引用了iomx8.h #define PORTB _SFR_IO8 (0x05).编译器遵循包含链
io.h -> iom168.h -> iomx8.h
io.h -> common.h -> sfr_defs.h
Run Code Online (Sandbox Code Playgroud)
在sfr_defs.h中写道:
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
Run Code Online (Sandbox Code Playgroud)
向上定义了更多的偏移量:
#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
Run Code Online (Sandbox Code Playgroud)
(抱歉格式化)这个错误来自哪里?
您应该使用辅助宏_SFR_IO_ADDR()并_SFR_MEM_ADDR()分别使用i/o和内存指令访问SFR,因为它们在两个名称空间中具有不同的地址.默认显然是内存映射,但不要指望它.
因此,您的代码可能如下所示:
#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
Run Code Online (Sandbox Code Playgroud)
或者,您可以切换到内存映射访问:
#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
Run Code Online (Sandbox Code Playgroud)