【问题标题】:AVR sbi command - Error: number must be positive and less than 32AVR sbi 命令 - 错误:数字必须为正且小于 32
【发布时间】:2010-04-10 09:10:03
【问题描述】:

我花了很长时间使用完整的 GCC 工具链(一切都是最新的当前稳定版本)设置我的 AVR 开发系统,并且我已经解决了大多数问题,但只有一个。

以下代码给了我一个我没有得到的错误。 AVR 汇编手册指出 sbi 指令可以接受 0-7 作为常量表达式,但我仍然出错。谁能解释一下为什么会这样?

  #ifndef __AVR_ATmega168__
      #define __AVR_ATmega168__
  #endif

  #include <avr/io.h>

      rjmp Init

  Init:

      ser r16
      out DDRB, r16
      out DDRD, r16

      clr r16

      out PORTB, r16
      out PORTD, r16

  Start:

      sbi PORTB, 0
      rjmp Start

有问题的行是 sbi PORTB, 0。

编译/组装:

avr-gcc ledon.S -mmcu=atmega168

【问题讨论】:

  • 什么?可以直接在168上的端口上操作吗?

标签: assembly avr avr-gcc


【解决方案1】:

更新原来你应该write your assembly code like this when using avr-libc

#include <avr/io.h>
sbi  _SFR_IO_ADDR(PORTB), 0

[已删除调试提示,没有实际解决方案]

【讨论】:

  • 好吧,我会被诅咒的。感谢那。这使我找到了解决这个烦人问题的方法。唉,即使你们都提供了帮助,我也不能将两者都标记为正确答案。无论如何,问题是 AVR libc 集在内部定义 __SFR_OFFSET 如果您不手动将其定义为 0x20 会导致上面显示的问题。如果您需要使用头文件,则需要在包含它们之前自己将其定义为 0 以保持兼容。
  • 我很确定您不能在任何 avr 上使用 sbi 端口号,并且通过更改 libc (!),您可能会使 sbi 在 r6 上工作。
  • @Jens - 实际上,有问题的头文件中的 cmets 指出,如果您使用的东西不使用偏移量,您应该自己定义 __SFR_OFFSET (好吧,我的汇编代码没有,也没有做我正在工作的书中的任何例子)。所以除非这本书根本上是错误的,否则我必须假设你可以 sbi 一个端口。
  • @Jens:在我正在使用的这台 644 上,PORTD &amp;=~ _BV(PD6); 被翻译成 5e 98 cbi 0x0b, 6,所以有个 AVR,您可以在上面使用 cbi/sti直接一个端口。出于某种奇怪的原因,如果我通过 gcc 使用 -mmcu=atmega164p 运行此命令,我会得到与 644 相同的机器代码。因此,自动定义为 0x20 的 __SFR_OFFSET 至少可以说有点奇怪。
  • @Jens:这解释了一些事情。 :-)
【解决方案2】:

我认为它抱怨的是 PORTB 而不是比特数 (0)。你是如何定义 PORTB 的?它需要在 0..31 范围内。如果您的端口定义在 32..63 范围内,您可能需要从 PORTB 中减去 32?

【讨论】:

  • 感谢您的帮助,但 PORTB 在 中定义(间接 - io.h 包括 iom168.h,然后包括实际定义它的 iomx8.h)为 0x05 所以应该也不是问题。
  • 就像一个实验一样尝试将:sbi PORTB, 0 更改为 sbi 5, 0 看看是否会出现相同的错误。
  • 感谢您的帮助。这让我走上了解决问题的正确轨道,如果您有兴趣,请参阅我对其他答案的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-29
  • 2021-10-25
  • 1970-01-01
  • 2019-08-28
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
相关资源
最近更新 更多