在基于通用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.