Arduino-关于数据类型

时间:2018-09-05 07:23:55

标签: c++ arduino-uno

我正在为项目使用的Arduino编写延迟功能。原因是TIMER0(用于Arduino延迟的默认计时器)被PWM控制占用。延迟功能的测试代码如下:

int count;
unsigned long int sec;

void delay_ms (uint16_t millisecond) {
  sec = ((16000000/12)/1000)*millisecond;
  for (count = 0; count < sec; count ++);
}

void setup (){
Serial.begin(9600);
}

void loop (){
  Serial.println('a');
  delay_ms(1000);
  Serial.println('b');
  delay_ms(1000);
}

此设置仅打印a和b之间的间隔为1秒。它工作正常,但是在此之前,我使用了其他设置,这些设置不起作用。更改为:

  • 将count声明为无符号long =>这导致延迟功能正常工作,但这只是第一次。
  • 在for循环的初始化步骤中将count声明为int并初始化为int =>延迟功能根本无法按预期工作。

基于Arduino参考在Unsigned LongInt上提供的知识,我认为在这种情况下它们本质上是相同的。因此,我想对循环如何处理数据以及延迟函数进行一些说明。

1 个答案:

答案 0 :(得分:3)

您用arduino-uno标记了问题,并且您为int提供的链接明确表示Uno上的int为16位,范围为-32768至32767:< / p>

  

在Arduino Uno(和其他基于ATmega的板)上,一个int存储一个16位(2字节)的值。这样产生的范围是-32,768到32,767(最小值为-2 ^ 15,最大值为(2 ^ 15)-1)。

现在((16000000/12)/1000)*1000(延迟1000)为1333333,它超出了int(甚至是unsigned int)。这意味着您的int变量count将在循环中溢出,并且您将拥有undefined behavior

count溢出时实际上发生的是它变为(因为Uno使用two's complement表示负数)。然后,您将 up 计数为零,然后将正数计数到再次溢出,导致count < sec始终为 为真,并给您无限循环。

当然,解决方案是使用可以处理像您这样的大数目而没有问题的类型。像unsigned long


哦,停止使用全局变量。 countsec都应位于延迟函数内部。 然后 停止制作自己的延迟功能,AFAIK Arduino框架应该具有可以使用的延迟功能。最后,尽管没有完整和适当的标准库(而是使用自己的框架),但Arduino是用C ++而不是C编程的。