我有一个非常简单的程序,这让我头痛。
一些背景:
我正在ATMELStudio6中编程一个arduino Uno“Atmega328P”。我在debugwire模式下使用JTAGICE mkII进行编程和调试。
我还使用了this method来使用arduino库来简化工作。
我写了一个简单的程序来计算一个外部中断管脚上的转换在我的例子中,我使用INT0_vect。im指向的值,只是每次转换的增量。
问题是在ISR中使用全局指针你可能认为我忘了添加volatile关键字,但你错了。
ISR为每个转换提供服务,但不会更改值。我不知道为什么,所以我通过程序,发现我的指针指向R00,一个工作寄存器。这应该没问题,但在ISR得到服务之前,R00被推送到堆栈R00会递增,并还原上一个值。
我不知道为什么会这样。正如我所说,我使用的“volatile uint8_t*”应该是指向易失性uint8的指针。
代码如下所示:

#include "Arduino.h"
void setup();
void loop();
void update();

volatile uint8_t* Count;
void setup()
{
    *Count = 0;
    attachInterrupt(0,update, CHANGE);  // makes ISR call update
}
void loop()
{
//  delay(1000);
}
 void update()
{
    (*Count)++;
}

主循环调用setup一次,然后重复循环。
附加中断是一个宏,它设置中断,然后有效地创建:
`ISR(INT0_vect){update();}`

一些附加信息:
我对c++和c编译器都使用-Os。
avr gcc全选项:
-funsigned char-funsigned位字段-DF_CPU=16000000UL
-I“../../../../arduino-1.0.5/hardware/arduino/cores/arduino”-I“../../../../arduino-1.0.5/hardware/arduino/variants/standard”-操作系统-fdata部分-功能部分-fpack struct-fshort enums-Wall-c-std=gnu99-fno exceptions-MD-MP-MF“$(@:%.o=%.d)”-MT“$(@:%.o=%.o)”-mmcu=atmega328p
avr-g++完整选项:-funsigned char-funsigned bitfields-DF-CPU=16000000UL-I“../../../../arduino-1.0.5/hardware/arduino/cores/arduino”-I“../../../../arduino-1.0.5/hardware/arduino/variants/standard”-Os-fdata sections-fffunction sections-fpack struct-fshort enums-Wall-c-fno exceptions-MD-MP-MF”$(@:%.o=%.d)“-MT”$(@:%.o=%.d)”-MT“$(@:%.o=%.o)”-mmcu=atmega328p
avr-g++链接器选项:-Wl,-Map=“$(OutputFileName.Map”-Wl,--开始组-Wl,-lm-Wl,-lcore-Wl,--结束组-Wl,-L”。/../../ArduinoCore“-Wl,--gc段-mmcu=atmega328p

最佳答案

由于Count指针是一个未显式初始化的全局变量,因此它被设置为0x0,这恰好是Atmega328P映射寄存器R00到的地址。
ISR()宏标记的函数向编译器指示它是一个C ISR处理程序。为了让编译器在不破坏ISR启动时可能运行的状态的情况下安排C代码执行ISR,它必须添加一些序言代码来保存CPU的一些寄存器状态(以及在ISR函数返回时恢复该状态的相应结尾),以便中断的执行路径没有被破坏。因此,ISR()指定使编译器在堆栈上保存并还原寄存器R00(和其他寄存器)。
这两种情况的结合就是为什么R00被保存在堆栈上,然后ISR将其递增,然后R00从堆栈恢复。
如果不希望发生这种情况,可以使用ISR_NAKED属性告诉编译器不要生成序言或结尾代码。但是,如果您的ISR句柄不能正确保存和恢复寄存器状态,那么前台运行的任何东西都可能表现得不太好。
因此,将Count设置为指向为计数器分配的某个位置。或者,使Count成为一个简单的变量而不是指针,并在ISR中直接处理它。
avr-gcc的中断处理支持的一个很好的概述可以在这里找到:http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

关于c++ - ISR点中用于注册的指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21031428/

10-15 06:48