Atmel/Arduino:ISR(TIMER0_OVF_vect)无法编译(__vector_16中的“首次定义") [英] Atmel / Arduino: ISR(TIMER0_OVF_vect) won't compile ("first defined" in __vector_16)

查看:793
本文介绍了Atmel/Arduino:ISR(TIMER0_OVF_vect)无法编译(__vector_16中的“首次定义")的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在研究PWM调制器,以模拟"汽车发动机的点火换向.然后,我将用它来驱动另一个微控制器,该微控制器通过RPM计数器的检流计来处理从原始信号(发动机换向器)到干净输出电压的转换.

I'm currently working on a PWM modulator to "simulate" a car engine ignition commutation. Then, I will use it to drive another microcontroller which handles the conversion from a raw signal (engine's commutator) to a clean output voltage, going through the RPM-counter's galvanometer.

这个项目也是我学习如何更好地控制微控制器的借口.

This project is also a pretext for me to learn how to have a better control upon my microcontroller.

好吧,我使用timer0(8位)编写了一个小程序,我需要触发两个中断服务程序(ISR):

Well, I wrote a small program, using timer0 (8 bits), and I need to trigger two interrupt service routines (ISRs):

  • TIMER0_OVF_vect:溢出中断
  • TIMER0_COMPA_vect:在比较时触发

我具有以下功能:

void configureTimer0(parameters)
{
    cli();

    // Some maths
    TCCR0A = (1<<WGM01) | (1<<WGM00); // I tried to use the "Fast PWM" waveform generation mode
    TCCR0B &= 0b00110000; // 5th and 4th bits are reserved. Every other bits is set to 0.
    TCNT0 = 0; // Initialize counter value to 0

    TCCR0B |= select_prescaler(prescaler); // Custom function to determine the right prescaler
    OCR0A = ext_OnTicks; // Output compare register is set to a predetermined numbers of ticks

    // Enabling overflows interrupt:
    TIMSK0 |= (1 << TOIE0);
    sei(); // Enable interrupts
}

然后,在某些情况下,我会根据情况将TIMSK0中的OCIE0位打开和关闭. 但是,始终会启用溢出中断.

Then, under certain conditions, I switch the OCIE0 bit in TIMSK0 on and off depending on the situation. However, the overflow interruption is always enabled.

尝试编译时,出现以下错误:

When I try to compile, I end up with these errors:

"C:\Users\UTILIS~1\AppData\Local\Temp\arduino_build_8383\sketch\PWM_modulator.ino.cpp.o" "C:\Users\UTILIS~1\AppData\Local\Temp\arduino_build_8383/..\arduino_cache_395570\core\core_arduino_avr_uno_a94ab6aaf61dfb93b4a8079c694a14c2.a" "-LC:\Users\UTILIS~1\AppData\Local\Temp\arduino_build_8383" -lm
wiring.c.o (symbol from plugin): In function `__vector_16':

(.text+0x0): multiple definition of `__vector_16'

C:\Users\UTILIS~1\AppData\Local\Temp\arduino_build_8383\sketch\PWM_modulator.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

exit status 1
Erreur de compilation pour la carte Arduino/Genuino Uno // Compilation error for Uno board (French)

我尝试使用ISR(TIMER0_COMPB_vect)而不是ISR(TIMER0_OVF_vect)进行编译,并且它可以工作,但实际上这不是我程序的重点.

I tried to compile with ISR(TIMER0_COMPB_vect) instead of ISR(TIMER0_OVF_vect), and it works, but indeed it's not the point of my program.

我还尝试了8位定时器ISR(TIMER2_OVF_vect).我可以同步Timer0和Timer2以获得所需的效果,但是我认为这样做并不干净(这使我无法使用Timer2功能).

I also tried ISR(TIMER2_OVF_vect) which is an 8-bit timer as well. I could synchronize Timer0 and Timer2 to achieve the desired effect, however I don't think it is quite clean to do so (and it prevents me to use the Timer2 capabilities).

我的代码有问题,但是无法理解错误隐藏的位置. 肯定与connection.c.o文件有关.

There is something wrong in my code, but cannot understand where the mistake is hiding. There is definitely something related to the wiring.c.o file.

PS:自问题出现以来,我一直在寻找解决方案已经很长时间了,但是我无法找到任何方法来正确地向Google询问Stack Overflow网站. 很抱歉,如果我错过了正确的搜索字符串!

PS: I've looked for a solution quite a long time since the problem appears, but I could not find any way to ask Google correctly neither the Stack Overflow site. Apologies if I missed the right search string!

推荐答案

可以为Timer0提供自己的处理程序,并且仍然使用Arduino环境.

It is possible to provide your own handler for Timer0 and still use the Arduino environment.

这是通过(可选)禁用文件wiring.c中的Timer0的现有处理程序(在Arduino安装内部)来完成的.在现有处理程序周围放入条件编译#ifndef/#endif:

This is done by (optionally) disabling the existing handler for Timer0 in file wiring.c (inside the Arduino installation). Put in conditional compilation, #ifndef / #endif, around the existing handler:

#ifndef _DISABLE_ARDUINO_TIMER0_INTERRUPT_HANDLER_

    #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
    ISR(TIM0_OVF_vect)
    #else
    ISR(TIMER0_OVF_vect)
    #endif
    {
        // Copy these to local variables so they can be stored in registers
        // (volatile variables must be read from memory on every access)
        unsigned long m = timer0_millis;
        unsigned char f = timer0_fract;

        m += MILLIS_INC;
        f += FRACT_INC;
        if (f >= FRACT_MAX) {
            f -= FRACT_MAX;
            m += 1;
        }

        timer0_fract = f;
        timer0_millis = m;
        timer0_overflow_count++;
    }

#endif

例如,在Windows上,文件wiring.c可能位于文件夹C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino中.

For example, on Windows, file wiring.c may be located in folder C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino.

请注意,可能需要具有管理权限才能对wiring.c进行更改.在Windows上,可以通过右键单击文本编辑器(文本编辑器,例如 Notepad ++ UltraEdit [1] ,它们可以处理Unix行尾字符-记事本无法真正处理此问题),然后选择以管理员身份运行" .

Note that it may be necessary to have administrative privileges to make changes to wiring.c. On Windows this is done by right clicking on the text editor (a text editor, like Notepad++ or UltraEdit[1], that can handle the Unix end-of-line characters - Notepad can not really handle this) and selecting "Run as Adminstrator".

然后,在源代码中,将这两行放在文件顶部:

Then, in your source code put these two lines at the top of the file:

#define _DISABLE_ARDUINO_TIMER0_INTERRUPT_HANDLER_

#include <wiring.c>

请注意,对于其他Arduino项目,它的工作原理与以前完全相同.仅当定义了预处理器符号_DISABLE_ARDUINO_TIMER0_INTERRUPT_HANDLER_时,才能禁用中断处理程序.

Note that for other Arduino projects it works exactly as before. The interrupt handler is only disabled if preprocessor symbol _DISABLE_ARDUINO_TIMER0_INTERRUPT_HANDLER_ is defined.

可能还必须对TIMER0_COMPA_vect应用相同的过程(同一文件夹中的文件Tone.cpp).

The same procedure may have to be applied to TIMER0_COMPA_vect as well (file Tone.cpp in the same folder).

这已在等效于Arduino Uno的Arduino IDE 1.8.5中进行了测试,文本编辑器 UltraEdit 和Windows 10.

This was tested with an Arduino Uno equivalent, Arduino IDE 1.8.5, text editor UltraEdit, and Windows 10.

1.我还希望 Visual Studio代码可以正常工作,但是我尚未对其进行测试.

1. I would also expect Visual Studio Code to work, but I haven't tested it.

这篇关于Atmel/Arduino:ISR(TIMER0_OVF_vect)无法编译(__vector_16中的“首次定义")的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆