C Arduino汇编程序编程:什么都没有发生
大家好,我的社区 我正在尝试用汇编语言编程我的旧Arduino Duemilanove板(Atmega 168V-10PU)。我以前试过几次,但每次代码都没有执行。所以我试着用C语言编写一个等价的测试程序,它成功了。这是:C Arduino汇编程序编程:什么都没有发生,c,assembly,arduino,avr-gcc,C,Assembly,Arduino,Avr Gcc,大家好,我的社区 我正在尝试用汇编语言编程我的旧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"); }
// file led.c
#include <avr/io.h>
int main(void)
{
DDRB = 0xFF;
PORTB = 0xFF;
while (1) {
asm("nop\n");
}
return 0;
}
它工作并激活Arduino引脚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
编译器转储会导致(缩短)
什么可以解释为什么什么都没发生
此外,下面是和的makefile
谢谢你的帮助
编辑:这里还有和的完整汇编程序转储文件
编辑2:我在include文件iom168.h中查找了寄存器地址,该文件引用了iomx8.h,其中显示#define PORTB\u SFR\u 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
(很抱歉格式化)
知道这个错误是从哪里来的吗?您应该使用helper宏
\u SFR\u IO\u ADDR()
和\u SFR\u MEM\u ADDR()
分别使用i/o和内存指令访问SFR,因为它们在两个名称空间中有不同的地址。默认值显然是内存映射,但不要指望它
因此,您的代码可能如下所示:
#包括“avr/io.h”
.全球主要
主要内容:
本地设计院r24,0xFF
输出SFR IO地址(DDRB),r24
输出地址(端口B),r24
完:
jmp端
或者,您可以切换到内存映射访问:
#包括“avr/io.h”
.全球主要
主要内容:
本地设计院r24,0xFF
sts-SFR-MEM地址(DDRB),r24
sts-SFR-MEM地址(端口B),r24
完:
jmp端
很明显,DDRB和PORTB在汇编文件中的解析方式不同,因此您可能使用了错误的io.h版本,这些版本可能是定义的?我刚刚在汇编程序源文件的开头添加了#define u SFR _offset0x00。在asm转储中,它现在显示出out((0x04)+0x00)、r24
和out((0x05)+0x00)、r24
,并且工作正常。
#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