Arduino-需要将计时器0溢出(TIMER0_OVF_vect)重新分配给不同的ISR-如何



在基于通用Arduino(ATMEGA386P(的应用程序上,我需要Timer 0的溢出中断(通常转到TIMER0_OVF_vect(来指向我自己的代码,而不是现有的Arduino代码。我意识到这将导致依赖于正常工作的1kHz间隔的Arduino运行时函数不可用。我在一个现有的基于Arduino的应用程序中工作,不能轻易地离开Arduino环境(例如,到AVR-GCC(,因为我需要保留一些其他的Arduino依赖项。我无法利用其他计时器(计时器1或计时器2(,因为它们正在用于其他目的。

我的问题是——我如何(或可以(重新配置定时器0,使其溢出中断向量指向我自己代码的ISR入口点?

谢谢。

添加信息2021年12月13日根据朋友评论2021年12日10日

我创建了ISR(TIMER0_OVF_vect((我将使用它来代替布线.c中的ISR(

ISR(TIMER0_OVF_vect)
{
// MY SUBSTITUTE CODE WILL GO HERE
}

虽然代码似乎通过了编译器,但它在链接过程中失败,并显示以下错误消息(来自Arduino IDE

wiring.c.o(来自插件的符号(:在函数__vector_16': (.text+0x0): multiple definition of__vector_16'中sketch\MYTESTPROGRAM.ino.cpp.o(来自插件的符号(:(.text+0x0(:首先在此处定义collect2.exe:错误:ld返回1退出状态退出状态1板Arduino Uno 编译错误

这个问题对我正在进行的一个更大的项目来说是一个阻碍,所以我非常感谢关于是否可以替换中断服务例程的任何进一步建议(而不需要更改或重新编译Arduino库(

再次感谢

此主题在arduino.cc.中处理

尽管如此,我还是使用了一种变通方法来获得相同的结果。这是在带有ATmega32U4的Arduino Micro上测试的,但应该直接转换为您的芯片。

我没有使用其ISR例程已经由Arduino定义的timer0溢出,而是使用输出比较寄存器B并将其设置为OCR0B = 0xFF。这将使输出比较匹配B中断在时间r0溢出时触发。

为了避免任何干扰,您应该禁用TIMSK0中的TOIE0位,这样Arduino的ISR(TIMER0_OVF_vect(就永远不会执行。相反,您设置OCIE0B位:

TIMSK0 = (1 << OCIE0B); // Disables TOIE0 and enables OCIE0B

然后,您的代码可以在中断中执行

ISR(TIMER0_COMPB_vect)
{
// Your code
}

为了赋予整个操作一些意义,您还需要通过根据需要设置CS02:0位来更改TCCR0B寄存器中的时钟。

显然,您将无法使用arduino本机millis()/micros()/delay()功能。您也可以使用输出比较寄存器A,但我喜欢保留将OCR0A定义为计数器的TOP的选项,因此使用B.

最新更新