【问题标题】:Can't assign value of 120 to static const unsigned char or value of 200 to const static unsigned int无法将 120 的值分配给 static const unsigned char 或将 200 的值分配给 const static unsigned int
【发布时间】:2015-04-01 04:10:29
【问题描述】:

我对 Arduino 之外的嵌入式 c++ 相当陌生,但到目前为止,我已经能够解决我遇到的所有问题,除了这个问题。 我在 Atmega 1284P 上使用 Atmel Studio,用 C++ 编码。我正在使用以下变量与 TTL 串行输入进行比较(串行输入在 0 到 255 之间以单个无符号字符字节传输):

const unsigned char STEER_DEADZONE_MIN = 120;
const unsigned char STEER_DEADZONE_MAX = 120;
const unsigned char THROTTLE_DEADZONE_MIN = 136;
const unsigned char THROTTLE_DEADZONE_MAX = 136;

当我尝试使用 STEER_DEADZONE_MIN 或任何列出的无符号字符时,它们显示为 12。我已确认我的程序使用 Atmel Studio 模拟器监视工具并将其打印到 LCD 上的显示为 12嵌入式设备。实际上,我已经为 unsigned char 提出了一个修复方法,即删除 const,但我有 const 是有原因的,因为我不希望更改值。声明为:

unsigned char TEST = 120;
unsigned char TEST1 = 136;

这会导致该值正确地为 120 或 136,但随后可能会意外更改该值。似乎如果我在主循环中执行分配:

const unsigned char TEST = 120;

这也修复了该值,但引入了其他问题,此后我的任何函数都无法访问它。

当涉及到 const unsigned int 时,我也遇到了一个看似相关的问题。当我在主循环之外声明它时:

const unsigned int SERVO_ESC_SPEED = 200;
const unsigned int SERVO_STEER_SPEED = 200;
const unsigned int SERVO_DISTANCE_SENSOR_SPEED = 200;

该值为 37900,但是,我尝试在我的主循环中将其声明为:

const unsigned int TEST = 200;

这更正了该值,但如上所述,由于我的函数不再可以访问它,因此无济于事。在这种情况下,在主循环之外删除 const 并不能修复该值。在这一点上,我真的很茫然。在这一点上,我唯一能想到的尝试的另一件事是创建一个包含所有这些 const 变量的设置类,看看是否可以更正这些值。我将在接下来尝试并更新结果。

【问题讨论】:

  • 也许您的代码中某处存在一个错误,它破坏了存储const 变量的区域;或者,链接器或程序加载器可能有问题,并且它没有首先正确设置const 变量区域。尝试制作一个最小的程序来测试,即一个只包含main()(或任何你的入口点)和一个const全局变量以及检查该变量值所需的绝对最少代码量。
  • 好的,所以我能够通过使用 atmega1284P 模板创建一个新的 Atmel Studio 项目来确认同样的问题,然后构建一个只定义了这些变量和一个 main() 的完全准系统 main.cpp只将它们直接打印到 LCD 上。在这一点上,我只能假设这是 avr-gcc、atmel studio 或工具链/链接器模板中的错误。无论如何,我找到了一种解决方法,方法是在 Settings.h 文件中构建一个 Settings 类并在该类中声明所有这些常量。
  • 我不会相信任何进一步的代码,只要你描述的一些基本问题的解决方法是必需的。
  • 你是对的。这更像是一个测试和一个临时的解决方法。在通宵工作之后,我终于找到了解决方法而不是解决方法。我的电路板制造商提供的模板启用了以下编译器优化:fdata-sections 和 ffunctions-sections。关闭这两个优化,完全解决了这个问题。 fdata-sections 导致了无符号字符的问题,而 ffunctions-sections 导致了无符号整数的问题。我现在已经将我的常量移回了所属的位置,并且一切正常。
  • 您可能应该进一步调查。看看您是否可以查看链接器映射以查看这些变量的位置(通常它们位于 .text 或 .rodata 中)。您的程序代码通常在 .text 中。也许您可以尝试检查是否正在加载 .rodata(如果这是这些常量所在的位置);或者可能将常量放入 .text 而不是 .rodata 。

标签: c++ constants avr-gcc atmelstudio


【解决方案1】:

把它们也变成静态的怎么样?

static const unsigned char STEER_DEADZONE_MIN = 120;
static const unsigned char STEER_DEADZONE_MAX = 120;
static const unsigned char THROTTLE_DEADZONE_MIN = 136;
static const unsigned char THROTTLE_DEADZONE_MAX = 136;

【讨论】:

  • 抱歉格式错误,我不知道如何在 cmets 中标记为代码或开始新行... 我试过了,它没有帮助,不幸的是。它们仍然显示为 12。我能够使其工作如下所列,但整数没有这样的运气:static unsigned char STEER_DEADZONE_MIN = 120; static unsigned char STEER_DEADZONE_MAX = 120; static unsigned char THROTTLE_DEADZONE_MIN = 136; static unsigned char THROTTLE_DEADZONE_MAX = 136;
  • 有趣。我怀疑 const 类型,它是全局的,并且您正在为嵌入式编译。我在这里找到了一些有趣的信息,也许这将有助于产生一些想法:embedded.com/electronics-blogs/programming-pointers/4023879/… 你是对的..comment 格式打击!
  • 有趣。我发现使用所有变量创建一个外部 Settings 类并将它们称为 Settings::STEER_DEADZONE_MIN 的解决方法似乎可行,但这是一个有趣的阅读,我计划继续尝试找出失败的原因。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2022-07-22
  • 1970-01-01
  • 2013-02-08
  • 2013-10-15
  • 2014-08-23
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多