gpt4 book ai didi

timer - Arduino Uno PWM 引脚冲突

转载 作者:行者123 更新时间:2023-12-02 07:08:52 29 4
gpt4 key购买 nike

我建了this motor shield基于L298N芯片控制坦克的两个电机。一个电机使用引脚 5 和 6,另一个电机使用引脚 10 和 11。

尝试添加TSOP 4838时为了用红外 Remote 控制水箱,我注意到反向移动引脚 10/11 上的电机只能全速工作 - 即引脚 11 上的高 (255) 值。任何低于该值的值都不会输出引脚 11 上的任何内容(这些引脚上测得的电压为 0 V)。

对于 Remote ,我使用 this libraryIR接收器连接在引脚 2 上(但引脚并不重要)。问题在于库代码本身。启用 IR 监听的行 irrecv.enableIRIn(); 是导致问题的原因。我了解到Arduino内部定时器和扩展板用于PWM的引脚存在冲突。

这是为电机反向供电的代码:

#include <IRremote.h>

// IR receiver configuration
const int irPin = 2;
IRrecv irrecv(irPin);

// Motors configuration
const int mLeftPin1 = 10;
const int mLeftPin2 = 11;
const int mRightPin1 = 5;
const int mRightPin2 = 6;

void setup()
{
// Start IR
irrecv.enableIRIn();

// Setup motors
pinMode(mLeftPin1, OUTPUT);
pinMode(mLeftPin2, OUTPUT);
pinMode(mRightPin1, OUTPUT);
pinMode(mRightPin2, OUTPUT);

// Move left motor in reverse, slower speed
analogWrite(mLeftPin2, 100); // This works only with 255 instead of 100
digitalWrite(mLeftPin1, LOW);
}

现在,我找到了here Arduino Uno 上的定时器使用的引脚是:

  • 引脚 5 和 6:由 Timer0 控制
  • 引脚 9 和 10:由定时器 1 控制
  • 引脚 11 和 3:由定时器 2 控制

所以我的问题是:

  1. 为什么说明书中的扩展板使用引脚 10 和 11 进行 PWM?它们对应2个不同的定时器。为什么不是 9 和 10?

  2. 为了将 IR 与电机屏蔽一起使用,我应该配置 IR 库以使用什么定时器?

  3. 如果答案是 2,则应在 IRremoteInt.h 中取消注释一行。我猜测 Uno 会采用第 68 行的 else 分支,尽管那里只有timer1 和timer2。我想知道为什么timer0不能用于Uno。

虽然我想留下切割痕迹和重新焊接作为最后的选择,但另一种可能性是更改屏蔽使用的引脚,但是哪个?我猜这也可以与在默认以外的其他引脚上将定时器配置为 PWM 配合使用,但我对定时器/中断一无所知,而且我对 Arduino 和 C 的知识有限。

我提出了一个很长的问题,因为我想学习而不仅仅是解决问题,所以请随意解释比所问的更多内容。

在寻找解决方案时,我还发现使用PWM时需要记住其他冲突。或计时器:

  • Timer0是一个8位定时器,它的最大值为255。它由delay()millis()使用code>,所以乱搞它会产生后果
  • Timer1是一个16位定时器,它最多可以容纳65535(无符号16位整数)。 Arduino 伺服库使用此定时器
  • Timer2 是 Arduino tone() 函数使用的 8 位定时器

当然,IRremote 库使用 TIMER_RESET,因此根据它使用的计时器,它可能会与关联的引脚发生冲突。

最佳答案

  1. 并非所有硬件都以最佳方式设计。使用 10 和 11 确实很浪费,因为它需要两个定时器。

2/3。理想情况下,您将使用 Timer0 以外的计时器。以下是有关计时器/中断的更多详细信息:

Arduino芯片(328P)有三个定时器。每个定时器可用于多种用途,但请务必注意,每个定时器只能启用一个定时器中断。

以Timer0为例。它会中断以便为delay() 和delay_us() 方法生成适当的延迟。它还用于引脚 5 和 6 上的 PWM 输出。发生这种情况是因为 PWM 输出不使用定时器中断,它们使用单​​独的输出比较模块。

现在具体看看你的问题,它应该工作正常,即使你有一个使用timer2的PWM输出,PWM不会在timer2上中断,所以IR库应该可以免费使用那个中断。然而,查看 IR 库代码,我们看到了这段代码:

ISR(TIMER_INTR_NAME)
{
TIMER_RESET;

似乎每次中断时,它都会重置计时器计数。这可能就是 PWM 输出无法正常工作的原因。输出比较模块正在等待某个滴答计数,但它永远不会达到该计数。

至于为什么它能在255下工作,我们可以看一下analogWrite代码:

void analogWrite(uint8_t pin, int val)
{
// We need to make sure the PWM output is enabled for those pins
// that support it, as we turn it off when digitally reading or
// writing with them. Also, make sure the pin is in output mode
// for consistenty with Wiring, which doesn't require a pinMode
// call for the analog output pins.
pinMode(pin, OUTPUT);
if (val == 0)
{
digitalWrite(pin, LOW);
}
else if (val == 255)
{
digitalWrite(pin, HIGH);
}

因此,通过写入 255,analogWrite 代码会忽略整个 PWM 和输出比较,而只是将引脚写入高电平。

最后,为了解决您的问题,我个人会采取不使用引脚 11 和 3(定时器 2)的路线。是的,这需要进行一些小的重新布线,但这样您就可以释放计时器2供IR库使用。

或者,您可以浏览 IR 库并尝试使其工作而不重置计数。

关于timer - Arduino Uno PWM 引脚冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18705363/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com