bin*_*nar 13 avr atmega timer arduino pwm
我基于L298N芯片制造了这个电机屏蔽,以控制一个水箱的两个电机.它将引脚5和6用于一个电机,而引脚10和11用于另一个电机.
在尝试添加TSOP 4838以便使用IR遥控器控制油箱时,我注意到在10/11引脚上反向移动电机只能在全速运行 - 即引脚11上的HIGH(255)值.低于该值不会在引脚11上输出任何内容(这些引脚上的测量电压为0 V).
对于遥控器,我使用这个库.该IR接收器连接在引脚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);
}
Run Code Online (Sandbox Code Playgroud)
现在,我在这里发现Arduino Uno上的定时器使用的引脚是:
所以我的问题是:
为什么指示灯中的屏蔽使用引脚10和11进行PWM?它们对应于2个不同的计时器.为什么不9和10?
为了使用IR和电机屏蔽,我应该使用什么定时器配置IR库?
如果答案是2,则应取消注释一行IRremoteInt.h
.我猜Uno会else
在第68行采取分支,虽然只有timer1和timer2在那里.我想知道为什么timer0不能用于Uno.
虽然我想留下切割痕迹和重新焊接作为最后的选择,但另一种可能性是改变屏蔽使用的引脚,但是哪个?而且我猜这也可以配置在其他引脚上将定时器配置为PWM而不是默认值,但我对定时器/中断一无所知,而且我对Arduino和C的了解有限.
我提出了一个很长的问题,因为我想要学习的不仅仅是解决问题,所以请随意解释所提出的问题.
在寻找解决方案时,我还发现在使用PWM或定时器时要记住其他冲突:
delay()
和使用millis()
,所以当它搞乱它时会有后果tone()
函数使用的8位定时器当然,IRremote库使用TIMER_RESET
,因此根据它使用的计时器,它可能与相关的引脚冲突.
use*_*391 14
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;
Run Code Online (Sandbox Code Playgroud)
它似乎每次中断时都会重置计时器计数.这可能是您的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);
}
Run Code Online (Sandbox Code Playgroud)
因此,通过写入255,analogWrite代码忽略了整个PWM和输出比较的东西,只需将引脚写入高电平.
最后,为了解决您的问题,我个人会采用不使用引脚11和3(timer2)的路线.是的,它需要一个小的重新布线,但这样你可以释放timer2供IR库使用.
或者,您可以在IR库周围寻找并尝试使其工作而不重置计数.
归档时间: |
|
查看次数: |
25197 次 |
最近记录: |