我有一个简单的 C 程序,用于熟悉我将使用的新(对我而言)MCU (ATmega32M1)。但是,我的程序在 -O3 优化级别无法正确运行。
我正在使用 Microchip Studio(版本 7.0.2594)(以前称为 Atmel Studio)。我正在使用 avr-gcc 5.4.0
在除 -O3 之外的所有编译级别,连接到输出 PB5 和 PD6 的 LED 均以 8 秒的周期闪烁。这是正确的行为。然而,在优化级别 -O3 下,只有连接到输出 PB5 的 LED 闪烁,而输出 PD6 保持低电平。
这对我来说是一个明显的错误,还是某种编译器错误(喘气!)?
如果它是编译器错误,如果您能给我指出一些有关如何更新 Microchip (née Atmel) Studio 7 使用的编译器的说明,我将非常感激 - 我对此真的很陌生,但我强烈怀疑v5.4.0不是avr-gcc的最新版本。
我的代码转载如下:
#include <avr/io.h>
#include <avr/interrupt.h>
static uint64_t execution_time;
////////////////////////////////////////////////////////////////////////////////
// Setup functions
static inline void SetClock(void) {
//Set clock to external crystal highest speed (8MHz):
//(These instructions must be completed in 4 clock cycles or less)
CLKPR = 0x80; //set CLKPCE, clear all else.
CLKPR = 0x00; //Clear CLKPCE, set CLKPS[3:0] to 0. (Smallest prescale - fastest speed.)
}
static inline void SetTimer1(void) {
//set up timer/counter 1 (CTC mode, TOP = OCR1A)
TCCR1A = 0; //WGM0 & WGM1 = 0
TCCR1B = 0x0D; //set WGM[3:0] = 0,1,0,0 (CTC with OCR1A as TOP); CS1[2:0] = 1,0,1 (internal timer, prescale 1024)
OCR1A = 0x7A12; //TOP = 31250; 4000.0 ms - This means an accurate count can be kept as well as the faster count.
TIMSK1 = 1<<OCIE1A; //Interrupt on Timer 1 reaching OCR1A.
//The Timer will run at 7.8125 ticks per ms.
}
void InitOutputs(void) {
DDRB |= 0x7 << DDB5; //SPARE6, 7, 10
DDRC |= 0x3 << DDC6; //SPARE8, 9
DDRD |= 0x7 << DDD5 | 0x3 << DDD0; //SPARE11, 12, 13 && RELAY H & L
}
void Setup(void) {
//Set up the various parts of the hardware.
SetClock();
SetTimer1();
InitOutputs();
sei();
}
////////////////////////////////////////////////////////////////////////////////
// Functional... functions
void TestISR(void) {
static uint64_t last_time;
if (execution_time > last_time) {
PIND = 1 << PORTD6;
last_time = execution_time;
}
}
int main(void) {
Setup();
while (1) {
TestISR();
}
}
ISR(TIMER1_COMPA_vect) {
execution_time += 4000;
PINB = 1 << PORTB5;
}
你的变量需要是
volatile
static volatile uint64_t execution_time;
否则,当您启用优化时,从中读取的内容将被优化,因为编译器看不到任何可能修改此变量的程序路径(ISR 不会从您的代码中调用)