c - Arduino 汇编程序编程 : Nothing happens

标签 c assembly arduino avr-gcc

您好 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;
}

编译器的 asm 转储结果为(缩短),

ldi r24,lo8(-1)  ;  tmp44,
out 0x4,r24  ;  MEM[(volatile uint8_t *)36B], tmp44
out 0x5,r24  ;  MEM[(volatile uint8_t *)37B], tmp44

它工作并激活 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

编译器转储结果(缩短),

ldi r24, 0xFF
out ((0x04) + 0x20), r24
out ((0x05) + 0x20), r24

什么可以解释为什么什么都没有发生。

此外这里还有 C version 的 makefile和 Assembler version

感谢您的帮助!

编辑:这也是 C version 的完整汇编转储文件。和 Assembler version

编辑 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

(抱歉格式化) 知道这个错误是从哪里来的吗?

最佳答案

您应该使用辅助宏 _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

或者,您可以切换到内存映射访问:

#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

关于c - Arduino 汇编程序编程 : Nothing happens,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14464713/

相关文章:

c - 在前台执行

c - *nix 中程序的默认语言环境是 "posix"吗?

这可以原子执行吗?

c - x86 - 使用内联汇编设置位

c++ - 如何创建一个空的全局类并在启动时实例化它?

javascript - 我的混合应用程序在检查包含字符串的 li 元素时不会更改页面

arduino - ESP32 Arduino-ide如何获取唯一id

c - 仅在某些条件下插入 fscanf

assembly - x86 汇编中断服务例程可以调用另一个中断吗?

c - 测试我的程序是否从 bash/ksh/csh 命令行执行