如何阅读atmega 32签名行?

时间:2012-09-10 11:38:29

标签: avr avr-gcc atmega avr-studio5

我尝试用boot_signature_byte_get(0);读取atmega32的签名行但是我得到了这个错误:'SIGRD' undeclared (first use in this function)似乎是因为我们只能读取SPMCR中具有SIGRD位的AVR的签名(我想!) 这是正确的吗?那么我怎样才能以另一种方式阅读签名行呢?

4 个答案:

答案 0 :(得分:2)

早在2007年,任何标题中都没有函数读取签名字节,然后在同一年推出。但看起来,它仍然存在一些问题。

数据表说:

All Atmel microcontrollers have a three-byte signature code which identifies the device.
This code can be read in both serial and parallel mode, also when the device is locked.
The three bytes reside in a separate address space.

意味着ATMEGA32具有对该字节的读访问权。同样在数据表中,它指定了如何读取该字节。在大多数MCU中,它的读取方式相同,但由于某些原因,某些头文件中缺少SIGRD定义编号,包括ATMEGA32。

但是,作为一种解决方法,我们可以手动定义SIGRD。我们必须知道它的价值。当我在搜索此定义的头文件中执行一些findstr(或grep)时,一致地将其值设为5.

所以,解决方法是:

#define SIGRD 5
#include <avr/boot.h>

我成功地编译了这个,但我刚刚尝试在模拟软件上测试程序,因为我现在没有ATMEGA32。它返回一个字节,所以现在由你来知道这是否是正确的字节...

关于你所说的SPMCR事情,似乎签名行在另一个地址空间(根据我的理解,我不知道这是否正确,我无法确认),以及获得它的方法,是使用一些指令,类似于我们将一些程序上传到MCU。

答案 1 :(得分:2)

我想提高一点并说明Flávio的答案,因为我今晚遇到了同样的问题。

  

那么我怎么能以另一种方式阅读签名行呢?

Flávio的解决方法做得很好:

#define SIGRD 5
#include <avr/boot.h>

void read_signature_row(uint8_t sr[3])
{
  sr[0] = boot_signature_byte_get(0x0000);
  sr[1] = boot_signature_byte_get(0x0002);
  sr[2] = boot_signature_byte_get(0x0004);
}

void setup()
{
  Serial.begin(9600);
  delay(100);

  uint8_t sr[3] = {0xcc, 0xcc, 0xcc};
  read_signature_row(sr);

  char buff[100];
  snprintf(buff, sizeof buff, "Device signature: %02X %02X %02X", sr[0], sr[1], sr[2]);
  Serial.println(buff);
}

void loop()
{}

我没有ATmega32,虽然这种方法为我的ATmega328P(1E 95 0F)和ATmega168PA(1E 94 0B)检索了正确的签名。

  

似乎这是因为我们只能在SPMCR中使用具有SIGRD位的AVR读取签名(我想!)。   这是对的吗?

不,它实际上在调用LPM之前将SIGRD设置为SPMCR,如avr/boot.h所示:

#define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD))
#define boot_signature_byte_get(addr) \
(__extension__({                      \
      uint8_t __result;                         \
      __asm__ __volatile__                      \
      (                                         \
        "sts %1, %2\n\t"                        \
        "lpm %0, Z" "\n\t"                      \
        : "=r" (__result)                       \
        : "i" (_SFR_MEM_ADDR(__SPM_REG)),       \
          "r" ((uint8_t)(__BOOT_SIGROW_READ)),  \
          "z" ((uint16_t)(addr))                \
      );                                        \
      __result;                                 \
}))

答案 2 :(得分:0)

我认为atmega32不支持读取用户程序中的签名字节。

atmega32 数据表显示此设备在其寄存器SPMCR中没有名为SIGRD 的位,此寄存器的第五位保留并标记为只读。

atmega640 / 1280/2560 处理器具有类似的寄存器,名为 spmcSr ,其位SIGRD(位5)< / strong>即可。但数据表解释说不应使用此位,因为此操作保留供将来使用(尽管如此,解释了签名的过程)。

您的编译器正常工作,因为atmega32没有此SIGRD位。

答案 3 :(得分:0)

存在SIGRD,可以在 ATmega164A / 164PA / 324A / 324PA / 644A / 644PA / 1284 / 1284P 处理器中使用。 “保留供将来使用”标记仅适用于SPM指令,而不是SPMCSR的最低5位,请参见第285页,第26.9.1节。