Assembly AVR sbi命令-错误:数字必须为正且小于32

Assembly AVR sbi命令-错误:数字必须为正且小于32,assembly,avr,avr-gcc,Assembly,Avr,Avr Gcc,我花了很长时间用完整的GCC工具链(一切都是最新的稳定版本)来建立我的AVR开发系统,我用它解决了大多数问题,只有一个 下面的代码给了我一个错误,我就是不明白。AVR汇编手册指出,sbi指令可以接受0-7作为常量表达式,但它仍然错误。有人能解释一下为什么会这样吗 #ifndef __AVR_ATmega168__ #define __AVR_ATmega168__ #endif #include <avr/io.h> rjmp Init

我花了很长时间用完整的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
\ifndef\uuuAVR\uATMEGA168__
#定义AVR ATmega168__
#恩迪夫
#包括
rjmp初始化
初始化:
ser r16
输出DDRB,r16
输出DDRD,r16
clr r16
出港B,r16
港外,r16
开始:
sbi端口B,0
rjmp启动
正在讨论的行是sbi端口B,0

编译/组装:

avr gcc ledon.S-mmcu=atmega168


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

更新结果表明,您应该:

#包括
sbi\u SFR\u IO\u地址(端口B),0

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

感谢您的帮助,但中将端口B定义为0x05(间接-io.h包括iom168.h,然后包括iomx8.h,它实际定义了端口),因此这也不应该是问题所在。正如一个实验尝试更改:
sbi端口B,0
sbi 5,0
以查看是否出现相同的错误。感谢您的帮助。这让我走上了解决问题的正确道路,如果你有兴趣,请看我对另一个答案的评论。好吧,我会被诅咒的。谢谢你。这让我找到了解决这个恼人问题的方法。唉,即使你们都帮了我的忙,我也不能把两者都标为正确答案。不管怎样,问题是如果不手动将其定义为0x20,AVR libc集合在内部定义了_SFR_偏移量,这导致了上面所示的问题。如果您需要使用头文件,则需要在包含它们之前将其定义为0,以保持兼容。我很确定您不能在任何avr上使用sbi端口号,并且通过更改libc(!),您可能正在使sbi在r6上工作。@Jens-实际上,有问题的头文件中的注释说明,如果您使用的是没有使用偏移量的东西,您应该自己定义_SFR_OFFSET(我的汇编代码没有,我正在使用的书中的任何示例也没有)。因此,除非这本书从根本上是错误的,否则我必须假设您可以sbi一个端口。@Jens:在这644上,我使用的是
PORTD&=~\u BV(PD6)
被翻译成
5e 98 cbi 0x0b,6
,因此有一些AVR,您可以在其上直接
cbi
/
sti
端口。出于某种奇怪的原因,如果我通过gcc使用
-mmcu=atmega164p
运行此命令,我将得到与644相同的机器代码。所以,至少可以说,自动定义为0x20的_SFR_偏移量有点奇怪。@Jens:这就解释了一些事情。:-)什么?您可以直接在168上的端口上操作?
#include <avr/io.h>
sbi  _SFR_IO_ADDR(PORTB), 0